Gododin Gododin Documentation

Example project

Ripple Pond — adopting Gododin in an existing game

examples/ripple_pond/README.md

View original Markdown · Download · All examples

A tiny complete Godot game that teaches one full incremental adoption: a working GDScript game keeps its scene, its rendering, and its optimized GDScript baseline, and moves its one substantial batch operation — the per-frame wave-equation step over the pond grid — into a pure Odin package behind one small native class.

The example directory is the adopted game. game/ beside it is the same game as it existed before adoption, kept runnable so every delta adoption made is visible and diffable.

The game

Click the water to splash it; waves reflect, interfere, and settle. In the adopted version, keys 1 and 2 switch which arm steps the water each frame:

  • GDScript — the preserved baseline (gd_ripples.gd, byte-identical in game/ and here): the same fixed-step wave equation on two packed f64 buffers with one integer write per cell.
  • Odin (native) — the same arithmetic in subsystem/pond.odin, reached through the scene's RipplePond node: one step call and one coarse frame_bytes call per frame, no per-cell foreign calls.

Both arms run the identical f64 expression sequence, so the water is byte-for-byte identical — tests/oracle.gd proves it — and the example makes no performance claim. The on-screen per-step milliseconds are a host-local observation; measured, fair language comparisons are their own workload (see the repository's comparison plans), not a claim this example makes.

Requirements

One extracted immutable Gododin SDK, the exact locked Odin compiler, and the exact pinned Godot executable named by the SDK's gododin.lock — the same prerequisites as the other examples (examples/setup.sh wires every example at once, including this one). No machine-local sibling folders, no private environment variables, no copied manifests.

Run and test

The five-chapter usage guide teaches adoption, authoring, iteration and export; setup covers installation. This README owns the example's controls, modes, source map and retained journey evidence.

Use shared example setup to connect this configured project to its matching SDK, compiler and engine, then run:

sh
cd examples/ripple_pond
./test.sh              # pure kernel, before/after game discipline, pipeline, oracle
./test.sh play         # public launcher, interactive windowed game
./test.sh oracle       # public launcher, headless byte/signal oracle

Modes are all (default), subsystem, game, pipeline, oracle and play. The oracle requires GODODIN_RIPPLE_ORACLE_PASS (600 frames, six byte checkpoints and six signal deliveries), GODODIN_RUN_PASS and zero Host owners. Its exit status is the application test result; it measures no speed.

GODODIN_PROFILE=release ./test.sh selects a release pipeline build. Currently oracle and play invoke public run without --profile, so those two modes still launch debug even if that environment variable is set. To test/run release, use the public profile-aware commands with this example as project. Do not infer the launch profile from the shell variable; inspect GODODIN_RUN_IDENTITY.

To replay adoption, the guide starts from a copy of game/. To inspect the change here, compare game/main.tscn and game/main.gd with the root versions: one native RipplePond child and the native arm/signal wiring are added; project.godot and the GDScript baseline remain byte-identical.

File responsibilities

File Owns
game/ the before state — never touched by adoption, kept for the diff
project.godot, main.tscn, main.gd, gd_ripples.gd the game: scene, input, HUD, rendering, GDScript baseline
tests/oracle.gd the application test: native vs GDScript byte oracle
declarations/ripple_pond.odin the authored class — the single source for the native surface
subsystem/pond.odin (+ _test) the pure kernel and its ownership/determinism tests
generated/ the generated catalog, bridge and docs; generate publishes the current bundle, and its output is never hand-edited
gododin.toml, gododin.lock portable intent; exact accepted identities

Journey record

Executed end to end on Windows x86-64 (development-host evidence under the desktop workstream; the installed attach flow itself carries the recording host's evidence): checkout authority over an adopted copy of game/, gododin init reporting mode=adopted with the game's three files byte-identical, doctor/generate/check green (one class, 11 operations, one property, one signal), accepted debug and release builds, the oracle passing through the public launcher (frames=600 checkpoints=6 signals=6, zero owners), both profiles exported and the exported applications executed with their identity environment and zero-owner shutdowns, and one native editor reload cycle observed clean end to end. Friction found and recorded: gododin init's template still hardcodes .dylib library names and a macOS target row on every host (a Windows/Linux consumer renames them — this example's committed files use the suite's recording-host shape), and the gododin generate/check lifecycle path needed two Windows fixes that landed with this example (mixed-separator managed-Odin paths and the generate stage's symbol-tool resolution); both are recorded in the platform migration record pending the next SDK reseat. The committed generated/ starts as the init skeleton: one gododin generate on a host with the selected SDK publishes the bundle this directory's committed toml binds.