McRogueFace/games/unwritten/core/assets.py
John McCardle 80908f771c UNWRITTEN: complete short-form RPG at games/unwritten/
A 30-45 minute turn-based RPG built overnight as an engine showcase:
six recruitable characters (party of three), four recurring NPCs,
choice-driven dialogue with visible-but-locked skill checks, shops,
loot, levels, two bosses with in-battle Talk options, the reverted
grey-town beat, and an epilogue assembled from the player's actual
choices. 33 dialogue scenes / 171 nodes. Terrain is ColorLayers only;
kenney_tinydungeon supplies characters, items, and props.

Creative direction, story, dialogue, maps, and systems design by
Fable; implementation by four Opus subagents (framework, battle,
overworld, integration). Verified by tests/playthrough.py: a scripted
headless run of all three acts, 20/20 beats passing, plus per-system
unit tests (script integrity, UI kit, 225-battle balance sim,
overworld).

Run: cd build && ./mcrogueface --exec ../games/unwritten/main.py

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vxWJ6GY384SmZiMVXgrF4
2026-07-03 10:11:12 -04:00

38 lines
1.1 KiB
Python

"""UNWRITTEN - shared assets. Owner: Agent A.
The ONE Texture for the whole game and the speaker->portrait sprite map.
Constructed once here; import TEX everywhere else (never re-create the Texture).
Asset path is relative to the build/ working directory (see ARCHITECTURE section 0).
"""
import mcrfpy
TEX = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16)
# Speaker id -> sprite index (BIBLE sections 2/3/4). NARRATOR has no portrait.
PORTRAITS = {
"PIP": 85,
"BRAMBLE": 96,
"MOTH": 84,
"VERA": 111,
"CANTOR": 109,
"NYX": 121,
"QUILL": 100,
"GRISELDA": 88,
"ODD": 87,
"BELL": 110,
"GATEKEEPER": 20,
"CUSTODIAN": 41,
"NARRATOR": None,
}
def portrait_index(speaker):
"""Return the sprite index for a speaker id, or None for NARRATOR.
Fail early: an unknown speaker id is a content/authoring error, not a
thing to paper over with a placeholder sprite.
"""
if speaker not in PORTRAITS:
raise KeyError(
"unknown speaker id %r - add it to core.assets.PORTRAITS" % (speaker,))
return PORTRAITS[speaker]