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
- Getting started: a first script, a sleep schedule for Fedai, step by step.
- Language: everything a script declares.
- How scripts run: transactions, the order of work, lifecycle.
- Reference: host types, the library, type mapping, grammar.
- Examples: Caria's scripts.