A text-based RPG is a loop of reading a description, making a choice, and updating a few numbers. You can build one in your browser using a simple state machine for stats and inventory, then feed that state to a local AI engine to generate the narrative. The key is defining strict rules for what the player can do and what the AI is allowed to invent.
Why Build a Text-Based RPG Locally?
Traditional text adventures require you to write every room description and dialogue line by hand. This becomes tedious fast, and while branching paths can multiply the number of possible routes, replayability often comes from state changes, puzzles, or limited branches rather than an exponential requirement. Using a local AI engine to handle the narrative generation significantly reduces the content bottleneck. You define the physics and the rules; the AI fills in the flavor. However, this does not eliminate the work entirely. You still need to craft prompts, edit generated text for consistency, and integrate the narrative output with your game logic.
Doing this locally in the browser means you can prototype instantly. There is no server setup or database to manage on your end, though you will still experience some latency from loading the engine, executing JavaScript, and rendering text. If you are experimenting with game balance, you can reset the state and try again immediately. This speed is critical for tuning the difficulty of puzzles and combat encounters.
Setting Up Your Browser Environment
You do not need a heavy framework. A single HTML file with embedded JavaScript is sufficient for a prototype. The core requirement is a text area for the game log and an input field for player commands. You also need a way to hold the game state, such as a simple object, variables, or other data structures.
Here is the minimal HTML structure you need:
<!DOCTYPE html>
<html>
<head>
<title>Shadow Vale</title>
<style>
body { font-family: monospace; background: #111; color: #eee; padding: 20px; }
#log { height: 400px; overflow-y: scroll; border: 1px solid #333; padding: 10px; }
#input { width: 100%; margin-top: 10px; background: #222; color: #fff; border: 1px solid #444; padding: 5px; }
</style>
</head>
<body>
<div id="log"></div>
<input type="text" id="input" placeholder="Type 'look', 'go north', or 'use key'">
<script>
// Game logic goes here
</script>
</body>
</html>
This setup keeps the interface clean. The #log div displays the AI's output and your actions. The HTML input element captures player commands. All logic lives in the script tag.
Designing the Core Loop: Stats and Inventory
The "game" part of the RPG is the state management. You need to track health, stats, and items. For this guide, we will use a simplified three-stat system: Strength, Agility, and Magic. These numbers determine if you can force a door open, dodge a trap, or cast a spell.
Define your player object clearly. Do not let the AI change these numbers arbitrarily; only your code should update them based on rules.
let player = {
name: "Kael",
stats: { strength: 5, agility: 3, magic: 2 },
inventory: ["rusty sword", "lantern"],
health: 100,
location: "start"
};
function updateHealth(amount) {
player.health += amount;
if (player.health <= 0) {
log("You have fallen. The Vale claims another soul.");
return true; // Game over
}
return false;
}
When the player interacts with the world, you check these stats. If the player tries to break a wooden crate, you might check if strength > 4. If they try to sneak past a guard, check agility > 3. The AI generates the description of the crate or the guard, but your code decides if the action succeeds.
Prompting the AI Dungeon Master
This is where the magic happens. You need to send the current game state to the AI and ask for a narrative response. The prompt must be strict. If you are too vague, the AI will invent new rules or ignore your inventory.
A good prompt includes the current location, the player's status, and the specific action they took. It should also constrain the AI to only describe the outcome, not change the stats.
For the "Shadow Vale" adventure, you might use a prompt like this:
You are the Dungeon Master for a text RPG set in Shadow Vale.
Current Player State:
- Name: Kael
- Stats: Strength 5, Agility 3, Magic 2
- Inventory: rusty sword, lantern
- Location: start (a foggy forest edge)
- Health: 100
Action: The player examines the mossy stone archway.
Write a vivid, 3-sentence description of what Kael sees.
Do not change his stats or inventory.
Mention if there is a hidden mechanism or item visible to the eye.
The constraint "Do not change his stats" is vital. Without it, the AI might decide Kael finds a sword and adds it to his inventory in the text, but your code won't know about it. Keep the AI as the narrator, not the game engine.
Generating Worlds and Quests Procedurally
You do not need to write every room. You can use the AI to generate the initial setup. For the Shadow Vale example, you want a starting dungeon with three unique NPCs and a hidden key puzzle.
Instead of hardcoding the NPCs, prompt the AI to generate them at the start of the game. You can store their names and roles in your JavaScript object.
Example generation prompt:
Generate 3 unique NPCs for the Shadow Vale starting area.
Each NPC should have:
1. A name
2. A brief personality trait
3. One secret they might reveal if asked politely
Output as a JSON object.
You then parse this JSON into your game state. When the player talks to an NPC, you pass the NPC's personality and secret to the AI as context. This ensures the NPC acts consistently. If the player asks about the "hidden key," the AI knows which NPC knows the secret because you passed that data in the prompt.
Testing and Balancing Your Adventure
Balancing a text RPG is difficult because the AI can be unpredictable. You need to test the "happy path" and the "failure path."
For the Shadow Vale puzzle, ensure the key is not too easy to find. If the AI hints at it too strongly in the description, the puzzle is solved. If it is too obscure, players will quit.
Test this by playing the scenario multiple times. Since the AI generates unique descriptions each time, you might see the key mentioned in the first paragraph one run and not at all the next. Adjust your prompt to control the "hint level."
Try adding a constraint to the prompt:
...
Mention the hidden key only if the player uses the lantern or looks closely.
Otherwise, describe the archway as plain and unremarkable.
This ties the AI's narrative output to your game mechanics. If the player has the lantern in their inventory, you can programmatically add the "uses lantern" flag to the prompt context.
Playing Offline and Saving Your Legend
Once you have the basic loop working, you can enhance the experience. Since the AI runs on your device, you can save the entire game state to local storage. This allows you to pause and resume later.
Serialize your player object and the current location data to JSON and save it to localStorage. When you reload the page, parse it back.
function saveGame() {
localStorage.setItem('shadowValeSave', JSON.stringify(player));
}
function loadGame() {
const saved = localStorage.getItem('shadowValeSave');
if (saved) {
player = JSON.parse(saved);
log("Welcome back, " + player.name + ".");
}
}
If you want a more polished experience with automatic world generation and persistent character progression, you can use Mythforge. It handles the on-device AI engine and state management for you, letting you focus on the narrative rules. It generates worlds and quests locally, so your data never leaves your device, and you can play offline once loaded.
The key to a good text RPG is not the AI's ability to write well, but your ability to constrain it. Define the rules, manage the state, and let the AI paint the picture. Start small with one room and one puzzle, then expand.