Download Game! Currently 126 players and visitors. Last logged in:WandererMesardusIberiamsspFimir

Blitzer's Blog >> 72467

Back to blogs index
Posted: 15 Sep 2026 16:19 [ permalink ]

#### 4. Add the Async Dispatcher Method

Add this new method directly inside the `RuntimeEnvironment` class:

```javascript
    async executeDelegatedCommand(verb, args, targetVar) {
        const cmd = this.delegatedCommands[verb];
        if (!cmd) return;

        // 1. Instant optimistic UI feedback
        if (cmd.start_msg) {
            console.log(`
${cmd.start_msg}`);
        }

        // Infer current room label from Program Counter
        let currentEnv = "UNKNOWN";
        let maxPc = -1;
        for (const [label, pc] of Object.entries(this.vm.labels || {})) {
            if (pc <= this.vm.pc && pc > maxPc) {
                maxPc = pc;
                currentEnv = label;
            }
        }

        // 2. Build the context envelope
        const payload = {
            verb,
            args,
            player: { id: "player_1" },
            room: { id: currentEnv },
            inventory: this.vm.memory['INVENTORY'] || [],
            memory: this.vm.memory
        };

        try {
            // 3. Dispatch with hard timeout race
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), cmd.timeout
|| 2000);

            const response = await fetch(cmd.endpoint, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload),
                signal: controller.signal
            });
            clearTimeout(timeoutId);

            if (!response.ok) throw new Error(`HTTP ${response.status}`);
            const data = await response.json();

            // 4. Output response
            if (data.output) {
                console.log(`
${data.output}`);
            }

            // 5. Apply memory mutations to VM state
            if (data.mutations) {
                if (data.mutations.memory && typeof data.mutations.memory ===
'object') {
                    this.vm.memory = { ...this.vm.memory, ...data.mutations.mem
ory };
                }
                if (data.mutations.inventory && Array.isArray(data.mutations.in
ventory)) {
                    this.vm.memory['INVENTORY'] = data.mutations.inventory;
                }
                this.saveState();
            }

        } catch (err) {
            // 6. Graceful timeout degradation
            if (cmd.fail_msg) {
                console.log(`
${cmd.fail_msg}`);
            }
        }

        // 7. Re-prompt user without advancing or breaking VM execution
        if (this.onPromptUser) this.onPromptUser(targetVar);
    }

```

---

### Testing the End-to-End Loop

1. **Start the VM** in Terminal 1:
```bash
cd /mnt/mesh_shared/src/ast-vm
npm start

```


*(You'll see `[SYS] Live Control Plane active on http://localhost:8080`)*
2. **Start the Command Microservice** in Terminal 3:
```bash
cd /mnt/mesh_shared/src/ast-vm-ext
npm start

```


*Terminal 1 should immediately print:*
```text
[SYS] Registered external command: PRAY -> http://localhost:3000/api/commands/p
ray

```


3. **Try typing in the VM**:
```text
> pray

```


You should see:
* Instant start message: `"You bow your head and begin to pray..."`
* External response text from `pray.js`.
* Any memory mutations automatically written to `game_idea.md` via
`saveState()`.


4. **Hot-reload test**:
Drop a new `shout.js` into `/mnt/mesh_shared/src/ast-vm-ext/commands/`, watch
it register live, and type `shout` directly into the VM prompt without
restarting anything.