The engine already auto-ticks SpriteAnim/Motion; it now auto-DRAWS too.
Declare a Sprite component (id/offx/offy/scale/flip/tint/hidden, shipped from
ludic.core) on an entity with a Position and esys_sprite draws it each Render
frame — no hand-written Render handler, no hand animation (adds the SpriteAnim
frame when present). Registered on the engine-system registry (Render) and
spliced only when the game declares Sprite, so a game that never declares it
compiles byte-identically; opt out by omitting Sprite or `disable system
esys_sprite`.
Deprecates the bare draw_sprite/draw_sprite_scaled globals in favour of
Screen.sprite/Screen.sprite_scaled: a direct bare call emits a one-time
compile-time deprecation note (the bare form still lowers, since Screen.sprite
uses it); migrates the chronorift demo to the namespaced calls (golden render
byte-identical).
Example sprite_render (pixel-readback: engine draws the sprite, respects
hidden). Full suite 109/0, goldens byte-identical, fixpoint holds.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Seven independently-usable modules on the six-lever contract with name-keyed
data registries (zero-code content): movement (grid/free/tween, 4/8-axis, veto +
interact), inventory + equipment (stat bonuses via the gameplay modifier stack),
crafting, event-driven quests + flags, an Ink/Yarn dialog graph, Sokoban
pushables + a switch/plate/gate signal graph, and over-time status effects
through the Combat pipeline. Reuses ludic.gameplay Stats/Combat. Deterministic.
21-check example, in the suite (103 passed, 0 failed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Perception -> decision -> action AI that writes the SAME intent fields the
player controllers read, so an enemy reuses the shooter's weapon/aim and a
companion reuses the mover (friendly vs enemy = faction + goal, not code).
Vision/Memory perception (throttled, faction + optional LOS), three decision
models (FSM, utility, behaviour tree) writing one Brain intent with a
cancellable DecisionMade hook, Reynolds flocking steering, and a Follower
companion. Reuses ludic.gameplay Faction/Stats. Deterministic. 8-check example.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Top-down shooter: TopDown decoupled move/aim (mouse/stick/move-dir/auto-aim),
a name-keyed Weapon registry (fire-rate/spread/pellets/pattern + data-driven
pierce/homing), and a self-contained deterministic Projectile pool with
faction-filtered Combat hits, pierce, ring/spiral patterns, and homing. One
weapon impl serves player + NPC via a want_fire intent. Budgeted wave Spawner.
Reuses ludic.gameplay Faction/Combat/Stats. 11-check example, in the suite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The reference six-lever controller: Platformer component (jump feel as data),
decomposed input/move/gravity/jump/anim engine sub-systems (each disable-able),
JumpRequested/Landed/StateChanged events, gravity policy enum, and the opt-in
scaffolding (moving/crumble platforms w/ rider carry, pickups+score, springs,
hazards+Life, checkpoints/goal). Reuses the shared esys_move collision.
Also fixes a latent SSA-name collision in ludic_sweep_entity that triggered
once a program declared >=11 events. Reseeded; C-free fixpoint holds.
3 new regression cases (100 passed, 0 failed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Repository-cleanup / DX pass folding three tracker items into one coherent
change, verified green end to end (`bin/x test` 49/0, `bin/x selfhost-test`
29/0, `bin/x test-tools` 29/0).
#28 — curate & categorise examples/
- 42 flat entries regrouped into intent-revealing subdirs: games/, rendering/,
ecs/, events/, networking/, lang/, library/ (was lib/).
- chronorift dir-vs-file duplication resolved: the entry file and its import
modules now live together under games/chronorift(.ludic).
- Every path reference updated repo-wide (test runner, editor-tool drivers,
docs/site, design docs).
- New examples/README.md indexes the whole set with run commands.
- Showcase examples without a self-asserting entry (hello, events, net_rt) now
get a compile-only rot guard in `bin/x test`, so nothing here rots silently.
#30 — text-diffable golden baseline
- The 4 binary selfhost/golden/*.ppm blobs are replaced by a single
selfhost/golden/renders.sha256 manifest (SHA-256 per render). Hashes are
byte-identical to the old PPMs, so the baseline is unchanged — only its form.
- game_case now compares framebuffer hashes; a regression shows as a changed
hex line in review, not "binary files differ".
- New `bin/x golden` regenerates the manifest deliberately (review with
`git diff selfhost/golden/renders.sha256`).
#27 — PPM & asset handling
- Headless renders now write build/out.ppm, never the repo root; `x app`,
`x clean`, messaging and .gitignore updated to match. Nothing is written to
the working root any more.
- Redundant local Kenney .zip archives removed (the art ships extracted;
.gitignore already excludes *.zip). CC0 License.txt files retained.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>