Recruited partners (Pippo, Tonia) were unfieldable: Game.battle_party() returns [gino, active_partner] and nothing ever called set_active_partner, so Nonna auto-locked as the only partner ever fought — their movesets and the combat paths those moves use were dead code in shipped play. And Diva Tonia had no cost-0 move, soft-locking at low Gusto vs a boss (Fuga disabled, no Gusto items: no legal action). - Content.gd: add Vocalizzo (one-enemy, power 2, cost 0, tap) to Tonia's kit ahead of acuto/aria — her reliable free poke; removes the soft-lock. - Battle.gd: add the Cambia command to Gino's top menu (gino-only; disabled when there is no alive benched partner). It opens a partner chooser and swaps the pick into the active slot in place via _do_switch. Party HP is authoritative in Game.hp, so the refielded Battler's setup() re-reads its exact HP — wounds persist with no sync code. Party round converted to index iteration so the in-place swap is observed the same round. - Playthrough.gd: flip the Tonia 0-Gusto-vs-boss case softlock->acts, drop the now-dead softlock arm, refresh the coverage comment, and add a dedicated _cambia_exercise() asserting id swap + active_partner update + HP persistence (pre-wounded Tonia re-enters at 5/13). Spec marked Implemented; SESSION_NOTES refreshed (prior archived). Verified headless: Playthrough EXIT=0 (0 SCRIPT ERROR, clean playthrough, both new check lines), test_runner 24/24, Smoke all screens OK. |
||
|---|---|---|
| assets/art | ||
| docs | ||
| src | ||
| test | ||
| .gitignore | ||
| icon.svg | ||
| icon.svg.import | ||
| project.godot | ||
| README.md | ||
Cartastrofe
Un GdR di carta — a paper-thin Italian RPG.
A complete, roughly one-hour turn-based adventure built in Godot 4.6 in the paper-craft RPG tradition: timed action commands, swappable partners, and a flat cut-out world. The land of Buonappetito has had its Five Sacred Flavours stolen by a vain aristocrat, and a young pizzaiolo named Gino sets out — rolling pin in hand, Nonna at his side — to win them back.
Originality. This is an original work and an homage to a genre — the mechanics and the paper-cut-out look — not to any specific game. Every character, name, location, item, line of dialogue, and piece of art is original to this project. There are no third-party characters, assets, music, or story. All artwork is hand-authored SVG. Real ingredient names (salt, oil, basil, tomato, parmesan) are, of course, just ingredients.
Running it
Requires Godot 4.6+ (no extra dependencies, no third-party assets).
# from the project root
godot --path . # opens the editor
godot --path . res://src/Main.tscn # runs the game directly
The default window is 1280×720 (canvas_items stretch, keep aspect), so it
scales cleanly to any size.
Controls
| Action | Keys |
|---|---|
| Move | WASD or arrow keys |
| Interact / confirm / advance text | E, Enter, or Space |
| Cancel / back | Esc or Q |
In battle, the same interact key drives every action command — tap it in the green sweet-spot for Perfetto! damage, hammer it during a mash window, and tap it just before an enemy hits to Parata! (guard).
The arc
Six segments, each a stereotype-flavoured area with a few fights and a boss, pacing to roughly an hour. Between chapters you return to the hub village of Borgo Saporito, which visibly regains its colour as each flavour comes home.
| # | Area | Boss | Reward |
|---|---|---|---|
| 0 | Borgo Saporito (hub/tutorial) | Piccioni | Nonna Assunta joins |
| 1 | Il Mercato | Donna Vespa | 🧂 Sale + Pippo joins |
| 2 | Le Colline | Il Cinghiale d'Oro | 🫒 Olio |
| 3 | Il Chiostro | Fra' Tortellino | 🌿 Basilico + Tonia joins |
| 4 | La Fattoria | 'O Capitano | 🍅 Pomodoro |
| 5 | Castello del Conte | Il Conte Parmigiano | 🧀 Parmigiano → finale |
The tone is affectionate, Asterix-style cultural comedy: everyone is ridiculous,
everyone is lovable, and lunch is sacred. See docs/DESIGN.md
for the full design document — premise, cast, systems, and architecture.
How it's built
Data-driven so the engine is written once and the ~1 hour of content is
authored as plain data tables. Scenes are constructed procedurally in code
(Main.tscn is the only hand-authored scene); every screen is a script that
builds its own node tree in _ready() and reads/writes the single Game
autoload.
src/
Main.gd / Main.tscn boot → Game → Title
autoload/Game.gd run state: party, HP, Gusto, coins, inventory,
flavours, flags, level, screen flow, input map
data/ pure static data + math (headless-testable)
Combat.gd damage / guard / level-up math — no nodes
Database.gd actors, moves, items, flavours
Content.gd item/actor lookups
Story.gd the six chapters: areas, NPCs, enemies, bosses
actors/PaperActor.gd the paper cut-out visual (SVG sprite + shadow + wobble)
overworld/ Overworld, Hud, DialogueBox
battle/ Battle (state machine), Battler, ActionCommand, BattleMenu
ui/ Title, GameOver, Cutscene, Shop, UiKit (shared styling)
assets/art/ 19 hand-authored SVGs (6 heroes/NPCs, 7 enemies, 6 bosses)
Key boundaries: Combat is pure math (knows nothing about nodes, fully unit testable); Story/Database/Content are the single source of truth for content (adding a chapter is a data edit, not an engine edit); PaperActor is the only place that knows how a character is drawn.
Testing
Three tiers, all runnable headless except the last:
# 1. Logic: 24 assertions on combat math + content integrity
godot --headless --script res://test/test_runner.gd
# 2. Smoke: full-compile + construct every screen with real state & textures
godot --headless res://test/Smoke.tscn
# 3. Visual QA (needs a display): render composed screens to PNGs
godot --path . res://test/Shoot.tscn # title / game-over / overworld / battle / boss
godot --path . res://test/Gallery.tscn # every art file in a grid
The smoke test exists because Godot's --import only shallow-parses scripts;
loading a scene full-compiles method bodies and loads autoloads, which is what
actually catches runtime errors.
Status
v0.1 — the complete one-hour arc, playable end to end. Engine plus all six segments authored as data, three partners, five flavours, win/lose/finale. Post-1.0 ideas (badges, audio, save slots, more enemy variety) are noted in the design doc's scope ladder.