Download Game! Currently 80 players and visitors. Last logged in:TigerlilyNocturIberiamsspGralgarr

Blitzer's Blog >> 72430

Back to blogs index
Posted: 15 Sep 2026 13:36 [ permalink ]
This is one of my absolute favorite types of bugs. Gemma followed your
instructions *flawlessly*it used `ACTION`, `AWAIT`, and `ENV_FLUSH` perfectly!
The logic it generated is a thing of beauty.

So why did "go north" fail?

The issue isn't Gemma. The issue is a classic Virtual Machine instruction
pointer race condition in our JavaScript!

### The Detective Work: Why `go north` failed

Let's look at what our Node.js runtime did when you typed `go north`:

1. `processInput` parsed it into `VERB = GO`, `ARG1 = NORTH`.
2. It checked `this.vm.actions['GO']` and found the label `handle_go`.
3. It correctly set the VM's Program Counter (`pc`) to the exact index of
`handle_go`.
4. Then, it called `this.vm.resume()` to wake the VM back up.

Now, let's look at what `resume()` does inside `vm.js`:

```javascript
resume(injectedMemory = {}) {
    this.memory = { ...this.memory, ...injectedMemory };
    this.state = 'RUNNING';
    this.pc++; // Move past the yielding instruction!
    this.run();
}

```

**The culprit is `this.pc++`!**

When `AWAIT` yielded execution, we needed `pc++` to move past it. But because
our smart parser manually moved the `pc` to the `handle_go` label *before*
calling resume, the `resume()` function faithfully added `1` to it.

As a result, it completely skipped the very first instruction in the block
(`JMP_IF ARG1 CONTAINS "NORTH" jungle_entrance`) and landed directly on the
second instruction: `OUT "You cannot go that way."`

It literally jumped over the condition check!

### The Fix: The PC Offset

We don't even need to modify the core VM to fix this. We just need to tell our
smart parser in `runtime.js` to offset the Program Counter by `-1` whenever it
performs an auto-jump, knowing that `resume()` is about to add `1` back to it.

Open `runtime.js` and update your `processInput` function to look like this:

```javascript
    // Intercept user input before it hits the VM
    processInput(input, targetVar) {
        const normalizedInput = input.trim().toUpperCase();
        
        // 1. Shadow Registry Intercept
        const words = normalizedInput.split(' ');
        const verb = words[0];
        const target = words[1];

        if (target && this.shadowRegistry[target]) {
            const shadowObj = this.shadowRegistry[target];
            if (shadowObj.hijackVerbs.includes(verb)) {
                console.log(`
[SYSTEM] You ${verb.toLowerCase()} the ${target.toLowerCase()}...`);
                console.log(`> The external environment responds:
${shadowObj.interactionText}`);
                if (this.onPromptUser) this.onPromptUser(targetVar);
                return; 
            }
        }

        // 2. Smart Parsing for AWAIT
        if (targetVar === '__AUTO_CMD__') {
            const fillers = ['AT', 'THE', 'TO', 'IN', 'ON', 'WITH'];
            const cleanWords = normalizedInput.split(' ').filter(w =>
!fillers.includes(w));
            
            const cleanVerb = cleanWords[0] || "";
            const arg1 = cleanWords[1] || "";
            const arg2 = cleanWords[2] || "";

            this.vm.memory['VERB'] = cleanVerb;
            this.vm.memory['ARG1'] = arg1;
            this.vm.memory['ARG2'] = arg2;

            let didAutoJump = false;

            if (this.vm.actions && this.vm.actions[cleanVerb]) {
                const targetLabel = this.vm.actions[cleanVerb];
                if (this.vm.labels[targetLabel] !== undefined) {
                    this.vm.pc = this.vm.labels[targetLabel];
                    didAutoJump = true;
                }
            }
            
            // The PC Offset Trick: If we jumped, subtract 1 so resume() puts
us in the right spot
            if (didAutoJump) {
                this.vm.pc--; 
            }
            
            this.vm.resume(); 
        } else {
            // Legacy INP behavior
            this.vm.resume({ [targetVar]: normalizedInput });
        }
    }

```

Once you apply this one-line mathematical trick (`this.vm.pc--`), your VM will
correctly execute the `JMP_IF` check.

Since Gemma's code structure is so perfect here, this patch will immediately
unlock the Jungle, the Hidden Cave, and whatever Treasure it generated for
you. Run `npm start` again and let's go get that treasure!