Skip to main content

Example games

The template ships eleven complete games in templates/crescent-game/examples/. Each is one self-contained index.tsx that default-exports a GameDefinition, so any of them can replace the game in src/game/index.tsx. Use them two ways: to see how an engine piece or module is used in a real game, and as the starting point for your own game of that kind.

The twelfth game is the starter, Sunset Sprint, in src/game/index.tsx: a racing module config.

At a glance​

ExampleKind of gameBuilt on2D or 3D
moon-blocksblock puzzle, endlesspuzzle module, block pack2D
moonrisemerge puzzle with levelspuzzle module, merge pack, drawn tiles2D
gem-cascadematch-three with levelspuzzle module, match pack in swap mode2D
flag-rush3 v 3 capture the flagshooter module3D
oath-of-ashvalestory-led town builder with sortieskingdom module3D
rooftop-hopparkour course over a voidcharacter and cameras3D
lantern-tagcollect lanterns, avoid guardsbots3D
pulse-arenafree-for-all against armed botscombat3D
tap-popone-tap arcade, 30 second rounds2D layer2D
sky-runnerside-scrolling platformer2D layer platformer kit2D
moon-chesschess against talking rivals or a friendturns2D

The five module examples are configs: change fields, not code. The six others write their own loop on the engine pieces, so everything (level, rules, camera, HUD) is in that one file.

How to run an example​

An example runs by becoming the game. From templates/crescent-game:

cp examples/lantern-tag/index.tsx src/game/index.tsx
npm run typecheck

Then start the game the way the Quickstart describes, for example in a browser with npm run web. To go back to the starter game, restore the file with git checkout src/game/index.tsx.

Run instructions: see Quickstart.

The relative require('../../assets/...') paths in the examples resolve the same from examples/<name>/ and from src/game/, so the copy needs no edits. Every example is checked by npm run typecheck, because the template's TypeScript config includes examples/.

All examples keep the same dev conventions: in development builds they show a hud-debug telemetry line and an AUTO button that plays the game by itself, every control has a testID, and the exit control calls onExit. Production builds hide the dev pieces.

Examples with a leaderboard or rooms work without a backend: scores stay on the device and rooms hold only you. To put them online, set GAME_BACKEND_URL and deploy the backend scaffold (backend overview); each leaderboard name an example uses must be in the backend's BOARDS.

Module examples​

moon-blocks​

Moon Blocks: the puzzle module's starter. The block pack, endless, on a night-sky palette. Drag pieces from the tray onto the 8 x 8 board; full rows and columns clear; the round ends when no piece fits.

  • Shows: the smallest real puzzle config: pack, mode, board, block.pieces, block.tray, theme colours and tileStyle.
  • Read first: examples/moon-blocks/index.tsx (30 lines), then Puzzle module.
  • Backend: the module's endless board and presence, already in the scaffold's BOARDS.

moonrise​

Moonrise: a merge puzzle in the night sky. Swipe to slide; two equal bodies become the next one, from a new moon through full moons, planets, a sun and a galaxy to the last step. Levels ask for the next body each time.

  • Shows: the merge pack in levels mode, theme.names naming every step, every tile drawn in code with theme.paintTile, a twinkling starfield with theme.paintBackground, and a font family picked with fonts.
  • Read first: examples/moonrise/index.tsx: the paintTile switch is the part to study for drawing tiles with the 2D layer's Draw2D.
  • Backend: the module's levels board.

gem-cascade​

Gem Cascade: a match-three. Drag a gem onto a neighbour to line up three or more; lines shatter, gems fall, and new lines clear on their own as cascades. Levels ask for a number of gems in a few moves.

  • Shows: the match pack with input: 'swap', levels, six gem cuts drawn with paintTile (one shape per colour, so colours also read by shape), draw.clip for facets, drifting sparkles in paintBackground, a custom hint.
  • Read first: examples/gem-cascade/index.tsx.

flag-rush​

Flag Rush: three against three capture the flag on the depot map, first to three captures. Bots fill every empty seat; friends who join take a bot's place in the same match.

  • Shows: a full shooter config: mode: 'ctf', rules, map, player loadout and camera, team names and colours, seats, bot difficulty and weapons, pickups.
  • Read first: examples/flag-rush/index.tsx (27 lines), then Shooter module. Change mode for team deathmatch, gun game, king of the hill or free-for-all.
  • Backend: rooms from the scaffold as shipped; add flag-rush-kills to BOARDS for the kills leaderboard.

oath-of-ashvale​

Oath of Ashvale: a storybook realm with a queen, a marshal and a farmer. Two chapters of dialogue with cut-out portraits, a knight-or-ranger choice, joystick sorties against bandit camps in the fog, Victory rewards, wheat and carrots, a watchtower, a barracks and land to clear.

  • Shows: every table of the kingdom config filled in: resources with sheet icons, eight buildings with generated .glb models, crops, units and classes on rigged character models with shared animation files, held weapons, tint per team, two missions, a town with prebuilt buildings, plots, debris, paths, a water row and walking villagers, a story of two chapters (16 and 13 beats), a full sounds set and the kingdom-power board.
  • Read first: examples/oath-of-ashvale/index.tsx: the story block shows the beat order that works (title, say, class choice, sortie, objectives, reward, unlock).
  • Assets: the characters and weapons are the KayKit Adventurers pack (by Kay Lousberg, CC0) in assets/models/kaykit/; the buildings in assets/models/ashvale/; the portrait and icon sheet in assets/sprites/oath-of-ashvale/sheet.png; music and effects in assets/audio/ashvale/ and assets/sfx/ashvale/.
  • Backend: add kingdom-power to BOARDS for the leaderboard; the save syncs through PlayerSaves.

