Download Game! Currently 83 players and visitors. Last logged in:SilencerSolvikGlaurungDescad

Blitzer's Blog >> 72499

Back to blogs index
Posted: 15 Sep 2026 23:08 [ permalink ]
That is the exact architectural insight that turns this from a neat demo into
an infinite, expandable game world.
Instead of asking a 9B model to keep track of a massive 20-room
macro-worldwhich would inevitably blow its context window and break the
geometryyou treat each 34 room segment as an isolated, compiled Sector Object
or "chunk".
Building a deterministic Sector Linker (linker.js) to stitch these artifacts
together is straightforward because FSO code is completely flat and stateless.
1. Core Technical Hurdles to Solve
To cleanly merge game_area_001.md and game_area_002.md, the linker script
needs to handle three distinct collision domains:
| Domain | Problem | Deterministic Fix |
|---|---|---|
| Label Collisions | Both areas define LBL start_game, LBL handle_help, etc. |
Namespace every label on ingest (e.g., a1_room_cove vs a2_room_cove). |
| Start Hook | Area 2 has its own entry jump that conflicts with Area 1. |
Strip start_game from Area 2; preserve Area 1's as the master spawn. |
| Compass Alignment | Adding a passage between two rooms requires opposing
exits. | Find an unused compass pair on both border rooms, update their DESC
text, and append reciprocal EXIT opcodes. |
2. Architecture of the Sector Linker (linker.js)
Here is a blueprint for a clean, deterministic script that links two compiled
FSO game areas:
/ 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) {
    // 1. Rename LBLs (except start_game and handle_help)
    let processed = code.replace(/LBL (?!start_game|handle_help)(\w+)/g, `LBL
${areaPrefix}_$1`);
    
    // 2. Rename JMP and JMP_IF targets
    processed = processed.replace(/JMP (?!handle_help)(\w+)/g, `JMP
${areaPrefix}_$1`);
    processed = processed.replace(/JMP_IF (.+) (\w+)$/gm, `JMP_IF $1
${areaPrefix}_$2`);
    
    // 3. Rename EXIT targets
    processed = processed.replace(/EXIT "([^"]+)" (?!handle_help)(\w+)/g,
`EXIT "$1" ${areaPrefix}_$2`);

    return processed;
}

export function mergeAreas(area1File, area2File, linkConfig) {
    // linkConfig: { room1: 'treasureroom', room2: 'jungle_path', dir1:
'EAST', dir2: 'WEST' }
    const a1Raw = fs.readFileSync(area1File, 'utf-8');
    const a2Raw = fs.readFileSync(area2File, 'utf-8');

    const a1 = parseEnvelope(a1Raw);
    const a2 = parseEnvelope(a2Raw);

    // Apply namespace prefixes to prevent identifier collisions
    let c1 = prefixArea(a1.code, 'a1');
    let c2 = prefixArea(a2.code, 'a2');

    // Strip start_game from Area 2 so it doesn't hijack execution
    c2 = c2.replace(/LBL start_game[\s\S]*?JMP \w+
/, '');
    // Strip duplicate global handlers
    c2 = c2.replace(/LBL handle_help[\s\S]*?AWAIT
/, '');

    // Inject the bidirectional stitch into the respective room blocks
    const exit1 = `EXIT "${linkConfig.dir1}" a2_room_${linkConfig.room2}
`;
    const exit2 = `EXIT "${linkConfig.dir2}" a1_room_${linkConfig.room1}
`;

    c1 = c1.replace(new RegExp(`(LBL a1_room_${linkConfig.room1}[\\s\\S]*?)(AWA
IT)`), `$1${exit1}$2`);
    c2 = c2.replace(new RegExp(`(LBL a2_room_${linkConfig.room2}[\\s\\S]*?)(AWA
IT)`), `$2${exit2}$2`);

    // Merge code and deduplicate base state
    const mergedCode = `${c1}

// --- SECTOR LINK: AREA 2 ---
${c2}`;
    const mergedState = `VAR INVENTORY ARR '[]'`;

    return `\`\`\`fso-state
${mergedState}
\`\`\`

\`\`\`fso-code
${mergedCode}
\`\`\``;
}

3. Why This Approach Scales
 * Infinite Modular Worlds: You can chain chunks indefinitely (area_001
connects to 002, which connects to 003), building expansive dungeon complexes
without overwhelming the model.
 * Deterministic Portals: The connection can be an ordinary direction
(EAST/WEST) or thematic transit opcodes like EXIT "PORTAL" a2_room_dungeon or
EXIT "SAIL" a2_room_island.
 * Zero Model Drift: Because the linking is executed entirely by regex in
Node.js, there is zero probability of the model breaking an existing room
while opening a passage to the next area.