Commit graph

11 commits

Author SHA1 Message Date
19fcf60599 wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run
ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
  1804 vars into 126 states, 64 into lets; 23498 edits in 460 files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00
5ffe50ed02 wip(0.S2): migrate - a var nothing writes becomes a let; a state is keyed by its module, directory or program, so every program's plan agrees; paths normalized; program states named SceneDemoState / scene_demo_st; the LSP reads state, mut and entry/handler parameters
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00
3eda72e8c2 wip(0.S3): packages and examples migrated in one run - ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:02:45 +03:00
aca263642d feat(cli): install in one command, and call the CLI ludic
Getting started meant cloning the repository, bootstrapping a compiler and
learning a task runner called `x`. That is a contributor's workflow handed to
everyone who wants to try the language.

Installing is now one command:

    curl -fsSL https://workshopsoft.pages.workshopsoft.io/ludic/install.sh | sh

install.sh puts a complete toolchain — compiler, CLI, engine runtime, bundled
ludic.* packages, formatter, language server — in ~/.ludic and adds it to PATH.
Prebuilt artifacts are checksum-verified; where a platform has none, or the
release predates this layout, it bootstraps from the compiler's own IR seed with
clang. The docs site publishes the script beside the pages that quote it, so the
page and the script can never come from different releases.

`x` becomes `ludic`, and the surface splits by audience. A user of the language
sees `new`, `run`, `build`, `test`, `add`, `fmt`, `lsp`, `doctor`, `upgrade`;
`ludic new` scaffolds a project that builds and plays as it stands. Everything
the toolchain repo needs moved under `ludic dev` — build, test, reseed,
bootstrap-cfree, docs-gen, release — unchanged apart from the namespace. Those
tasks read arguments one position further along, so dispatch_dev sets a shift
and commands use arg_n()/arg_total() rather than each knowing its own depth.

Release artifacts become complete install roots (bin/ beside runtime/, packages/
and VERSION) rather than bare binaries, which is what the installer unpacks.
`ludic dev test` asserts the whole shape: it stages an install, puts it on PATH
with no LUDIC_HOME, and runs new -> build -> test through it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:01:52 +03:00
bf36bc8a8f refactor(runtime,packages,examples): named constants, package enums, idiom sweep
- runtime: HEADLESS_FRAME_PATH, STICK_DEADZONE / STICK_LEFT_X/Y, key and
  byte codes as char literals throughout (`k == 'w'`, `fill(rt_map, ' ', …)`)
- ludic.gameplay/stats: drop the duplicate `stat_field` (it answered "atk"
  for every build stat); Stats.base uses stats_field_name
- ludic.shooter: compare aim modes and fire patterns with AimMode.* and
  WeaponPattern.* instead of raw ints; STICK_RIGHT_X/Y
- ludic.npcai: DecisionMade / brain_set_state use AiState.*
- examples/games/menu.ludic uses Font.load / Ui.* with FONT_PATH and
  BACKDROP named; strings.ludic header says what it prints
- whole tree: `x = x + 1` → `x += 1` (single-term right-hand sides only),
  `0 - x` → `-x`, ASCII codes → char literals; every .ludic and every
  ```ludic fence reformatted with the fixed formatter (whitespace only)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 01:12:26 +03:00
57b8747c31 feat(render): #85 engine sprite-render system + deprecate bare draw_sprite
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 23s
ci / build-and-test (push) Successful in 2m20s
commit-lint / conventional-commits (push) Successful in 5s
docs / build-and-deploy (push) Successful in 28s
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>
2026-09-02 07:20:13 +03:00
46c275c4c1 feat(controllers): #59 RPG systems — ludic.rpg 7-module suite (base + extensible)
Some checks failed
commit-lint / conventional-commits (push) Waiting to run
docs / build-and-deploy (push) Waiting to run
bootstrap / cfree-fixpoint (push) Successful in 21s
ci / build-and-test (push) Has been cancelled
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>
2026-09-01 17:25:56 +03:00
9ce69d23e3 feat(controllers): #61 NPC AI — ludic.npcai package (base + extensible)
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 22s
ci / build-and-test (push) Successful in 2m11s
commit-lint / conventional-commits (push) Successful in 4s
docs / build-and-deploy (push) Successful in 29s
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>
2026-09-01 17:12:32 +03:00
02a8bcc324 feat(controllers): #60 shooter — ludic.shooter package (base + extensible)
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 21s
ci / build-and-test (push) Successful in 2m9s
commit-lint / conventional-commits (push) Successful in 4s
docs / build-and-deploy (push) Successful in 28s
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>
2026-09-01 17:04:49 +03:00
dd5cb5817b feat(controllers): #58 platformer — ludic.platformer package (base + extensible)
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 21s
ci / build-and-test (push) Successful in 2m8s
commit-lint / conventional-commits (push) Successful in 4s
docs / build-and-deploy (push) Successful in 28s
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>
2026-09-01 16:41:34 +03:00
fb728bbefe chore(repo): DX cleanup — categorise examples, text-diffable golden, build/ output (#27 #28 #30)
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>
2026-08-30 18:54:21 +03:00