Engine-piece examples​

rooftop-hop​

Rooftop Hop: a parkour course over a void. Move with the left stick, drag the right half to look, JUMP across gaps. Rings are checkpoints, the green pad is the goal, falling returns you to the last checkpoint. The camera button cycles third person, first person, top-down and side view.

  • Shows: the character controller (createCharacterState, stepCharacter, resolveCharacterParams), the four camera rigs (resolveCameraRig, CharacterCamera, nextCameraMode), CharacterControls, a level from resolveLevel drawn with LevelMeshes, a moving platform on a path (createPath, MovingPlatform), checkpoints and the goal as zones (useZones), game feel (GameFeel, juice, stretch), a waypoint autopilot (createWalker, waypointCommand) and a fastest-time leaderboard.
  • Read first: examples/rooftop-hop/index.tsx, then Character and cameras.
  • Backend: board rooftop-hop, lowest first.

lantern-tag​

Lantern Tag: collect five lanterns in an arena while three guards patrol. They hear you sprint and land, see you when you cross their view, chase you and lose you again. Three lives.

  • Shows: bots (BotSquad, BotMeshes, createRoster, patrol routes, hearing and sight, backOff), pathfinding on a grid (gridMap, findPath, nearestWalkable), a hut and ramps laid out from a text map, a slow title orbit (CameraDolly on a closed path), typed signals between systems (createSignals, useSignal), positional sound (useAudioMixer, AudioListener), particles and a leaderboard.
  • Read first: examples/lantern-tag/index.tsx, then Bots and Audio.
  • Backend: board lantern-tag, lowest first.

pulse-arena​

Pulse Arena: free-for-all in a neon arena against three armed bots, first to ten eliminations. Hold FIRE to shoot (the same thumb aims), SWAP cycles rifle, shotgun and rockets, aim assist pulls the crosshair onto enemies, everyone respawns.

  • Shows: the combat kit with no module around it: CombatWorld, weapons (spreadOf, isReloading), bot gunners (createGunner, driveBotWeapon), CombatEffects, and the combat HUD (Crosshair, HitMarker, HealthBar, AmmoCounter, DamageNumbers, Killfeed).
  • Read first: examples/pulse-arena/index.tsx, then Combat. Start here for a shooter rule the shooter module has no mode for (waves, bomb defusal).
  • Backend: board pulse-arena, lowest first.

tap-pop​

Tap Pop: dots drift around the screen; tap one to pop it before the 30-second timer runs out, with a local best.

  • Shows: the 2D layer end to end: GameCanvas2D, stage units that fit any phone, taps mapped to the stage (PointerEvent), the fixed-step loop, tweens (createTweens), particles (createParticles2D), text, haptics, a one-shot sound (useOneShots), a seeded random (makeRng), a font family from @/engine/ui/fonts, and the HUD chrome (TopBar, Banner, FinishCard, RoundButton). It also has a dev performance scene (64 tiles and 200 particles).
  • Read first: examples/tap-pop/index.tsx, then 2D layer. Start here for any flat game: one-tap arcade, cards, word games.
  • Backend: board tap-pop, highest first.

sky-runner​

Sky Runner: a side-scrolling run across rooftops drawn from a tile map: coins, spikes that send you back, one-way ledges, a flag at the end.

  • Shows: the 2D platformer kit: a tile map from strings (createTileMap, drawTileMap), the platformer controller (createPlatformer, stepPlatformer, platformerInput: coyote time, jump buffer, short hops, wall slides and wall jumps), triggers (Triggers2D), a follow camera (createCamera2D, cameraView), two parallax layers (drawParallax), sprite sheets drawn in pixel-art mode (createSheet, createSpriteAnimator, pixelZoom) with vector shapes as the fallback, and an autopilot built on raycast2D.
  • Read first: examples/sky-runner/index.tsx: the MAP strings and the autopilot function.
  • Assets: assets/sprites/sky-runner/runner.png and roof-tiles.png.

moon-chess​

Moon Chess: chess on the 2D layer against three computer rivals at easy, medium and hard who talk, against a friend online, or pass-and-play on one phone. A drawn board and pieces, tap or drag to move, slides, a promotion picker, take-backs.

  • Shows: the turns kit: chessRules and the chess helpers (createChess, playMove, legalMovesFrom, san, toFen, undoMove), the search (searchMoves, pickMove), the computer opponent (useOpponent), online turns (useTurnRoom: seats, resign, rematch with colours swapped), room codes and launch links (makeRoomCode, useLaunchRoomId, roomInviteUrl), presence and a leaderboard.
  • Read first: examples/moon-chess/index.tsx (the largest example, about 1300 lines), then Turns. For another board game, keep its screens and flow and swap chessRules for your own TurnRules.
  • Backend: the rivals' lines come from the backend's model (POST /ai/turn, see AI opponent); offline the search still plays, silently. Online games need rooms.

Picking a starting point​

You wantCopy
a block, merge, match or sort puzzlemoon-blocks, moonrise or gem-cascade, then change the config
a shooter with standard modesflag-rush
a town builder with a storyoath-of-ashvale
a 3D platformer or obstacle courserooftop-hop
tag, stealth, chase, enemies that patrollantern-tag
a shooter with your own rulespulse-arena
any flat arcade, card or word gametap-pop
a 2D platformer or runnersky-runner
a board gamemoon-chess
a car racethe starter game in src/game/index.tsx