Goose

Goose samples

If you have not written Goose before, read docs/tutorial.md first: it introduces the language by example and says which of these to read when. docs/reference.md then covers the whole language, topic by topic.

These short, self-contained programs demonstrate common programming tasks using Goose's memory model: flat data, references into growing arrays, relative links, and variable-size enums, without heap allocation. Each file starts with a comment explaining what it demonstrates. The files are numbered in reading order. The later samples assume familiarity with the first six.

Build any sample into an executable beside it with the C compiler the Goose compiler finds on the machine, or run it straight away inside the compiler's process:

goose build 01_tour.goose && ./01_tour
goose 01_tour.goose

The C the compiler writes can also be built by hand (goose -o tour.c 01_tour.goose, linked with the runtime goose --emit-runtime writes, or --standalone for a C file that holds the runtime itself); goose build --dry-run prints those commands.

run_samples.py compiles and runs them all and compares their output with expected/, both ways where the backend is available; test/run_tests.py calls it, so they are compiled and run as part of the test suite.

Foundations

Sample What it shows
01_tour The core language in one program: values and widths, every array kind, slices, structs, control flow as expressions, several results, optionals, references bound with .= and compared with .==.
02_memory The memory model, made visible: references that survive growth, scope exit as the only free, scratch buffers cleared through a helper, flat nested containers, copy, grow-shrink stacks, limited arrays, reusable pools.
03_strings Strings as u8 arrays: builders, str/format, slices as safe views, split/trim/join/find, parsing, sorting slices, UTF-8, inline small strings, a format overload.
04_errors The three error idioms: a trailing bool, an optional narrowed by if/guard, and return ... from for deep failures; assert, abort, exit.
05_shapes Algebraic data types in fixed and variable mode, match by value and by reference, case functions as the virtual-call idiom; variable-mode values with their text inline, one flat array, reached in any order through an index of 4-byte in pool links.
06_functions Generics without declaring them, overloading, UFCS, blocks that compile to loops, return through a HOF, nested functions with free variables.

Classic algorithms

Sample What it shows
07_sieve Eratosthenes: a tight loop at declared widths with the bounds checks proved away; Euclidean %; wrapping unsigned hashes.
08_bignum Arbitrary precision on u32 limbs with u64 carries: 100!, fib(500), 2^1000, decimal printing, a format overload; grow-only numbers popped through references.
09_sorting Insertion sort, a recursive merge sort with caller-owned scratch, binary search, all over slices; the library's sort and stable_sort; timings on a million ints.
10_sudoku Backtracking with u16 bitmask candidates and fewest-candidates-first, the whole state one struct passed by reference.
11_maze BFS and Dijkstra over a byte grid: a grow-only queue with a read head, a grow-shrink heap through heap_push/heap_pop, paths drawn back onto the maze.
12_huffman Frequencies, a priority queue, a code tree with 2-byte relative links, bit packing, and a round trip.

Data structures

Sample What it shows
13_linked_list A doubly-linked list in a reusable pool with in pool links and a self sentinel found by .==: O(1) insert/remove through references, slot reuse, move-to-front.
14_bst A binary search tree in a grow-only pool with self-relative links: insertion by retargeting one reference, recursive walks with caller-owned output.
15_word_freq Word counts of a text file with a dictionary keyed by slices into the text: nothing copied, results sorted and tabulated.
16_records Orders with inline strings and item lists kept as one flat array of variable-size records; per-customer totals through a dictionary.

Parsers and interpreters

Sample What it shows
17_calc An interactive calculator: tokens as fixed-mode enum values, recursive descent straight to values by functions nested in evaluate that share its locals, variables in a dictionary, every error one return ... from. Run with calc < data/calc.stdin.
18_json A JSON parser and printer: variable-mode nodes in one pool with 4-byte relative links, the parser state as locals of parse shared by the nested recursive functions, deep errors with positions, pretty and compact rendering, key and index lookups.
19_vm A stack bytecode VM: a fixed-mode enum per instruction, a match dispatch loop, a disassembler, two hand-assembled programs.

Graphics, simulation, threads

Sample What it shows
20_life Conway's Life on a torus: two byte grids that swap roles, Euclidean % wraparound, ASCII frames.
21_raytrace Spheres, a floor, shadows and reflections with float3 math; writes raytrace.ppm and prints an ASCII preview.
22_image_filters Box blur and Sobel over row slices, bounds-check free; writes .pgm files.
23_mandelbrot_threads A worker pool over typed queues: flat jobs in, flat rows out, reassembled in order; serial vs parallel timing on stderr.

Interop

Sample What it shows
24_call_c extern fn to libm and to a small C header (call_c.h): scalars, a slice, a struct through a reference, a string builder C appends to. Build with goose --include call_c.h ....

Serialization

Sample What it shows
25_serialize A word index saved and loaded as raw bytes: bytes_of views the element region without copying it, to_bytes builds the framed image, from_bytes verifies an untrusted one before it becomes a value. Fixed nodes with 4-byte links and a compact variable-size form of the same tree; tampered, truncated and extended files rejected.

Pools of slices

Sample What it shows
26_file_tree A directory tree: nodes in a reusable pool, passed around as references, each directory's entries one run of 4-byte in pool links in a reusable[] pool, grown in place or moved by realloc_slice; rm -r gives slots and runs back, mv relinks, and the pools' counts show the reuse.

The GPU

