Warren

A maze game for the Scareathon arcade, after The Maze Runner and Labyrinth. You and up to three friends wake in a wide grassy clearing walled in by a maze that was not built for people: grey stone walls 34 m high, damp and mossy, ivy hanging from them. Find the way out. The maze goes round the clearing in rings, each walled off from the next but for one gate; a pale light stands up past the gate out of the last ring.

This is the start: the clearing, the first ring, rooms for playing together, and a maze made fresh each round. Apophis, packs of mummies and a Griever hunt the passages, and other boys, the runners, run them; the walls do not move, and there is no night. Every player is Inside’s boy: no face, a plain shirt (its colour by seat, the first red) and dark trousers.

What the game is meant to be (pillars, art direction, the maze’s rules, enemies, playing together) is in DESIGN.md; this file is how it is built and run.

Godot 4.7, GL Compatibility, landscape first (it also fills a portrait window). Web build in build/, served at https://sclondon.github.io/Warren/build/.

Playing

Laying out mazes by hand

Open res://maze_editor.tscn. Its root is a MazeLayout: set Maze Seed and Rings in the Inspector and press Generate. The maze is laid out as pieces (MazePiece) in folders: Walls, Piers, Terraces, Ivy, Vines, Bridges, Trees and the Beacon, each shown as it will be. Move, turn, resize (a box’s Size, or scale it), copy or delete any of them; a bridge’s far end is its child End. Save the scene as res://mazes/<name>.tscn and rounds play it: layouts in res://mazes/ are played in name order (round 1 the first), round and round; with none there, every maze is generated. Playable off leaves one out. Game Light off shows it in the editor’s plain light.

The rules for generated mazes are set here too: every generated round is made by maze_editor.tscn’s Clearing Style (with the clearing’s own wall), Square Sections (a MazeStyle each, from the clearing out), Desert (DesertStyle: dunes, the diagonal walls, its far wall) and Round Sections (a RoundStyle each, showing only what a round section uses), from the round’s own seed (Mazes.rules). A section’s border wall is the one round its outside. The maze is 7 rings: 3 square sections, the desert (a ring of its own) and 3 round ones; Rings counts them the same way. Change a section’s style here, save, and the next round played uses it; the pieces laid out in this scene only count once saved into res://mazes/.

Walls count where they stand: which lines between cells have a wall is read from the wall and pier pieces when the maze is played, so taking one away opens the way there (for the players, the things that hunt them and the way out), and one put down on a line (every 14 m, half a cell off the middle) closes it. The rings, gates and clearing come from the seed. Generate again replaces everything in the layout.

To find out what a setting does, turn on Live Preview: the maze is shown as the game builds it from the rules, and built again a moment after any setting changes (about 3 s for the whole maze; nothing of it is saved, and the pieces are hidden meanwhile). Clear the pieces to keep the scene light; Generate only when you want pieces to move by hand. Hover a setting for what it does. In the editor ivy is drawn flat green (IvyClimb.plain): growing every patch leaf by leaf was most of what Generate cost. tests/preview_check.tscn opened in the editor ("$G" --headless --path . --editor tests/preview_check.tscn --quit-after 600) builds the preview and prints its time; tools/generate_times.gd times the steps.

How it works

Commands

Godot is C:/Program Files (x86)/Steam/steamapps/common/Godot Engine/godot.windows.opt.tools.64.exe ($G below).

