- Store win and end conditions as a JSON AST (
{op: "pointsAtLeast", n: 10}withall/any/not). A code registry resolves each op. - A world stores a frozen copy of its scenario and a
rulesVersion. Changing a preset in code then does not change running worlds. - Each op lists its triggers (
built,tileLost, …). Check only affected predicates on a tick. This keeps cost low at large scale. - Keep balance numbers in one constants package per scenario. No
if scenario == Xin the engine.