Skip to content

main no longer boots Claude-of-Duty: "Set.prototype.add is not a function" in world construction #9907

Description

@proggeramlug

Summary

Current main no longer boots Claude-of-Duty. World construction dies with:

[boot] init failed TypeError: Set.prototype.add is not a function
TypeError: Set.prototype.add is not a function
    at solidSlabs        (src/world/util.js:591)
    at buildBuilding
    at WorldSystem.init
    at createConfig

Set.prototype.add is of course a builtin, so a receiver that reached this point is not being recognised as a Set.

The code

src/world/util.js:591 — nothing exotic:

export function solidSlabs(w, h, holes) {
  const xs = new Set([-w / 2, w / 2]);
  for (const o of holes) {
    xs.add(Math.max(-w / 2, o.x - o.w / 2));
    xs.add(Math.min(w / 2, o.x + o.w / 2));
  }
  const cuts = [...xs].sort((a, b) => a - b);
  // …
}

Regression window

base result
d36a1af0c (+ the root_reload cap fix, now upstream as b0bb990db) boots, renders
890514a6d fails as above

That is 108 commits. Both bases have the root_reload fix, so it is not that.

What does NOT reproduce

Every reduction I tried passes on 890514a6d. Compiled and run individually:

  1. new Set() + .add()
  2. class Tracked extends Set overriding add and calling super.add
  3. a Set held in a class field, mutated through a method
  4. .add reached by computed key — (d as any)["add"](5)
  5. new Set([1, 2, 3]) then .add(4) — literal elements
  6. new Set([-w / 2, w / 2]) then .add(...)computed elements
  7. the whole solidSlabs body reproduced standalone, with holes
  8. the game's real solidSlabs, imported from src/world/util.js and called directly — 75 MB binary, correct output

Number 8 is the informative one: the same function, same module, same import graph, compiled and called on its own, works. It only fails inside the full program.

That points at something context-dependent rather than at the lowering of this function in isolation — specialization driven by the real call sites (src/world/kit.js:106 passes openings) is my first guess, but I have not confirmed it.

Reproducer

git clone <claude-of-duty>
perry compile src/native/main.ts -o dist/cod
./dist/cod

Fails during world init, ~60 s in, before any window content.

I could not narrow it further without full game builds (~35 min each), which makes a 108-commit bisect impractical on my side. Someone able to bisect this range in CI should land on it quickly, and I am happy to test any candidate commit.

Note

An unrelated observation from the same comparison, in case it is a useful signal: the compiled binary grew from 106 MB to 151 MB across this same 108-commit window, with identical auto-optimize flags and near-identical runtime/stdlib archive sizes (26.7 -> 27.0 MB, 35.0 -> 35.3 MB). So the growth is in generated code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions