Rebuild the API Reference around one page per symbol and richer, verified content.
Pages & navigation
- One HTML page per symbol (kw-*, type-*, phase-*, screen-*, fn-*, annot-*, op-*)
instead of a single scrolling page; namespace overview pages (ns-screen …
ns-color) and a searchable index (api.html) with client-side fuzzy search.
- Sticky-header scroll offset (scroll-margin) so a jumped-to entry/param/color is
never hidden, plus a flash highlight on the scrolled-to target.
Deep linking in every snippet & example
- Namespace members split: `Screen`→namespace page, `fill_rectangle`→method page;
`Color`→palette page, `Charcoal`→its swatch — separately.
- Named arguments (`width:`) link to that parameter's anchor on the method page.
- Hover any token for a summary card built from the real API data (symbols.json).
Content & coverage
- Full authoritative surface documented from the compiler: every keyword, type,
the 6 phases (Start/Input/FixedUpdate/Update/LateUpdate/Render, each its own
page), all 22 annotations, namespace methods with parameter docs, builtins,
the world_* reflection ABI, networking, operators — 155 symbols.
- Longer, clearer explanations; "model"/"model instance" terminology, not "entity";
descriptive identifiers in every example (Position{column,row}, Velocity{delta_x,
delta_y}, Health{current,maximum}, Player/Enemy) — no Pos/Seg/x/dx.
- Accuracy fixes from compiler ground-truth: world_count() takes no arg,
world_query_next(property, cursor) arg order, event fields bind by name; dropped
`when` and `module` (not in the self-hosted parser).
Tooling
- inventory.json + check.py: coverage guard (every symbol has a page), duplicate-
token guard, and broken-link guard — fail CI so docs can't drift.
- validate.py: compiles every ```ludic example against bin/ludicc (158 compile).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.6 KiB
id: annot-predicted name: @Predicted category: annotations kind: annotation tokens: @Predicted sig: @Predicted handler Name { … } tip: Run a control handler on the owning client speculatively and on the server authoritatively. order: 50
@Predicted marks a control handler that runs in two places: speculatively on the client that owns the affected instance, so local input feels instant, and authoritatively on the server, whose result reconciles the client if the two diverge. It is the responsive-control role from Quake-style client-prediction, named for the netcode behavior (owner-predicts plus server-authoritative plus reconcile) rather than the machine, and it matches Unity's GhostMode.Predicted so the concept transfers. Prediction is explicit — Ludic never silently predicts — and it only applies to instances of an @Owned model, since the dispatch reads is_owner to decide whether the local client should run it. Use it for the owning player's movement and actions; leave authority-only rules on @Server.
program PredictedMovement {
@Sync property Position { column: int = 0, row: int = 0 }
@Owned model Player { @Sync Position }
@Predicted handler MovePlayer phase Input { # owner predicts, server reconciles
let pressed = Input.key()
for (Position) in query [Position, {Player}] {
if pressed == 'd' { Position.column = Position.column + 1 }
}
}
handler SpawnPlayer phase Start {
spawn Player { Position { column: 0, row: 0 } }
}
}