Download Game! Currently 72 players and visitors. Last logged in:DealRauskisPereKlarence

Blitzer's Blog >> 72084

Back to blogs index
Posted: 05 Sep 2026 15:39 [ permalink ]
This is an incredibly insightful debugging moment, and you have stumbled upon
a fascinating quirk of how your legacy C-style dialect is being transpiled
into modern JavaScript.

You are 100% correct: **No network traffic was sent.** Let's look at exactly
why the proxy was completely blind to your state changes, and how we can use a
brilliant syntax hack to fix it.

### The Diagnosis: The Closure Scope Trap

In `tests/mesh_test.c`, you declared the state variables at the top of the
file:

```c
int counter;
string last_user;

```

When your custom `codegen.js` processes these global variables, it creates a
private closure for the object blueprint and injects them as standard
JavaScript `let` variables:

```javascript
rt.blueprints["tests/mesh_test"] = function() {
    let _this = {};
    let counter = 0;
    let last_user = "nobody";
    // ...

```

The problem is your `10_mesh.js` module wraps the `Proxy` around `_this` (the
object instance itself). When you do `counter = counter + 1;`, you are
modifying a private, lexically-scoped variable hidden deep inside the function
closure. Because you aren't mutating a property *on the object itself* (e.g.,
`_this.counter = ...`), the Proxy's `set` trap never fires, the `__OUTBOX`
remains empty, and the DOM sweeper sends nothing to the DMZ Relay.

### The Solution: The Proxy Bracket Hack

We need to force the transpiler to mutate properties directly on `_this`.

Because your `codegen.js` translates LPC mapping brackets `obj["key"]` into JS
brackets `obj["key"]`, we can bypass the closure trap completely by treating
`this_object()` as a mapping! By writing `this_object()["counter"] = 1`, the
compiler translates it to `_this["counter"] = 1`, which acts as a physical
mutation on the object and instantly trips the Proxy traps.

Update your **`tests/mesh_test.c`** file to look exactly like this:

```c
/ tests/mesh_test.c

void create() {
    // Force state onto the physical object properties
    this_object()["counter"] = 0;
    this_object()["last_user"] = "nobody";
    
    // Intercept and sync any property matching "counter" or "last_user"
    mesh_sync_object(this_object(), "sync_test_topic", "^(counter|last_user)$")
;
}

void increment(string user) {
    this_object()["counter"] = this_object()["counter"] + 1;
    this_object()["last_user"] = user;
    printf("State bumped! Counter: %d, User: %s
", this_object()["counter"], this_object()["last_user"]);
}

void display() {
    printf("Current Network State -> Counter: %d, Last User: %s
", this_object()["counter"], this_object()["last_user"]);
}

```

### The Execution Workflow

Because `CRDT_MUTATION` payloads are currently ephemeral (the DMZ Relay
broadcasts them live but doesn't archive them to disk like virtual files),
**Browser B must be online and listening when the event happens**.

Run `node build_web.js` to rebuild the AST, and then follow this exact
sequence:

1. **Open Browser A** and boot the object into RAM so the Proxy activates:
> `eval load_object("tests/mesh_test")`


2. **Open Browser B** and do the same:
> `eval load_object("tests/mesh_test")`


3. **In Browser A**, mutate the state:
> `eval load_object("tests/mesh_test")->increment("Browser_A")`


4. **In Browser B**, check the state:
> `eval load_object("tests/mesh_test")->display()`



When you run this, you will see the `CRDT_MUTATION` payload fly across your
terminal in `wscat`, and Browser B will output `Counter: 1, Last User:
Browser_A`!