Sample What it shows
27_gfx_cube A window and a spinning, lit cube with the gfx module: GLSL shaders written in the program as """ strings and compiled in by embed_shader, vertex and index buffers from bytes_of, a uniform block as a packed struct, a depth buffer, the arrow keys; saves its last frame as gfx_cube.png. Needs a compiler built with the gfx package (GOOSE_BUILTIN_LIBS); the test runner draws it off screen.
28_physics_boxes Boxes fall into a walled arena containing two pyramids and a rotating arm. The physics module simulates them with Box3D on up to eight worker threads. Each frame retrieves all transforms in one call and writes them into an instance buffer. Each box is drawn as a unit cube with sunlight and shadows. Shaders are """ strings in the program; the two vertex shaders share their inputs through one global part. Space triggers an explosion, the mouse controls the view, and Up and Down adjust the rate at which boxes fall. Once the arena contains --boxes boxes, the oldest are returned to the top. Needs a compiler built with the gfx and physics packages (GOOSE_BUILTIN_LIBS); the test runner draws 120 frames off screen.

Windows and widgets

Sample What it shows
29_ui_todo A to-do list and a color mixer with the ui module: Nuklear's immediate-mode widgets drawn through gfx. Each frame lists the windows and widgets and reads back what the user did to them: a text field committed with Enter, buttons, check boxes, options, a menu bar, a tooltip, a progress bar, a color picker and properties; the check marks recolored through Nuklear's color table, text in Roboto from the Nuklear submodule, and the whole ui scaled up and down, its font baked again at each scale. Saves its last frame as ui_todo.png. Needs a compiler built with the gfx package (GOOSE_BUILTIN_LIBS); the test runner draws 30 frames off screen.

A small game

Sample What it shows
30_mini_minecraft A playable voxel world using only gfx: procedural hills, trees, caves, coal, water, pixel textures, sky and a bitmap font. Exposed-face chunk meshes with corner shading, captured mouse look, fixed-step walking and swimming, a grid ray for mining and placement, inventory, four crafting recipes, lamps, mining fragments, a day/night cycle, and validated atomic saves. Starts directly in an 80 × 40 × 80 world. No asset files or physics/UI dependencies. The test runner checks gameplay and renders 30 frames off screen.

Run goose samples/30_mini_minecraft.goose. WASD walks, Space jumps or swims, Shift runs, Ctrl sneaks slowly and stops at ledges, and the mouse or arrow keys look around. Jumping or releasing Ctrl lets you step off a ledge; sneaking does not change the player's height. Hold the left mouse button to mine; right-click or E places a block (hold to build repeatedly). Select a slot with 1–8 or the wheel, middle-click to select the aimed-at material, and press C to craft. Two wood blocks make eight planks; five planks make a wooden pick. Three mined stone and two planks upgrade it to a stone pick. One coal and one plank make four lamps. Hold Shift while clicking a recipe or pressing its number to craft all affordable batches, up to the inventory limit. Tools equip automatically and are only crafted once.

Crafting and pause release the cursor. Losing focus also pauses; click or press Escape to resume. A full day lasts ten minutes, with a moving sun, moon, stars, and peaceful nights that make lamps useful around a home.

H toggles help, Escape pauses, and F12 saves mini_minecraft.png. F5 explicitly saves mini_minecraft.sav in the working directory; F9 loads it. Starting a fresh world never overwrites a save. Saves include the time of day; older saves without a clock load in the morning. Close the window to quit. -- --seed N chooses terrain, -- --frames N renders a repeatable screenshot, and -- --test runs the gameplay checks without opening a window. The finite world deliberately omits mobs, hunger, damage, tool wear, and flowing water.

A small Doom-like game

Sample What it shows
31_mini_doom A playable Freedoom E1M1 using gfx and audio: checked little-endian WAD parsing, palette and patch decoding, a texture atlas, BSP-clipped floor polygons, textured walls, billboard sprites, sliding collision, stairs, falling, doors, lifts, pickups, combat, and one update/draw loop. Includes pistol, shotgun, chaingun and fists, four enemy types, imp fireballs, exploding barrels, damaging floors, secrets, the blue key and the exit. Uses the supplied data/freedoom1-e1m1.wad.

Run goose samples/31_mini_doom.goose from the repository root, or pass the source's path from any working directory. It starts directly in the level. Its default WAD path is data/freedoom1-e1m1.wad under resource_dir(): beside the entry source for JIT, or beside a compiled executable for AOT. When distributing the executable, include that data directory, or use --wad <path> to select an external WAD. The sample runner supplies --wad because it builds executables outside the sample's asset directory. The recursive BSP walk uses caller-owned growable scratch, restoring its length on return; clipping has no fixed polygon-corner limit. WASD walks, Shift runs, mouse or Left/Right turns, E or Space uses doors and switches, and left mouse or Ctrl fires. Select fists, pistol, shotgun, or chaingun with 1–4 (the latter two must be collected). Tab toggles the map; H toggles help. Escape pauses and releases the cursor; click or Escape resumes. Losing focus pauses. R restarts after death or completing the level. F12 saves mini_doom.png in the working directory.

The sample uses medium-difficulty things. Find the blue key and use the exit switch. Lifts lower when used or crossed, wait, and carry you back up. Some walls are secret doors. The automap shows the whole map and does not pause play. Blue lines mark locked doors; yellow lines mark triggers.

-- --frames 30 runs for thirty frames with a fixed timestep and saves a PNG. The sample runner uses this mode for its rendering smoke check. -- --silent disables playback; device failure also permits silent play. -- --wad PATH overrides the default WAD; relative paths use the working directory.

This is an independent, approximate game, not a compatible Doom engine. It omits music, saves, multiplayer, jumping, vertical aiming, monster pathfinding, directional monster art and the larger weapon set. Unimplemented weapon/ammo pickups provide bullets; a chainsaw pickup does the same. The WAD's own sprites, font and sounds keep the sample self-contained beyond that one asset file.