Wanted to see what I could do with a one-shot based on the old roguelike code which is tens of thousands of lines…
full one-shot prompt
You are an experienced browser-game developer and classic roguelike designer. Build WORDROT: The Last Page, a complete, single-player, turn-based dungeon roguelike contained entirely in one index.php file.
Tagline: Kill monsters. Steal their letters. Spell your way out.
The game should feel like a classic overhead roguelike with a mischievous tabletop personality: dangerous corridors, readable combat, strange equipment, a talking sword, and a dungeon that knows someone is trying to escape.
Its defining mechanic is literal spellcraft:
Monsters carry letters. Defeating them gives you those letters. Assemble letters into words to learn spells.
A second, closely related resource decision supports that mechanic:
Dice are money—but you can also sacrifice them to restore mana. Every emergency refill spends part of your shopping budget.
Build a complete, modest game around those ideas. Do not turn this into a sprawling role-playing framework.
1. One-file requirements
Deliver all application HTML, custom CSS, JavaScript, content definitions, and any necessary PHP inside one index.php.
Use Phaser 3 for the dungeon and effects, and Bootstrap 5 for the surrounding interface. Load explicitly version-pinned CDN distributions compatible with the APIs you use. Do not use floating latest URLs.
Use vanilla JavaScript. No database, accounts, npm, Composer, bundler, jQuery, external game-data endpoints, or additional local files.
Generate all visual assets within the file using canvas textures, Phaser graphics, text glyphs, inline SVG, or CSS. Use system fonts. Do not reference nonexistent image, sound, or sprite-sheet files.
The Phaser and Bootstrap distributions should be the only required external resources. Once those libraries load, gameplay must not make network requests.
Store the active run and local records in localStorage. PHP may simply serve the page.
“One page” means a single browser page with in-page panels and dialogs—not that every inventory entry must fit inside one viewport.
2. Premise and run structure
The player awakens inside an unfinished fantasy novel whose pages are rotting into a dungeon. Someone called the Redactor has been deleting the characters’ memories and rewriting every escape attempt.
The player remembers only two things: a missing dungeon cat named Tabby, and the fact that their sword is named Fred.
Fred remembers considerably more, but insists that “dramatic timing” prevents him from explaining everything immediately.
Build a five-floor run. On floors one through four, a living Dungeon Core must be destroyed to reveal the stairs. On floor five, the player confronts the Redactor and breaks the final Core.
The main loop is:
Explore → Fight → Collect letters and dice → Learn useful spells → Improve equipment → Destroy the Core → Descend.
Winning ends the run with escape and a short conclusion involving Fred and Tabby. Dying ends the run permanently.
Preserve local high scores and discovered lore between runs, but do not provide permanent statistical upgrades. A fresh run starts on equal mechanical footing.
3. Literal spellcraft
Maintain a letter pouch as a count map, such as:
{ A: 2, B: 1, L: 3, Z: 1 }
Normalize letters to uppercase. Do not introduce uppercase/lowercase rarity tiers in this version.
Each ordinary monster has a defined letter reward. Display that letter on its visible dungeon token or inspection panel. Different letter variants may share an AI behavior.
When an eligible monster dies, grant its letter exactly once. The letter is not randomly changed after the kill.
Letters can also appear in finite bookshelf caches, treasure, and merchant stock. Ensure useful letters are distributed deliberately rather than relying entirely on uniform alphabet randomness.
Learning a spell consumes the letters in its name once. Casting the learned spell consumes mana, not more letters.
For example, learning BLINK consumes B, L, I, N, and K. Learning FIREBALL consumes two Ls.
All recipes should be visible from the beginning. Locked recipes show exactly which letters are missing. No external dictionary, natural-language interpretation, arbitrary word recognition, or guessing game.
Learning a spell consumes one turn. Opening the spellbook, inspecting a recipe, or canceling does not.
Validate the complete recipe before changing inventory. Subtract all required counts atomically. Reject duplicate learning without consuming anything.
Make this mechanic visible almost immediately: place a guaranteed Z+A+P letter bundle in the safe entrance area, and guide the player through learning and casting their first spell.
4. A small, complete spellbook
Implement these eight spells. Treat the numbers as initial balancing values; adjust them coherently if necessary.
| Spell |
Mana |
Effect |
| ZAP |
3 |
Attack a visible enemy within five tiles for modest lightning damage. |
| HEAL |
4 |
Restore a moderate amount of health, capped at maximum health. |
| BLINK |
4 |
Teleport to a visible, unoccupied, legal floor tile within five tiles. |
| PUSH |
3 |
Damage a visible enemy within four tiles and push it up to two tiles away. |
| GUARD |
3 |
Reduce the next two incoming hits; unused protection expires after three subsequent turns. |
| FIREBALL |
6 |
Damage a target tile and its reachable cardinal neighbors. Clearly preview possible self-damage. |
| MAP |
4 |
Reveal the current floor’s terrain without revealing enemies, loot, or unopened-container contents. |
| SEAL |
5 |
Temporarily suspend a visible Dungeon Core’s spawning for three subsequent enemy phases. |
Use a shared spell-definition catalog containing recipe, cost, range, targeting rules, description, and effect identifier.
The preview, displayed cost, and actual effect must use the same definitions and validators.
Walls and closed doors block direct attacks. FIREBALL must not pass damage through a wall simply because a tile is geographically nearby.
BLINK cannot land inside walls, actors, closed doors, or outside the map. PUSH cannot move an enemy through a wall or blocked diagonal. Cores are immovable.
SEAL pauses spawning; it does not destroy a Core or satisfy the floor objective.
An invalid target or canceled selection must not consume mana, letters, items, or a turn. Do not deduct resources when the player merely clicks a spell button.
5. Dice: money or mana
Use three wallet denominations: d4 coins, d6 coins, and d8 coins.
A wallet contains counts of physical dice, not accumulated roll totals. For example, “3 × d6 coins” means three spendable six-sided dice.
Shops charge explicit quantities of particular denominations. Avoid ambiguous price labels that could be mistaken for a random roll.
At any time the player could use a consumable, they may Burn a Die. Choose one denomination, consume exactly one die, roll it once, and restore that much mana up to the maximum.
Show the possible restoration range before confirmation. Show the rolled result and actual mana restored afterward.
Burning a die consumes one turn. Reject the action at full mana without spending the die.
The same wallet backs shopping and mana restoration. Do not maintain separate “spell dice” and “money dice.”
Example decision: the player has two d6 coins and needs both for better armor, but burning one could provide enough mana to BLINK away from a dangerous encounter.
Dice supplies must be finite. No rewards for repeatedly searching an exhausted shelf, reopening a shop, revisiting a room, or reloading the page.
6. Turn-based movement and combat
The simulation advances only after a valid, committed player action.
Support eight-direction movement using the numeric keypad, cardinal movement using arrow keys or WASD, and clickable controls. Provide a Wait action.
Prevent diagonal corner-cutting. Use the same legal-step rules for the player, enemies, and pathfinding.
Bumping into a hostile performs a melee attack. Bumping into a closed door opens it but does not also move through it. Bumping into solid stone does not consume a turn.
Moving, attacking, waiting, opening a door, searching a container, learning or casting a spell, using an item, burning a die, and changing equipment each consume one turn.
Looking, browsing inventory, reading dialogue, viewing help, and canceling targeting are free.
Use this consistent resolution order:
Validate action → Apply the player action and its costs → Resolve immediate deaths → Resolve surviving enemies → Resolve ongoing effects → Update visibility and objectives → Save.
Stop the sequence immediately if the player dies. An enemy killed by the player action must not retaliate later in that turn.
Newly created temporary effects must not expire immediately. Track their application turn and expiration explicitly.
Use small, readable damage numbers. A normal successful melee hit should deal at least one damage after armor. GUARD may fully absorb a hit as an explicit exception.
Do not restore health merely because the player walks back and forth. Healing comes from spells, consumables, finite shrine effects, or explicitly described level-up benefits.
Animations may continue between decisions, but animation callbacks must never determine damage, loot, enemy turns, or resource consumption.
7. Dungeon generation and living Cores
Generate five floors of approximately 48 × 32 tiles, with seven to ten connected rooms each. Favor readable layouts and meaningful encounters over enormous maps.
Mix a dependable room-and-corridor generator with a few handcrafted room templates: a library, crypt, shrine, treasury, and merchant room.
Each room has a stable ID, a semantic type, a generated name, and a short local description. Generate mechanics from its type—not by searching its display name for particular words.
Preserve room descriptions and search results after generation.
Validate connectivity after placing corridors, doors, and obstacles. The entrance, Core, required merchant room, and exit must be reachable without requiring any particular spell.
Place the Core in a room far from the entrance by actual walkable path distance, not simply in the last room generated.
Use bounded generation attempts and a valid fallback layout. Never rely on an unbounded random-placement loop.
A Core activates when first discovered. While active, it attempts to spawn a minion every six turns. Give it a cap of two living summoned minions and four successful summons total per floor.
A newly summoned minion cannot act until the following player turn. Failed placement must not hang the game or stack actors.
Display the Core’s health, spawning countdown, and remaining summon budget when it is visible. Spawning stops permanently when it dies.
Destroying the Core converts its tile into stairs. This happens exactly once. Entering the stairs prompts a clear, irreversible descent to the next floor.
Neither the player nor enemies should need to walk through an occupied Core tile to reach required areas.
8. Enemies, visibility, and the boss
Implement approximately six AI archetypes with data-driven letter variants rather than a separate AI implementation for every letter.
Include a straightforward melee pursuer, a durable guard, a slow creature, a ranged attacker, a mobile skirmisher, and a mimic.
Each should have a recognizable tactical role. Slow creatures may explicitly act every other turn; other enemies receive at most one action per player turn.
Use reliable grid pathfinding. Enemies cannot attack through walls, stack on one another, or know the player’s exact position after losing sight. They may investigate a last-known position.
A mimic should not reveal its true identity through hover text, health bars, the minimap, or the bestiary before discovery. Its reveal should leave the player a decision before its first attack.
Implement field of view with roughly seven tiles of vision and remembered terrain. Unexplored areas are hidden; explored but unseen terrain is dim.
Hide unseen enemies, health bars, effects, and current loot information. MAP reveals terrain knowledge, not omniscience.
The Redactor should have a telegraphed line attack: mark the threatened tiles, allow one complete player decision, then resolve the attack against those fixed tiles.
Give the boss a limited summoning budget and a basic melee attack. Do not require any specific spell to win.
The final Core is protected until the Redactor dies. Afterward, destroying it completes the run. Make both steps visible in the objective panel.
9. Fred, Tabby, and local storytelling
Fred the Sword is the player’s starting weapon and companion. He cannot be sold, discarded, or replaced, but he can be upgraded.
Write short, event-driven lines for discovering a room, learning a spell, narrowly surviving, burning valuable dice, confronting a Core, finding a memory, and winning or dying.
His personality is dry, opinionated, and occasionally helpful. He should not constantly interrupt play.
Use a dialogue catalog with conditions, priorities, cooldowns, and recent-line suppression. Commentary must reflect actual game events and must not reveal undiscovered information.
For example, after burning the last d8:
“That was our armor budget. An excellent vintage.”
Provide five short memory fragments about Tabby and the player’s earlier escape attempt. Tie them to discoverable objects or floor milestones, not a real-time timer.
Finish the story on the fifth floor. Tabby does not need escort AI; rescuing the cat can be part of the ending.
All dialogue and narrative text must work locally. No chatbot interface, API key, external language model, or network-generated room descriptions.
10. Equipment, advancement, and shops
Keep equipment compact: Fred, one armor slot, and two ring slots.
Use a small catalog of mechanically distinct armor and rings. Effects may improve armor, maximum health, mana capacity, spell damage, or vision. Give every displayed modifier a working effect.
Fred can receive a few bounded upgrades. Do not create hundreds of procedural weapons that the player cannot equip.
Generate item names from small local tables, but generate their descriptions from their actual effects. A colorful name must not imply an ability the item does not possess.
Track base statistics separately from equipment modifiers. Recompute derived statistics from current equipment instead of repeatedly adding and subtracting bonuses.
Equipment swaps must not create free healing or mana. Clamp current resources to new maximums without filling newly available capacity.
Gain experience from finite encounters. Offer modest level-up choices such as health, mana capacity, or combat power. Cap progression and handle the maximum level without an infinite loop.
Place Shopkeeper How in safe rooms on floors two and four. Stock healing items, dice-independent emergency consumables, letters, armor, rings, and a Fred upgrade.
Generate stock and prices once. Buying, selling, and upgrades must validate ownership and payment, then commit exactly once. Buying and selling the same item must never produce a profit loop.
Use finite stock and persistent transactions. Leave shop theft out of this version.
11. Interface and visual identity
Use a readable retro dungeon aesthetic: dark stone, parchment-like panels, bright glyphs, compact effects, and a restrained accent palette.
The player should be immediately recognizable as @ or an equally clear generated character token. Monsters should expose their collectible letters without requiring constant inspection.
Place the Phaser dungeon beside a compact panel showing health, mana, level, current floor, dice wallet, equipped items, current objective, and selected target.
Provide accessible buttons for Wait, Spellbook, Inventory, Burn a Die, Interact, Journal, and Help.
The spellbook should show learned spells first, then craftable recipes, then incomplete recipes with highlighted missing letters.
Keep a persistent, filterable journal with separate categories for combat, discoveries, and Fred’s comments. Use structured events internally; do not detect combat by searching prose for words such as “attacks” or “defeated.”
Add a bestiary that fills as creatures are encountered. Do not populate it with undiscovered monsters merely because the floor generator created them.
Support camera follow, zoom controls, resizing, and correct pointer-to-tile conversion at every zoom level.
Click-to-walk may traverse known safe terrain one resolved turn at a time. Interrupt it when an enemy becomes visible, the player takes damage, a path becomes blocked, or the player presses Escape. Do not auto-attack.
Bootstrap dialogs must prevent movement keys from leaking into the dungeon. Reopening a dialog must not attach duplicate event handlers.
Include a short tutorial, reduced-motion or fast-animation option, and visible explanations for disabled actions.
12. Architecture and persistence
Keep one authoritative, serializable run state separate from Phaser sprites, cameras, tweens, DOM elements, and event listeners.
Use integer tile coordinates throughout the simulation. Convert to pixels only in rendering and input adapters.
Organize the single file into clearly marked sections for configuration, content catalogs, seeded randomness, generation, state, action resolution, combat, AI, rendering, interface, persistence, and tests.
Route keyboard, mouse, touch, inventory buttons, and spell buttons through the same action resolver. Input handlers should request actions, not mutate health or inventory directly.
Use explicit input modes such as Exploring, Targeting, Menu, Resolving, and Run Over. Avoid a collection of unrelated movement and targeting booleans.
Use stable unique IDs for actors, items, rooms, containers, and events. Centralize death processing so experience, letters, loot, and objective updates can occur only once.
Save after completed turns and committed transactions. Persist the seed, gameplay random-generator state, map, actors, resources, learned spell IDs, inventory ownership, Core state, merchant stock, searched containers, memories, and pending level-up choices.
Resolve immutable spell properties from the catalog after loading. Do not reconstruct partially populated spell objects.
Use ordinary JSON-safe data and one save format. Never save Phaser objects or rendered journal HTML.
Cosmetic randomness must not change gameplay rolls. Reloading must not reroll loot, restore spent dice, revive dead enemies, refresh shops, or duplicate rewards.
Validate loaded saves, include a schema version, and show a useful message when storage is unavailable or corrupted.
Immediately record death or victory as a finished run. Ordinary refreshing must not resume it as active.
13. Completion and acceptance tests
Prioritize an entire enjoyable run over extra systems. Do not add possession, multiplayer, crafting beyond spell recipes, hunger, an overworld, unrestricted dialogue, online services, or permanent power progression.
Include lightweight tests for the rules independent of rendering.
Verify that repeated-letter recipes consume the correct counts: FIREBALL must require and remove two Ls. Invalid crafting must leave all resources unchanged.
Verify that canceled targeting spends nothing; a committed spell spends its displayed mana exactly once; Core damage is applied exactly once; and every death grants rewards at most once.
Verify that burning a die decrements the correct wallet count once, restores the actual rolled amount subject to the mana cap, and remains spent after reload.
Verify that movement, line of sight, teleportation, knockback, and pathfinding agree on blocked tiles and diagonal corners.
Verify connected maps across multiple seeds, finite Core summons, persistent searches and merchant stock, stable item ownership, and correct save/load restoration.
Provide a guaranteed playable opening sequence: pick up ZAP’s letters, learn ZAP, fight a simple enemy, collect its letter and dice, inspect another recipe, and encounter the first Core.
Every visible feature must work. No dummy combat, placeholder effects, fake buttons, missing assets, TODO sections, or invented claims about tests you did not execute.
Deliver the complete index.php in one code block, followed by brief local-server instructions, controls, and an honest validation note. Do not return another plan or split the implementation into additional files.