Adds the rest of the game/entity/property lifecycle as @-hooks, each firing at
one timeline moment and reducing to ordinary code:
- @OnStart / @OnQuit (program): @OnStart aliases the Start phase; @OnQuit runs in
the frame loop's done: block, after the loop stops and before teardown.
- @OnDespawn(Model) (entity): a destructor. Despawn doesn't statically know the
entity's model, so hooks compile to @on_despawn_<Model>(entity) functions and
emit_despawn dispatches on @L_kind. Symmetric with @OnSpawn.
- @OnAttach(Property): fires in emit_init_component once a property is attached
and seeded, with the property bound by name.
Registries + parsing mirror @OnSpawn. examples/lifecycle.ludic narrates the whole
timeline (output 1 700 50 950 2). Behaviour-preserving (goldens byte-identical,
despawn users unaffected when no hooks registered); test.sh 16/16, fixpoint holds.
Deferred: @OnDetach (per-property runtime dispatch) and scene @OnEnter/@OnExit
(need scene support in the compiler).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds two annotations that give properties/models a scriptable feel WITHOUT
reattaching behavior to data — both reduce to code the data-oriented model
already emits:
- @Computed field on a property: a derived value that is NOT stored; x.field
expands inline to its expression (bare names read as fields of x) at each use.
Zero storage, zero runtime dispatch. Reuses qualify_fields (now non-destructive,
base-node based); a g_computed registry keeps derived fields out of the layout.
- @OnSpawn(Model) on a handler: a constructor that runs at each spawn of Model
with the model's properties bound by name. Spawn statically knows the model, so
no runtime dispatch; emit_spawn binds the properties and inlines the hook body.
examples/annotations.ludic now exercises @Handles/@Queries/@Computed/@OnSpawn
(output 3 25 0 0); test.sh 15/15, fixpoint holds, goldens byte-identical.
Deferred (need more machinery, by design): @OnDespawn (despawn doesn't statically
know the entity's model) and @OnChange (needs change-tracking).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Queries(these: [Prop{constraint}, ...], on: Model) on a handler desugars to the
existing S_QUERY loop: each property binds by its own name, a Prop{...} block
qualifies its bare fields to that property, and on: adds a {Model} tag filter.
Implemented via parse_queries_anno + qualify_fields (parse_game.ludic), wired
into parse_one_decl; @Handles parses on the program (documentation).
examples/annotations.ludic demonstrates it (output 3 1 0 0); test.sh 15/15.
Docs: added the Annotations section to LANGUAGE.md and did the vocabulary prose
pass (component->property, archetype->model, system->handler, game->program)
across the docs. check-docs + test-tools green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Self-hosted compiler (selfhost/*.ludic), runtime, examples, editor tooling,
and docs. Phase 1 of the syntax-redesign cohesion pass has landed:
edge-system fix, signature-query, when-alias, and the documentation truth-pass.
Suite green (14/14), C-free bootstrap fixpoint holds.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>