This is the holy grail of procedural text adventures. By compiling small,
stable "chunks" and deterministically stitching them together, you completely
bypass the context-window limits of the LLM.
You can run this pipeline overnight to generate 50 areas, link them all
seamlessly, and build an entire MMO-scale world without a single hallucinated
room.
Here is the deterministic linker.js script to fuse two valid FSO artifacts
together.
1. The Sector Linker (linker.js)
This script will read both files, prefix all labels to prevent namespace
collisions (e.g., LBL a1_room_cove vs LBL a2_room_cove), strip the duplicate
global handlers from Area 2, mathematically inject the bidirectional exits,
and update the room descriptions so the player knows the path is open.
Copy and paste this into your terminal:
cat << 'EOF' > linker.js import fs from 'fs'; function parseEnvelope(content)
{ const stateMatch = content.match(/```fso-state([\s\S]*?)```/); const
codeMatch = content.match(/```fso-code([\s\S]*?)```/); return { state:
stateMatch ? stateMatch[1].trim() : '', code: codeMatch ? codeMatch[1].trim()
: '' }; } function prefixArea(code, areaPrefix) { // Prefix all LBL
declarations (except globals) let processed = code.replace(/LBL
(?!start_game|handle_help)(\w+)/g, `LBL ${areaPrefix}_$1`); // Prefix JMP
targets processed = processed.replace(/JMP (?!handle_help)(\w+)/g, `JMP
${areaPrefix}_$1`); processed = processed.replace(/JMP_IF (.+) (\w+)$/gm,
`JMP_IF $1 ${areaPrefix}_$2`); // Prefix EXIT targets processed =
processed.replace(/EXIT "([^"]+)" (?!handle_help)(\w+)/g, `EXIT "$1"
${areaPrefix}_$2`); return processed; } function mergeAreas(a1Path, a2Path,
config) { const a1 = parseEnvelope(fs.readFileSync(a1Path, 'utf-8')); const a2
= parseEnvelope(fs.readFileSync(a2Path, 'utf-8')); let c1 = prefixArea(a1.code,
'a1'); let c2 = prefixArea(a2.code, 'a2'); // Strip entry point and globals
from Area 2 to prevent hijacking c2 = c2.replace(/LBL start_game[\s\S]*?JMP
\w+
/, ''); c2 = c2.replace(/GLOBAL "HELP" handle_help
/, ''); c2 = c2.replace(/LBL handle_help[\s\S]*?AWAIT
/, ''); // Formulate the bidirectional exits const exit1 = `EXIT
"${config.dir1}" a2_room_${config.room2}
`; const exit2 = `EXIT "${config.dir2}" a1_room_${config.room1}
`; // Inject the EXITS strictly above the AWAIT opcode c1 = c1.replace(new
RegExp(`(LBL a1_room_${config.room1}[\\s\\S]*?)(AWAIT)`), `$1${exit1}$2`); c2
= c2.replace(new RegExp(`(LBL a2_room_${config.room2}[\\s\\S]*?)(AWAIT)`),
`$1${exit2}$2`); // Append the new exits to the DESC string so the player can
see them c1 = c1.replace(new RegExp(`(LBL a1_room_${config.room1}[\\s\\S]*?DESC
"[^"]+)("\
)`), `$1 [Path ${config.dir1} is open]$2`); c2 = c2.replace(new RegExp(`(LBL
a2_room_${config.room2}[\\s\\S]*?DESC "[^"]+)("\
)`), `$1 [Path ${config.dir2} is open]$2`); // Build the final mast
er envelope return `\`\`\`fso-state
VAR INVENTORY ARR '[]'
\`\`\`
\`\`\`fso-code
${c1.trim()}
// --- SECTOR 2 ---
${c2.trim()}
\`\`\``; } // CLI Execution parameters const [,, p1, p2, r1, r2, d1, d2, out]
= process.argv; if (!out) { console.log("Usage: node linker.js <area1> <area2>
<room1> <room2> <dir1> <dir2> <output>"); process.exit(1); } try { const
outputString = mergeAreas(p1, p2, {room1: r1, room2: r2, dir1: d1, dir2: d2});
fs.writeFileSync(out, outputString); console.log(`[SYS] World Merged: ${r1}
<-> ${r2} via ${d1}/${d2} into ${out}`); } catch (err) { console.error(`[LINKER
FAULT] ${err.message}`); } EOF
2. Mocking Area 2
To save you from running the full 3-stage LLM pipeline just to test the
linker, let's create a quick valid game_area_002.md right now. Let's make it a
dangerous jungle biome.
cat << 'EOF' > game_area_002.md ```fso-state VAR INVENTORY ARR '[]' LBL
start_game GLOBAL "HELP" handle_help JMP room_jungle LBL room_jungle ENV_FLUSH
DESC "A dense, humid jungle. Vines hang from the canopy. Exits: EAST." EXIT
"EAST" room_temple AWAIT LBL room_temple ENV_FLUSH DESC "An ancient stone
temple overgrown with moss. Exits: WEST." EXIT "WEST" room_jungle AWAIT LBL
handle_help OUT "Type directions (like NORTH or EAST) to move around." AWAIT
EOF
--- ### 3. Fuse the Worlds! Let's link the `cove` from Area 1 to the `jungle`
in Area 2. We will route it so heading `SOUTH` from the Cove takes you into
the Jungle, and heading `NORTH` from the Jungle brings you back to the Cove.
Run the linker script: ```bash node linker.js final_game.md game_area_002.md
cove jungle SOUTH NORTH world.md
4. Play the Mega-World
If the linker worked, you now have a seamless, multi-biome game. Boot up the
mega-world:
node cli.js world.md
Look at the description when you spawn in the Cove. It should dynamically say
[Path SOUTH is open]. Try walking SOUTH into the Jungle, EAST to the Temple,
and all the way back to the Shipwreck to solve the locked door!