A load freed only the parsed trip's nodes (Json.free) and kept every string the parser made, because
a loader might keep one; free_all freed every string and every key, so on a tree a migration had
added a literal to (`Value.put(v, "sver", Value.str("2"))`) it freed the literal and aborted.
- The parser marks the string values it makes (JP_OWNED, in the node's otherwise unused num) and
interns object keys (a few names, never freed); free_all frees only marked strings, never keys,
and a list's spares too. A setter that gives a marked node other text (value_set_str/_strs,
value_into_str/_strs, value_become) frees the parser's text first. value_as_int / _as_float read a
string as 0 as before.
- ludic.base sv_str returns intern(...): every package load that keeps a text read from a section
(minimap labels, a Thing's look, photo tags and files, an effect's label, ...) holds its own copy.
Golden json_free_edited: parse, put a literal key and string in, set a string, keep an interned copy,
free_all - 1100 loads: the copy reads on and nothing grows (the toolchain before this aborts, 134).
Tests: ludic.save, base, settings, minimap, things, photo, effects; json_saves, value_list_regrow; the
36 ui examples.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| actions | ||
| ecs | ||
| events | ||
| functions | ||
| games | ||
| lang | ||
| library | ||
| modules | ||
| networking | ||
| rejected | ||
| rendering | ||
| state | ||
| README.md | ||
Examples
A curated tour of Ludic, grouped by intent. Every example here is exercised by
the test suite (bin/ludic-dev test / bin/ludic-dev selfhost-test), so nothing in this
directory silently rots.
Run any program straight from the repository root (so assets/ resolves):
bin/ludic build examples/games/snake.ludic # compile + open a real window
bin/ludic build examples/games/snake.ludic --headless # render one frame to build/out.ppm
bin/ludic examples/lang/offline_rewards.ludic # compile + run a plain program
games/ — complete, windowed games
| Example | What it shows |
|---|---|
games/snake.ludic |
A full game from primitives: input, grid, growth, collision, score. |
games/menu.ludic |
A retained-UI title screen — the UI declared as data. |
games/chronorift.ludic |
A 2D co-op JRPG: overworld, dungeon, random encounters, turn battle, boss, save. The entry file imports the modules under games/chronorift/. |
rendering/ — drawing primitives
| Example | What it shows |
|---|---|
rendering/draw_prims.ludic |
The extended Screen.* primitives — line, circle, triangle, fill, sprite. |
ecs/ — the entity-component world
| Example | What it shows |
|---|---|
ecs/hello.ludic |
The smallest program that exercises the ECS pipeline. |
ecs/world_get.ludic |
Reflection: read/write a component by name. |
ecs/world_scan.ludic |
Reflection: scan the world and identify each entity. |
ecs/world_query.ludic |
Reflection: iterate the world by property. |
ecs/world_spawn.ludic |
Reflection: a mod spawns a fresh entity by model id. |
ecs/world_mixed.ludic |
Reflection: get/set through real struct offsets. |
ecs/world_dyn.ludic |
Reflection: register a brand-new component at runtime. |
events/ — the event bus
| Example | What it shows |
|---|---|
events/events.ludic |
EV0: the event-bus core — declare, emit, @On. |
events/mod_events.ludic |
Two listeners on one event, driven from a mod. |
events/cancel.ludic |
EV3: cancellable (decision) events. |
events/recurse.ludic |
EV6: re-entrant emit is depth-bounded — no runaway cycle. |
events/promote.ludic |
EV1: @Public promotes a lifecycle hook to a public event. |
events/prop_events.ludic |
EV1 for properties: attach/detach events. |
events/scene_events.ludic |
EV1 for scenes: on-enter / on-exit events. |
events/program_events.ludic |
EV1 for the program scope: start/quit events. |
events/layer_events.ludic |
EV1 for layers + a public layer's show/hide events. |
events/scoped.ludic |
A despawned entity drops out of subsequent event work. |
networking/ — deterministic multiplayer (N0–N6)
Each maps to a stage of the Networking design; all run over the compiler's built-in loopback transport with zero foreign code.
| Example | What it shows |
|---|---|
networking/net_echo.ludic |
N0: the transport seam. |
networking/net_snapshot.ludic |
N1: whole-world snapshot to a memory buffer. |
networking/net_sync.ludic |
N2: @Sync replication codegen. |
networking/net_owner.ludic |
N3: entity ownership. |
networking/net_rpc.ludic |
N4: remote events / RPCs. |
networking/net_roles.ludic |
N5: handler roles + the drivable sim. |
networking/net_demo.ludic |
N6: a networked game end to end, in pure Ludic. |
networking/net_rt.ludic |
A blessed server-authoritative replication runtime. |
lang/ — language & standard-library tour
| Example | What it shows |
|---|---|
lang/annotations.ludic |
The annotation-first style: @Queries / @Computed / @OnSpawn / @Handles. |
lang/qdecl.ludic |
@Queries desugaring to the query system. |
lang/lifecycle.ludic |
The whole game lifecycle as @-hooks, in firing order. |
lang/detach.ludic |
Structural attach/detach + @OnAttach / @OnDetach. |
lang/reason.ludic |
Reason-carrying teardown (@OnDespawn: Despawned vs Quit). |
lang/toggle.ludic |
enable/disable at the three ECS scopes. |
lang/scenes.ludic |
One active scene at a time, handlers grouped into layers. |
lang/strings.ludic |
Strings as values: compare, join, interpolate, slice. |
lang/operators.ludic |
Compound assignment on every type, unary minus, char escapes, list literals. |
lang/rng_demo.ludic |
The Random.* extensions (value/int/sign). |
lang/time_demo.ludic |
Time.frame / elapsed / delta. |
lang/offline_rewards.ludic |
A worked idle-game example over the Time/Date/Duration stdlib. |
library/ — building and linking a shared library
A how-to for compiling a .ludic module to a native .dylib/.so/.dll and
linking a second program against it via extern fn:
bin/ludicc examples/library/combat.ludic --shared -o build/libcombat.dylib
bin/ludicc examples/library/arena.ludic -o build/arena -Lbuild -lcombat
| Example | What it shows |
|---|---|
library/combat.ludic |
Exported functions callable across the C ABI. |
library/arena.ludic |
A program that links against the shared library. |