Design
Goals
- One language for the town's behaviour: buildings, parts, areas, residents, and the visual effects on screen.
- Papyrus's model, without its known flaws: a script attached to an object, properties in
the editor, events, states, timers, waiting and persistence, as in Bethesda's Papyrus. What
goes wrong there is designed out from the start:
- scripts falling behind under load, and stack dumps → one thread working minute by minute, with logical budgets and no calls tied to frames;
- an error that skips a call and carries on with a default value → the transaction is undone and its binding closes, with a report at the line;
- saves that keep orphaned data, and values silently dropped when code changes → explicit migrations with a report of what was kept, changed and dropped.
- One implementation: the compiler, the bytecode, the VM and the execution model are a single Rust project, and the same VM runs on the server, in the native game and in the browser (Architecture). There is nothing to keep in step between targets.
- The world belongs to the host: its lifecycle, field values, how saves are stored, the network, the database, the events coming in and the game's services are the game's. The core knows no town; host types, events, contracts and natives are given from outside (Embedding Kalem).
- Exact rules: the rules are precise enough to allow one correct implementation; conformance tests and future hosts rely on them.
- Tools are part of the language: error messages, the language server, the debugger, the profiler and the conformance tests (Tools).
Version 1
- Primitive types; properties, memory, contract fields and client inputs.
- Catalog events, flat states and synchronous functions.
- Timers of two kinds: declared (
daily,every) and one-shot (after,at). - Atomic transactions, the order of work, the lifecycle, budgets and the error policy.
- Saving at a minute's boundary, loading with the same definitions, and explicit migration.
- The three targets;
VisualEffect,Lightand signals on the client. - Forms made from manifests, the language server, line breakpoints and stepping.
Tasks and waiting, wait for, sending events from scripts, object references, collections and
overriding functions by state come in the next version.
Out of scope
- General-purpose programming: files, network, threads.
- Simulating the server every frame, and polling: server scripts run on events and time.
- Scripts calling each other directly, or writing another object's fields: objects interact through events and contract fields.
- Inheritance between user scripts, closures, generics, exceptions.