"$G" --headless --path . --import                         # after adding a class_name script or a model
"$G" --headless --path . -s res://tests/maze_test.gd      # the maze plan
"$G" --headless --path . -s res://tests/smoke_test.gd     # alone: walk, walls, out, next maze, touch
"$G" --headless --path . -s res://tests/climb_test.gd     # ivy onto a terrace, a vine, a rope bridge
"$G" --headless --path . -s res://tests/strand_test.gd    # a strung vine: walked as a tightrope, cut into two vines
"$G" --headless --path . -s res://tests/hunt_test.gd      # enemies in a round; caught, back to the clearing
"$G" --headless --audio-driver Dummy --path . -s res://tests/runner_test.gd   # runners: a route, ivy, drawing a hunter, caught, leading to a gate, a puppet
"$G" --path . --resolution 1280x720 --audio-driver Dummy -s res://tools/runner_shots.gd -- <folder>   # pictures of runners
"$G" --headless --audio-driver Dummy --path . -s res://tests/loot_test.gd     # what lies about and the camps: placed, taken, slots, torch, spear, hook, ladder, map, the room's news
"$G" --path . --resolution 1280x720 --audio-driver Dummy -s res://tools/loot_shots.gd -- <folder> [1|1c|2|3|4|5|6|7|8]   # pictures of them
"/c/Program Files/Blender Foundation/Blender 4.3/blender.exe" --background --python props/tools/build_props.py [-- <folder> [names]]   # their models (and pictures)
"$G" --headless --path . -s res://tests/layout_test.gd    # a layout changed by hand, saved, loaded and played
"$G" --editor --path . res://tests/editor_check.tscn       # (after layout_test) what the editor shows, saved to user://editor_view.png
"$G" --headless --path . -s res://tests/enemy_test.gd     # Apophis and the mummies on their own
"$G" --headless --path . -s res://tests/griever_test.gd   # the Griever on its own
# each newer kind on its own (always with --audio-driver Dummy: some make sounds)
for t in ghoul centipede spider abomination flesh_mound slime_wall bats baboon dog alien beetles fish_person angel frog frog_swarm harpy boar chicken gargoyle deer wildlife imp imp_swarm colossus coyote skinwalker tripod crow; do
  "$G" --headless --audio-driver Dummy --path . -s res://tests/${t}_test.gd; done
# pictures of each: tools/<kind>_shots.gd (windowed, 1280x720)
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/frog_shots.gd -- <folder> [toad|swarm|maze|all]   # the frogs
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/coyote_shots.gd -- <folder> [studio|strips|maze|all]   # coyotes: views, trot/gallop strips, a pack in a hall
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/skinwalker_shots.gd -- <folder> [studio|strips|maze|all]   # the skinwalker
"$G" --headless --path . -s res://tests/dev_test.gd -- --dev   # the dev tools (and the clearing wall's height)
"$G" --path . --resolution 1280x720 -s res://tools/climb_shots.gd -- <folder>   # pictures of the ways up
"$G" --headless --path . -s res://tools/bake_preview.gd -- [seed] [rings]   # a maze to look round in the editor: preview/maze_preview.scn
"$G" --path . --resolution 900x900 -s res://tools/head_sheet.gd -- <file.png>    # every head shape
"$G" --path . --resolution 900x900 -s res://tools/legs_sheet.gd -- <file.png>    # every trouser cut and boot
node tools/dev_relay.mjs <scareathon-v3/server> 3111      # local rooms (needs server/node_modules)
sh tools/coop_test.sh                                     # two copies in one room against it
"$G" --path . --resolution 1280x720 -s res://tools/shots.gd -- <folder>   # pictures to look at
"$G" --path . --resolution 1280x720 -s res://tools/clearing_shots.gd -- <folder> [seed]   # the clearing: hills, woods
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/deer_shots.gd -- <folder> [studio|strips|maze|clearing|all]   # deer and elk, gallop strips, the herd, wildlife
"$G" --headless --audio-driver Dummy --path . -s res://tests/marsh_test.gd   # the marsh: water, sedges in it, the lane in
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/crow_shots.gd -- <folder> [studio|beat|maze|clearing]   # crows, ravens, blue jays, the wingbeat
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/marsh_shots.gd -- <folder> [seed]   # the marsh, him in it
"$G" --headless --audio-driver Dummy --path . -s res://tests/insects_test.gd   # moths, flies, dragonflies: counts, culling, a light, carrion, caught, perching, cost
"$G" --path . --audio-driver Dummy --resolution 1280x720 -s res://tools/insects_shots.gd -- <folder> [studio|maze|all]   # the insects up close, and in a round
"$G" --headless --path . --export-release "Web" build/index.html

Flags (command line -- --name=value or the page’s ?name=value): server=<url> for another rooms server. dev turns on the dev tools (on anyway when the game is run from the Godot editor): everyone starts in front of a gate of the clearing (start=middle for the middle), and a DEV button under the clock opens god mode: put mummies (of a chosen kind, alone or in a pack), the snake or a Griever into the maze ahead, a runner or three (+ RUNNER,

Not done yet

Rings past the first; enemies knowing about the ways up (terraces, bridges); ears; walls that move, doors that shut at night, a map, sound and music, names, and reconnecting mid-round past the server’s 90 seconds.