Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Box2D v3.1.0 (fetched by CMake)
- **LCB binding** (`src/box2dxt.lcb`, `library org.openxtalk.box2dxt`): declares `foreign handler`
bindings to the shared library and public `b2PascalCase` handlers callable from xTalk. This API
speaks **metres and radians**; body type codes are `0=static, 1=kinematic, 2=dynamic`.
- **The Kit** (`src/box2dxt-kit.livecodescript`): a pure-xTalk convenience layer (260+ `b2k*`
- **The Kit** (`src/box2dxt-kit.livecodescript`): a pure-xTalk convenience layer (312 `b2k*`
handlers incl. the game modules: input, sprites, player controller, camera) that speaks
**screen pixels and degrees**, binds bodies to LiveCode controls, and runs the animation
loop. This is what the examples and most users actually call.
Expand All @@ -44,12 +44,15 @@ Docs live in `docs/` (`architecture.md`, `building.md`, `getting-started.md`, `a
binaries are in `prebuilt/` — the SOURCE `tools/package-extension.py` lays into the extension's
`src/code/<arch>-<platform>/` tree; the install is the packaged extension, not a loose drop-in (a
loose `box2dxt.{so,dll,dylib}` beside a saved stack is only the dev/fallback path, mapped at runtime
by the Kit's `b2kEnsureNativeLib`). The **Game Kit** (input/sprites/player/camera/sound modules, plan.md
Phases 0-5) is implemented and user-verified on Win32; `plan.md`'s decision log is the as-built
record. Six examples: demo, contraption builder, spike (Phase-0 harness), **platformer showcase**
(the Game Kit pushed hard — the focus of this repo's game work), **slingshot** (angry-birds-style
tower knockdown — the physics core carrying a whole game with zero events and zero assets), and the
**self-test harness** (below).
by the Kit's `b2kEnsureNativeLib`). The **Game Kit** (input/sprites/player/camera/sound modules) is
implemented and user-verified; content **Waves 0-7 are built** (Wave 8, builder cross-pollination, is
the only remaining roadmap item); `plan.md`'s decision log is the as-built record. Six examples: demo,
contraption builder, **spike-gamekit** (the Phase-0 Game Kit harness), **platformer** (the flagship
game showcase — the Game Kit pushed hard across 5 levels, with bestiary I + variety walkers + bestiary
II frog/barnacle/spider — the focus of this repo's game work), **slingshot** (angry-birds-style tower
knockdown over 3 levels — the physics core carrying a whole game with zero events and zero assets), and
the **self-test harness** (below). (The single-screen micro-game was retired in Wave 5; its "whole game
from the physics core" pattern survives only as `kit-guide` section 20 prose.)

## The golden rule: the embedded-Kit sync

Expand Down Expand Up @@ -105,9 +108,9 @@ failure. Run it after **every** `.livecodescript` edit.
pass" and let the user confirm.

**The self-test harness** (`examples/box2dxt-selftest.livecodescript`) is the runtime safety net:
~125 deterministic assertions (currently **v12**) driving the real Kit (paused world +
`b2kStepOnce` hand-stepping + `b2kInputInject` scripted keys). The workflow for every **Kit**
change: (1) add/extend an assertion
~180 deterministic assertions across 37 test handlers (currently **v22**) driving the real Kit
(paused world + `b2kStepOnce` hand-stepping + `b2kInputInject` scripted keys). The workflow for
every **Kit** change: (1) add/extend an assertion
that captures the new behavior, (2) **bump `kStHarnessV`** (the report header prints it, so a
stale paste identifies itself), (3) the user clicks RUN ALL TESTS and reports. **Example-only
changes do NOT bump the harness** — the rule is conditional on Kit edits (Waves 1 and 3 shipped
Expand Down Expand Up @@ -395,7 +398,7 @@ Every kind must be wired through the **whole pipeline** or it half-works. Touch
rows; save-keys unique per kind; selection is non-destructive (`selectPart` stores `uSelFg`/`uSelLine`
and `deselectPart` restores them, so highlighting never corrupts a part's real colours).

## Contributing conventions (from CONTRIBUTING.md)
## Contributing conventions

- **Units/types across the FFI:** reals `double`, booleans `int` (0/1), handles positive `int`
(0 invalid, opaque). `b2*` = metres/radians, `b2k*` = pixels/degrees.
Expand Down
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ Box2D v3.1.0 (fetched by CMake)
a full build-and-run physics sandbox with fans, magnets, lasers, bombs,
motors, and save/load. Game-minded? The
[platformer showcase](examples/box2dxt-platformer.livecodescript) is the
Game Kit pushed hard — player controller (run, double-jump, wall-jump,
dash, climb, crawl, swim), scrolling camera, spritesheets, moving
platforms, coin puzzles, a hilltop swim pool — and the
Game Kit pushed hard — five scrolling levels (grass, stone, ice, haunted,
desert) with a full player controller (run, double-jump, wall-jump, dash,
duck, climb, swim, drop-through, platform-carry), a bestiary (bats, a
mimic, piranhas, a ghost, a kickable snail shell, crushers, and more),
joints (rope bridge, boulder, exploding barrel, collapsing bridge),
spritesheets, and synthesized audio — and the
[slingshot](examples/box2dxt-slingshot.livecodescript) is pure physics
joy: catapult cannonballs into toppling towers, angry-birds style
(three levels, ballistic aim preview, zero assets). And the
Expand Down Expand Up @@ -92,9 +95,13 @@ x86) on every push; see [docs/building.md](docs/building.md).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for the layer conventions, the
embedded-Kit sync rule, and the static checks
(`python3 tools/check-livecodescript.py`) that gate every change.
The three layers and their conventions are in
[docs/architecture.md](docs/architecture.md); the build is in
[docs/building.md](docs/building.md). The Kit is the single source of truth —
after editing `src/box2dxt-kit.livecodescript`, re-sync the embedded copies
with `python3 tools/sync-embedded-kit.py`. Two static gates run on every change
(and in CI): `python3 tools/check-livecodescript.py` (the script layer) and
`python3 tools/sync-embedded-kit.py --check` (embedded-Kit drift).

## License

Expand Down
2 changes: 1 addition & 1 deletion dist/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The game builds itself and starts immediately.
- **Controls:** **arrows / WASD** move · **Space** jump (press again in mid-air
to **double-jump**, or off a wall to **wall-jump**) · **SHIFT / X** dash ·
**↓** duck · **R** restart · **M** mute. Grab every coin (the flag turns gold)
and touch the flag to advance — there are four levels.
and touch the flag to advance — there are five levels.

That's it. Enjoy the physics.

Expand Down
44 changes: 24 additions & 20 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,46 +116,50 @@ the recipient a one-step install with the right native library bundled in — no
loose libraries to place.

To instead hand someone a ready-to-run game as a single self-contained zip (no
repo, no toolchain, no internet, no extension install step), bundle the source
(extension + C shim + Kit), the per-platform native libraries under their bare
name, the demo's spritesheets, a built **and saved** stack, and the end-user
install guide. `tools/make-release.py` does it — the recipient runs straight from
the unzipped folder, with the Kit's `b2kEnsureNativeLib` mapping the
beside-the-stack library at runtime (the dev/fallback path, no install needed):
repo, no toolchain, no internet), bundle the extension (the `.lcb` plus its
`code/<arch>-<platform>/` native libraries), the C shim + Kit for reference, the
demo's spritesheets, a built **and saved** stack, and the end-user install guide.
`tools/make-release.py` does it — the native library travels **inside the
extension**, so the recipient installs one extension and the engine loads the
right per-platform library automatically (no loose library to place):

```sh
# Build & SAVE the stack in OXT first (e.g. the platformer), then:
python3 tools/make-release.py --stack /path/to/NewPlateformerDemo.oxtstack
# -> dist/NewPlateformerDemo.zip
```

It copies `src/box2dxt.lcb` / `box2d_lc.c` / `box2dxt-kit.livecodescript` into
`source/`, renames each `prebuilt/` library to the bare name the Kit maps under
`libraries/`, copies the platformer's `Spritesheets/` art into `spritesheets/`,
adds `dist/INSTALL.md`, and drops your saved stack at the root — producing:
It copies `src/box2dxt.lcb` together with its whole `src/code/` tree into
`extension/` (run `tools/package-extension.py` first to populate it), copies
`box2d_lc.c` / `box2dxt-kit.livecodescript` into `source/` for reference, copies
the platformer's `Spritesheets/` art into `spritesheets/`, adds `dist/INSTALL.md`,
and drops your saved stack at the root — producing:

```
NewPlateformerDemo/
├── NewPlateformerDemo.oxtstack # your --stack
├── INSTALL.md # the three-step end-user install guide
├── source/ box2dxt.lcb, box2d_lc.c, box2dxt-kit.livecodescript
├── libraries/ box2dxt.{dll,dylib,so}
├── INSTALL.md # the end-user install guide
├── box2dxt.lce # optional prebuilt extension (only with --lce)
├── extension/ box2dxt.lcb + code/<arch>-<platform>/box2dxt.{so,dll,dylib}
├── source/ box2d_lc.c, box2dxt-kit.livecodescript (reference)
└── spritesheets/ the demo's PNG + XML sheets
```

Override a library with `--win` / `--mac` / `--linux` (e.g. an SSE2 or
older-glibc build), the art folder with `--sheets`, or the stack's in-zip name
with `--stack-name`; `--check` validates the inputs without writing the zip.
The recipient follows `INSTALL.md`: drop their platform's `libraries/` file
beside the stack, **Load** `source/box2dxt.lcb`, open the stack, and point its
Pass `--lce /path/to/box2dxt.lce` to drop a prebuilt extension in too (so testers
can install in one click instead of Packaging `extension/box2dxt.lcb`
themselves); override the art folder with `--sheets`, the stack's in-zip name
with `--stack-name`, or the output path with `--out`; `--check` validates the
inputs without writing the zip. The recipient follows `INSTALL.md`: install the
`.lce` (or open `extension/box2dxt.lcb` in the Extension Builder and **Package**
it — keeping its `code/` folder alongside), open the stack, and point its
first-run prompt at `spritesheets/`.

## Platform & CPU notes

- **AVX2 / SIMD.** Box2D assumes **AVX2** on x64 by default. If your binary must
run on older CPUs, configure Box2D with `-DBOX2D_DISABLE_SIMD=ON` (slower) or
an SSE2 build. The committed `prebuilt/linux-x86_64` binary is built with SIMD
disabled so it runs anywhere.
an SSE2 build. The committed `prebuilt/libbox2dxt-linux-x86_64.so` binary is
built with SIMD disabled so it runs anywhere.

```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBOX2D_DISABLE_SIMD=ON
Expand Down
68 changes: 40 additions & 28 deletions docs/expansion-prep.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ that keep the expansion as reliable as the engine underneath it.

| | |
|---|---|
| Baseline | Kit + games user-verified; self-test harness **v10, ~113 assertions, all pass** (Wave 2 closed 2026-06-13) |
| Baseline | Kit + games user-verified; self-test harness **v22, ~180 assertions across 37 test handlers, all pass** (current; Waves 1–7 all closed) |
| Assets | **LANDED (2026-06-11)** — Kenney's iconic platformer family, ~900 frames; Wave 0 catalogue below |
| Wave 1 | **COMPLETE — user-verified 2026-06-12** (the three-level platformer; see §7) |
| Wave 2 | **COMPLETE — user-verified 2026-06-13** (player actions I, harness v10; see §9) |
| Wave 3 | **BUILT — statically verified 2026-06-13** (bestiary I + HAUNTED HOLLOW; see §10) |
| Showcase polish | **BUILT — statically verified 2026-06-13** (pre-Wave-4: longer/re-spaced levels, the kit's first JOINT mechanics — rope bridge + boulder + barrel; a prototyped wrecking ball was cut as un-sprite-able — and four variety species; all example-side, zero Kit change, no harness bump) |
| Wave 4 | **SWIM user play-tested in the platformer 2026-06-14** (harness **v12**, two Opus reviews clean; see §11). The Kit gained `b2kPlayerAddWater` + a buoyant `swim` mode/state/anim; the platformer's L1 GREEN HILLS gained a **HILLTOP POOL** (a raised-bank basin — the swim showcase, where it's tested), tuned heavier and with the hero hitbox fixed to match the art (gotcha 28), all per the user's OXT pass. DONE: swim zones, pit-dwellers (the micro-game `fish`, debut), lava (already in platformer L4). CARRY-OVER: the collapsing-bridge trap, and the micro-game's L3 "THE DEEP" (built but shows an example-side white-world build issue — set aside) |
| Wave 5 | **BUILT — statically verified 2026-06-14** (player actions II: double-jump `airJumps`, wall-slide/jump, dash, duck capsule-reshape, moving-platform carry — all opt-in Kit knobs, defaults unchanged; harness **v13**, six new tests; see §12). Enabled + showcased in the platformer; the micro-game was retired (focus is the platformer). Awaiting the OXT feel pass. |
| Next | Iterate Wave 5 feel in OXT (the new moves' tuning numbers are first-pass); the collapsing-bridge trap remains a loose end |
| Wave 1 | **COMPLETE — user-verified 2026-06-12** (the iconic-feel base; shipped as a three-level platformer, since grown to **five levels**; see §7) |
| Wave 2 | **COMPLETE — user-verified 2026-06-13** (player actions I; see §9) |
| Wave 3 | **COMPLETE — statically verified 2026-06-13** (bestiary I + HAUNTED HOLLOW; see §10) |
| Showcase polish | **COMPLETE — statically verified 2026-06-13** (pre-Wave-4: longer/re-spaced levels, the kit's first JOINT mechanics — rope bridge + boulder + barrel; a prototyped wrecking ball was cut as un-sprite-able — and four variety species; all example-side, zero Kit change, no harness bump) |
| Wave 4 | **COMPLETE — SWIM user play-tested in the platformer 2026-06-14** (see §11). The Kit gained `b2kPlayerAddWater` + a buoyant `swim` mode/state/anim; the platformer's L1 GREEN HILLS gained a **HILLTOP POOL** (a raised-bank basin — the swim showcase, where it's tested), tuned heavier and with the hero hitbox fixed to match the art (gotcha 28), all per the user's OXT pass. DONE: swim zones, lava (platformer L4), the collapsing bridge (now L4's lava crossing). |
| Wave 5 | **COMPLETE** (player actions II: double-jump `airJumps`, wall-slide/jump, dash, duck capsule-reshape, moving-platform carry — all opt-in Kit knobs, defaults unchanged; see §12). Enabled + showcased in the platformer; the **micro-game was retired here** (focus is the platformer). |
| Wave 6 | **COMPLETE — statically verified, merged** (bestiary II: frog hopper, barnacle lurking clam, spider ceiling-dropper — woven into L1/L2/L4). |
| Wave 7 | **COMPLETE — statically verified, merged** (the desert biome: **L5 SCORCHED DUNES** — the platformer's fifth level, sand/desert). |
| Wave 8 | **NOT STARTED** — builder cross-pollination (animated sprite parts + the player-as-a-part in the Contraption Builder); the only remaining roadmap item. |
| Next | Wave 8: the builder cross-pollination. |
| Companions | [plan.md](../plan.md) (history/decision log) · [game-engine-spec.md](game-engine-spec.md) (module design) |

---
Expand Down Expand Up @@ -178,11 +181,13 @@ to Kit API (`b2kFoe…`).
platformer re-skinned sprite-only (real thwomp art, spike tiles, biome
ground). *The "it looks like the classics now" wave.*
**COMPLETE — user-verified 2026-06-12.** Shipped as a **three-level
platformer**: L1 GREEN HILLS (movement + the toys: springboard, bonk
row, one-way bridge, mound, clouds, spike pit), L2 THE WORKS (button
gate, saw lever, thwomps, yellow key + the walled door), L3 FROZEN
CITADEL (everything on ICE, snow biome, a second saw, red key +
door). Springboards, ?-boxes paying coins, POOLED brick debris,
platformer** (a historical milestone — the platformer has since grown
to **five levels** through Waves 3 and 7): L1 GREEN HILLS (movement +
the toys: springboard, bonk row, one-way bridge, mound, clouds, spike
pit), L2 THE WORKS (button gate, saw lever, thwomps, yellow key + the
walled door), L3 FROZEN CITADEL (everything on ICE, snow biome, a
second saw, red key + door). Springboards, ?-boxes paying coins,
POOLED brick debris,
button art on the polled plate, stand-to-flip lever, chained-weight
thwomps (static at rest, **not player-movable**), walled doors whose
gates are STRUCTURAL (floor-to-ceiling; the flag and last coins
Expand Down Expand Up @@ -210,25 +215,32 @@ to Kit API (`b2kFoe…`).
Design in §9; as-built record in plan.md's decision log. The §9
ABI question resolved to NO ABI CHANGE (the shim's pending
shape-def filter already covers chain creation).
3. **Wave 3 — bestiary I:** shelled (kickable!), ghost, bat, mimic,
pipe plant, crusher-with-faces — into a platformer "haunted" section.
4. **Wave 4 — liquids:** swim zones (done — the platformer's hilltop pool)
+ lava (already in L4) + pit dwellers (the micro-game fish) + the
collapsing bridge (carry-over). As-built record in §11.
5. **Wave 5 — player actions II:** wall-slide/jump, dash, double-jump
powerup (boxItem delivers it), platform carry.
6. **Wave 6 — bestiary II + promotion:** chaser, lunger, spider, saws;
`b2kFoe…` promotion decision with two consumers in hand.
7. **Wave 7 — the showcase level:** one long level using every biome
mechanic — the "iconic platformer" demonstration piece, plus sprite HUD.
8. **Wave 8 — builder cross-pollination** (closes Phase 5): sprite parts +
the player as placeable kinds in the contraption builder.
3. **Wave 3 — bestiary I (COMPLETE):** shelled (kickable!), ghost, bat,
mimic, pipe plant, crusher-with-faces — into the platformer's L4
"HAUNTED HOLLOW".
4. **Wave 4 — liquids (COMPLETE):** swim zones (the platformer's hilltop
pool) + lava (L4) + the collapsing bridge (now L4's lava crossing).
As-built record in §11.
5. **Wave 5 — player actions II (COMPLETE):** wall-slide/jump, dash,
double-jump powerup (boxItem delivers it), platform carry. The
micro-game was retired here.
6. **Wave 6 — bestiary II + promotion (COMPLETE):** frog hopper,
barnacle lurking clam, spider ceiling-dropper — woven into L1/L2/L4;
the `b2kFoe…` promotion decision deferred (no second consumer yet —
the micro-game retired).
7. **Wave 7 — the desert biome (COMPLETE):** the platformer's fifth
level, **L5 SCORCHED DUNES** (sand/desert) — the "iconic platformer"
demonstration piece.
8. **Wave 8 — builder cross-pollination (NOT STARTED — the only
remaining roadmap item):** sprite parts + the player as placeable
kinds in the contraption builder.

## 8. Open questions / risks

- **macOS/Linux (R1):** unverified; the self-test is the acceptance suite.
- **`b2kScene*` promotion:** likely lands with Wave 4 (a third level wants
the format) — decide then.
- **`b2kScene*` promotion:** did NOT land — the platformer reached five
levels (through Wave 7) keeping its scenes example-side, so the format
was never promoted to Kit API. Revisit only if a second game needs it.
- **`spritesheet_complete.xml`** is an orphan (its `sprites.png` wasn't
uploaded) — no content loss; upload the PNG later or delete the XML.
- **Mixed grids:** 70px (C) vs 128px (B) — normalised per level via
Expand Down
Loading
Loading