Open Source

scumm-game

A tiny SCUMM-style point-and-click adventure engine, written in C with raylib. Multiple self-contained games with a built-in game picker, click-to-walk pathfinding, inventory, and multi-actor follow AI.

scumm-game screenshot — Guybrush on the dock

At a Glance

Language
C (~900 LOC)
Renderer
raylib 5.x (native + WebAssembly)
Pathfinding
Dijkstra over walkbox visibility graph
Animation
8fps walk cycles, 4 directions
Interaction
Look at / Use / Pick up / Give verb bar
Sprites
250-frame Guybrush sprite sheet

Features

Click-to-Walk Actor

Guybrush paths around the dock using Dijkstra over the walkbox visibility graph — routes around concave notches instead of shortcutting through them.

Animated Sprites

8fps walk cycles in four directions, perspective-scaled with distance, rendered with nearest-neighbour filtering. Faces the direction of travel and idles on frame 0 when stopped.

Verb Bar

Classic SCUMM interaction model: Look at, Use, Pick up, Give. Click a verb, click an object, actor walks over and speaks. Give-to-tip interactions with clickable hotspots.

Walk-Behind Foregrounds

Hand-authored polygons re-sample the background and draw over the actor so he can pass behind things. Triangulated via ear-clipping — any simple polygon works.

Multi-Walkbox Support

Scenes can define multiple walkable regions. Each walkbox is an independent polygon — Dijkstra pathfinding works across all of them, routing through shared edges.

Hole Polygons

Cut non-walkable holes inside walkboxes. Hole polygons subtract from the parent region so the actor paths around obstacles like tables, pillars, or barrels.

Scale Lines

Define perspective scaling with a scale line — the actor grows and shrinks based on vertical position in the scene, giving depth to flat 2D backgrounds.

Live Editors

Walkboxes, holes, foreground z-planes, and scale lines are all drawn in-game with the mouse — no external tools. Vertices snap, auto-order by angle, and save to plain text.

Inventory System

Pick up items and carry them in an inventory. Use the Give verb to hand items to other actors — the engine handles walk-to, face, and dialogue automatically.

Multi-Actor Follow AI

Multiple actors on screen with follow AI — secondary characters trail the player actor, pathfinding around walkbox geometry with separation spacing.

Clickable Hotspots

Define interactive regions on the background. Hotspots respond to verbs — Look, Use, Pick up, Give — with per-hotspot dialogue and actions.

Game Picker

Press [G] to open the in-game game-picker menu. Multiple self-contained games are organized as independent data directories, switchable at runtime.

Sprite Browser

Flip through raw sprite frames and tag them into named animations. Built directly into the binary — press B to enter.

Editor Keys

KeyModeAction
EWalkbox / FG editorClick to add verts, drag to move, click edge to insert
WIn editorEdit the blue walkable polygon
FIn editorEdit / cycle magenta walk-behind polygons
NIn editorAdd another foreground polygon
OIn editorSort verts by angle (unwrap self-intersections)
RIn editorReset active polygon
SIn editorSave to walkbox.txt / fg.txt
HIn editorEdit hole polygons (cut non-walkable areas inside walkboxes)
KIn editorEdit scale line (perspective depth scaling)
DDebug overlayShow walkbox + foreground outlines
GGame pickerSwitch between self-contained games at runtime
BSprite browserFlip frames, tag animations, save to sprites.txt

File Layout

src/main.c                 Single-file engine
Makefile                   macOS / raylib 5.x via homebrew
run.sh                     Compile + run
build_web.sh               Emscripten WebAssembly build
docs/                      Web build output (index.html/js/wasm/data)
assets/bg-dock.png         Backdrop (per-game data dirs)
walkbox.txt                Authored walkable polygon
fg.txt                     Authored walk-behind polygons
sprites.txt                Raw-sheet → named-animation mapping
guybrush_sprites_v3/       250-frame raw sheet
sprites/guybrush/<anim>/   Exported, ready-to-render frames
export_sprites.sh          Bakes sprites.txt → sprites/guybrush/

Build & Run

# Native (macOS)
brew install raylib   # one-time
./run.sh              # compile and launch

# WebAssembly (requires Emscripten SDK + raylib source)
./build_web.sh        # outputs to docs/

Not a reimplementation of the SCUMM bytecode VM — no .lfl / .he loading, no interpreter. Just the engine surface that makes a SCUMM-style game feel like a SCUMM game.