Skip to main content

Kalem

Kalem is the behaviour language of Caria, a cartoon town that lives on its own. What a thing in town does, when and why, is written in Kalem: a business opening and closing, a street lamp coming on in the evening, the town's power grid, a resident's day. How lights and neon signs look on screen is Kalem too.

Kalem follows Bethesda's Papyrus (Skyrim, Fallout): a script is attached to an object and has properties that show in the editor, events, states and timers. The name comes from there as well: papyrus is the paper, kalem (Turkish for pen) is what writes on it.

At a glance​

A script that opens and closes a business by its hours and the town's power, and counts the visitors while it is open:

/// Opens and closes the business by its hours and the town's power; counts visitors while open.
server script BusinessHours extends Building
label "Business · opening hours"
category "Server behaviours"

group "Opening hours"
/// Closing may pass midnight (18:00–03:00).
property opensAt: time = 18:00 "Opens"
property closesAt: time = 03:00 "Closes"
end

memory hasPower: bool = true "Power"

writes business.open: bool
writes business.visitors: int

timer opening daily at opensAt
timer closing daily at closesAt

on ready
decide()
end

on timer opening, closing
decide()
end

on city.powerChanged(powered)
hasPower = powered
decide()
end

function decide()
if hasPower and clock().between(opensAt, closesAt)
goto Open
else
goto Closed
end
end

auto state Closed
on enter
business.open = false
end
end

state Open
on enter
business.open = true
end

// A closed business admits nobody: Closed has no handler for this event.
on building.visitorEntered
business.visitors += 1
end
end
  • The header says the script runs on the server and attaches to buildings (Script).
  • Properties show in the component's form in the editor; every building sets its own hours (Properties).
  • Memory is the script's own lasting state (Memory).
  • Fields are the building's public values: this script writes them, anyone may read them (Contract fields).
  • Timers fire by the world's clock (Timers); events come from the town (Events).
  • States keep whether the business is open; a closed one ignores visitors (States).

Two sides​

  • Server scripts (server script) run in the world. The town lives without the player: the clock, the events and the fields are on the server, and so is the code that decides. Everything an event or a timer changes is one atomic transaction.
  • Client scripts (client script) run on screen: a part's colour, its light. They save nothing and never change the world; they read the server's fields as signals (Client scripts).

Where scripts are written​

Scripts are written in Sakin Editor, Caria's editor (an IntelliJ IDEA plugin). In a .kalem file, Kalem's language server gives errors as you type, completion and documentation. A script is attached as a component to a package (a building, a character, an object), to one of its parts or to the world; Play runs the world and Debug stops it at a line (In the editor).

Principles​

  • Everything is in the script: properties, memory, fields, events, states and timers are written in code. The editor's forms are made from the script.
  • Exact rules: the same start and the same events always give the same result (Determinism).
  • A core that knows no town: the language knows nothing of buildings or residents. Host types, events, fields and the calendar come from the game (Host types).
  • Tools first: an error gives the file, line and column; the language server and a debugger with breakpoints are part of the language.

Where to start​

  1. Getting started: a first script, a sleep schedule for Fedai, step by step.
  2. Language: everything a script declares.
  3. How scripts run: transactions, the order of work, lifecycle.
  4. Reference: host types, the library, type mapping, grammar.
  5. Examples: Caria's scripts.