Realm of Heroes CRPG
Realm of Heroes: A Night Without Memory is a party-based, real-time-with-pause RPG in the style of the Infinity Engine games, written in GDScript for Godot 4.3 with D&D 5e SRD rules. It lives in games/crpg-realm/ and is an early-access vertical slice. It is also the test bed for the Infinity AI scenario engine, which plays any fighter, monster or NPC, and its tests can record each run to video.
On this page
A frame from a recorded test run in the village square. The activity log (bottom left) holds a numbered dialogue. The banner and the input stream at the top are test overlays.
Pages
| I want to | Read |
|---|---|
| Run the game or the tests | CRPG quick start |
| Look up a key or a HUD button | CRPG controls |
| Look up an autoload, data file, endpoint or variable | CRPG reference |
| Build a campaign in the visual editor | CRPG campaign editor tutorial |
| Change the Godot project: scenes, items, traps, spells | Extending the CRPG |
| Understand collision, pathfinding, fog of war and NPCs | CRPG world systems |
| Write or run tests, or use the Infinity AI engine | CRPG testing and Infinity AI |
The Godot project and the editor are separate programs. The editor (packages/crpg-editor, also listed as RobOS cRPG Editor in the app catalog) writes JSON-LD files into games/crpg-realm/, and the game plays them.
What is in the repository
| Part | Where | What it is |
|---|---|---|
| Game | games/crpg-realm/ | Godot 4.3 project, GL Compatibility renderer, 1920x1080 viewport. Main scene: CharacterSelect.tscn. |
| Cartridges | games/crpg-realm/cartridges/ | Six campaigns bundled as single JSON files, played by CartridgeWorld.tscn. |
| Hand-built scenes | games/crpg-realm/scenes/ | Homestead, VillageSquare, WhisperingForest, AncientCatacombs, GarrisonKeep and TacticalBattle, with hard-coded encounters. |
| Scenario engine | scripts/engine/ScenarioEngine.gd | Data-driven D&D 5e rules and the Infinity AI. Used by tests and the Scenario Arena, not yet by the hand-built scenes. |
| Editor | packages/crpg-editor/ | Electron app for campaigns, characters, items, enemies, spells, abilities and maps. |
| Bundler | packages/crpg-builder/ | crpg-cartridge.js compiles a campaign and its maps, characters and items into a cartridge. |
| Blockout maps | packages/robos-crpg-blockout/ | Python tool that renders grey-box maps and writes the 5-ft collision grid the scenario engine uses. |
| Tests | games/crpg-realm/tests/e2e/ | Gherkin features run by behave. |
Characters and monsters render as 3D miniature pawns (CharacterModel3D.gd) in a 160x160 viewport, with sockets for a weapon, shield and helmet. Heroes pick from 9 races and 12 classes.
The original campaign
The five hand-built scenes form the first campaign. Character Select starts a cartridge when one is selected; to play these scenes use ./debug.sh --scene Homestead (see the quick start).
graph LR
HS["Homestead"] -->|"front door, after looting the footlocker"| VS["VillageSquare"]
VS <--> WF["WhisperingForest"]
WF <--> AC["AncientCatacombs"]
AC -->|"secret passage (garrison-key)"| GK["GarrisonKeep"]
VS -->|"garrison gate (garrison-key)"| GK
GK -->|"Malakor defeated"| V["VictoryScreen"]
| Scene | What is in it |
|---|---|
Homestead.tscn | You wake in the manor and meet Elora. You must loot the footlocker before the front door lets you leave. |
VillageSquare.tscn | The hub. 11 buildings with collision, 12 townsfolk (including Blacksmith Brand, who gives the garrison key), a shop, ground items, and the locked Royal Garrison Gate. |
WhisperingForest.tscn | Dire wolves, Goblin Peddler Griknok, Hermit Varis. |
AncientCatacombs.tscn | Three placed traps, skeleton archers, the Spirit of Sir Justin, the Grand Sarcophagus (it holds a garrison key), and the secret passage to the keep. |
GarrisonKeep.tscn | The fight with Captain Malakor, then VictoryScreen.tscn. |
The door-by-door detail is on the scenes, doors and maps page.
How play works
Real time with pause. Space freezes the action; you can then queue moves with Shift-click, change the leader or formation, or pick a spell, and unpause. Keys and buttons are on the controls page.
The activity log at the bottom of the screen carries combat rolls, dialogue and journal updates. It has three heights (124, 240 and 420 px; Tab or L cycles them). Dialogue replies appear as numbered lines in the log, and you pick one with the number key or a click.
Combat, in the hand-built scenes, uses d20 attack rolls against AC with advantage and disadvantage, saving throws, and a threat table for enemy targeting. Combat, party and spells covers the formulas, the six formations and the spell code.
How it is tested
The tests treat the game as a black box. behave features drive the running game over its local HTTP API, and in human mode ffmpeg records each scenario from a virtual X display.
| Suite | Folder | Features | What it covers |
|---|---|---|---|
| Engine | features/engine/ | 13 | Rules, spells, AI directives, items, traps, movement, blockout maps, fuzzed battles. Can run headless with no video. |
| Normal | features/normal/ | 18 | One mechanic per feature in the real scenes: fog of war, shop, looting, traps, aggro, formations, pathfinding |
| Spells | features/spells/ | 24 | One feature per spell or fighter ability |
| Scenario adventures | features/scenarios/ | 4 | Stories loaded from a campaign file and played through the real scenes |
| Full playthroughs | features/full_playthroughs/ | 6 | Start-to-finish runs |
cd games/crpg-realm
python3 run_cucumber_tests.py --engine --backend
CRPG testing and Infinity AI explains the layers and how to write a scenario.
Interactive courses
Two quiz-style courses are published with these docs: the cRPG course and Game Builder Academy. They are generated from the knowledge graph (.robos/kgraphs/learning/package.jsonld) by a script, not written from these pages, so check them against the pages here.
Known limits
- Two rule systems. The hand-built scenes use hard-coded numbers in GDScript. For example, the Malakor fight uses 48 HP and AC 14 in
GarrisonKeep.gd, althoughmonsters.jsonsays 58 HP and AC 16. Initiative order, death saving throws and per-level spell slots exist only in the scenario engine. CRPG reference lists which data files each system reads. - Adding a spell to the hand-built scenes needs code. Each spell is a branch in
CombatManager.gd. A new entry inspells.jsonalone does nothing there. - Mods only add traps.
DataStoreV1.gdreadstraps_filefrom amod.jsonand nothing else. - The HTML test report cannot tell pass from fail. It marks a scenario PASSED when its video exists. Use the
behaveexit code. - Do not regenerate the game with
packages/crpg-builder. It would overwrite hand-edited data andproject.godot. See the reference. - Browser builds (
export_web.sh) have no control server, so the tests cannot run against them.