nemocity / web /mock /feed.js
AndresCarreon's picture
NEMOCITY v0 β€” mock backend, gradio 6.16.0 (pre-SSR)
d72231c verified
Raw
History Blame Contribute Delete
11 kB
// NEMOCITY β€” scripted mock petition feed (?mock=1 and the live "welcome build").
// Each script is a full petition lifecycle as SSE-shaped events with relative
// delays (seconds of simTime). main.js stamps feature.t at apply time so
// construction always starts "now"; world_delta features carry exact cells
// (the engine isn't running in mock β€” these were placed by hand against the
// genesis layout and do not collide with it or with each other).
//
// GENESIS_FEATURES mirrors the contract's genesis list verbatim β€” the fallback
// when web/mock/world.json (generated later by tools/gen_web.py) is absent.
const T0 = 1781222400; // CITY_EPOCH_S
const colCells = (cx, z0, z1) => {
const cells = [];
for (let z = z0; z <= z1; z++) cells.push([cx, z]);
return cells;
};
const rowCells = (cz, x0, x1, skip = []) => {
const cells = [];
for (let x = x0; x <= x1; x++) if (!skip.includes(x)) cells.push([x, cz]);
return cells;
};
const seedOf = (i) => (2654435761 * (i + 1)) % 2147483647;
let gi = 0;
const G = (tool, args) => ({
id: `e_g${String(++gi).padStart(3, "0")}`,
wish_id: "genesis",
tool,
args,
seed: seedOf(gi),
t: T0 + gi * 0.25,
});
const GB = (kind, name, cx, cz, w, d, floors, hue, variant) =>
G("place_building", { kind, name, cx, cz, w, d, floors, hue, variant });
export const GENESIS_FEATURES = [
// roads first (every genesis footprint touches one)
G("lay_road", { cells: colCells(0, -12, 12), klass: "avenue", name: "Main St" }),
G("lay_road", { cells: rowCells(0, -12, 16, [8, 9]), klass: "avenue", name: "1st Ave" }),
G("lay_road", { cells: [[8, 0], [9, 0]], klass: "street", name: "Old Bridge" }),
G("lay_road", { cells: colCells(13, -6, 6), klass: "street", name: "River Rd" }),
G("lay_road", { cells: rowCells(-5, -8, 0), klass: "street", name: "Elm St" }),
G("lay_road", { cells: colCells(-5, -5, 3), klass: "street", name: "2nd St" }),
// downtown
GB("town_hall", "City Hall", -2, -3, 2, 2, 2, 44, 0),
GB("office", "Meridian House", 1, -2, 1, 1, 5, 208, 1),
GB("cafe", "Corner Cafe", 1, 1, 1, 1, 1, 35, 0),
GB("market", "Main St Market", -1, 1, 1, 2, 1, 30, 2),
GB("park", "Founders Park", -4, 1, 2, 2, 0, 110, 0),
// Elm / 2nd St cluster
GB("house", "Elm Cottage", -1, -6, 1, 1, 1, 18, 0),
GB("house", "Gable House", -4, -6, 1, 1, 2, 26, 1),
GB("house", "Second St House", -6, -4, 1, 1, 1, 350, 2),
// east of the river: the bridge commute from day one
GB("factory", "Riverside Works", 14, -3, 3, 2, 1, 28, 0),
GB("warehouse", "East Storage", 14, 1, 2, 2, 1, 40, 1),
GB("house", "River House", 14, 3, 1, 1, 1, 14, 0),
GB("house", "Ferry Cottage", 14, -5, 1, 1, 2, 200, 1),
G("note", { text: "Nemocity is listening. Ask for a building.", kind: "milestone" }),
];
// ------------------------------------------------------------------ scripts
const WELCOME = {
wish_id: "w_demo_cafe",
match: "cafe|coffee|shop|store|bakery|restaurant|diner",
events: [
{ at: 0.0, ev: { type: "wish_started", wish_id: "w_demo_cafe",
text: "a corner cafe where Main St meets 1st Ave" } },
{ at: 2.6, ev: { type: "plan", wish_id: "w_demo_cafe", plan: {
intent: "build",
blurb: "A warm corner for the morning crowd. Permit granted.",
buildings: [{ kind: "cafe", name: "Cafe Luna", near: "Main St and 1st Ave", floors: 1, hue: 35 }],
decline_reason: null } } },
{ at: 3.4, ev: { type: "tool_call", wish_id: "w_demo_cafe", call_index: 0, tool: "place_building",
args: { kind: "cafe", name: "Cafe Luna", cx: 2, cz: 1, w: 1, d: 1, floors: 1, hue: 35, variant: 2 } } },
{ at: 3.7, ev: { type: "world_delta", feature: { id: "e_demo_cafe", wish_id: "w_demo_cafe",
tool: "place_building",
args: { kind: "cafe", name: "Cafe Luna", cx: 2, cz: 1, w: 1, d: 1, floors: 1, hue: 35, variant: 2 },
seed: 1830293847 } } },
{ at: 5.4, ev: { type: "wish_granted", wish_id: "w_demo_cafe", epoch: null,
epitaph: "Cafe Luna opens where Main St meets 1st Ave β€” first coffee is on the mayor." } },
],
};
const APARTMENTS = {
wish_id: "w_demo_apts",
match: "apartment|home|house|housing|condo|famil|live|residen",
events: [
{ at: 0.0, ev: { type: "wish_started", wish_id: "w_demo_apts",
text: "homes for the families moving in" } },
{ at: 2.7, ev: { type: "plan", wish_id: "w_demo_apts", plan: {
intent: "build",
blurb: "Homes first β€” five floors of them, walking distance to the square.",
buildings: [{ kind: "apartments", name: "Elm Court", near: "north end of Main St", floors: 5, hue: 18 }],
decline_reason: null } } },
{ at: 3.5, ev: { type: "tool_call", wish_id: "w_demo_apts", call_index: 0, tool: "place_building",
args: { kind: "apartments", name: "Elm Court", cx: 1, cz: -8, w: 2, d: 2, floors: 5, hue: 18, variant: 1 } } },
{ at: 3.8, ev: { type: "world_delta", feature: { id: "e_demo_apts", wish_id: "w_demo_apts",
tool: "place_building",
args: { kind: "apartments", name: "Elm Court", cx: 1, cz: -8, w: 2, d: 2, floors: 5, hue: 18, variant: 1 },
seed: 482919101 } } },
{ at: 5.6, ev: { type: "wish_granted", wish_id: "w_demo_apts", epoch: null,
epitaph: "Elm Court tops out at five floors β€” sixteen new households over Main St." } },
],
};
const PARK = {
wish_id: "w_demo_park",
match: "park|garden|green|playground|tree|lawn|plaza|square",
events: [
{ at: 0.0, ev: { type: "wish_started", wish_id: "w_demo_park",
text: "a little park east of Main St" } },
{ at: 2.6, ev: { type: "plan", wish_id: "w_demo_park", plan: {
intent: "build",
blurb: "Every block deserves shade. A green opens off Main St.",
buildings: [{ kind: "park", name: "Juniper Green", near: "east of Main St", floors: null, hue: null }],
decline_reason: null } } },
{ at: 3.4, ev: { type: "tool_call", wish_id: "w_demo_park", call_index: 0, tool: "place_building",
args: { kind: "park", name: "Juniper Green", cx: 3, cz: 3, w: 2, d: 2, floors: 0, hue: 110, variant: 0 } } },
{ at: 3.7, ev: { type: "world_delta", feature: { id: "e_demo_park", wish_id: "w_demo_park",
tool: "place_building",
args: { kind: "park", name: "Juniper Green", cx: 3, cz: 3, w: 2, d: 2, floors: 0, hue: 110, variant: 0 },
seed: 99182447 } } },
{ at: 4.6, ev: { type: "tool_call", wish_id: "w_demo_park", call_index: 1, tool: "lay_road",
args: { cells: [[1, 3], [2, 3]], klass: "street", name: "Juniper Walk" } } },
{ at: 4.9, ev: { type: "world_delta", feature: { id: "e_demo_parkrd", wish_id: "w_demo_park",
tool: "lay_road",
args: { cells: [[1, 3], [2, 3]], klass: "street", name: "Juniper Walk" },
seed: 77120993 } } },
{ at: 6.6, ev: { type: "wish_granted", wish_id: "w_demo_park", epoch: null,
epitaph: "Juniper Green opens at the end of a brand-new lane off Main St." } },
],
};
const TOWER = {
wish_id: "w_demo_tower",
match: "tower|skyscraper|office|highrise|high-rise|bank|glass|tall",
events: [
{ at: 0.0, ev: { type: "wish_started", wish_id: "w_demo_tower",
text: "a glass tower for the downtown skyline" } },
{ at: 2.8, ev: { type: "plan", wish_id: "w_demo_tower", plan: {
intent: "build",
blurb: "Downtown earns a crown β€” twelve floors by Founders Park.",
buildings: [{ kind: "tower", name: "Nano Spire", near: "downtown", floors: 12, hue: 205 }],
decline_reason: null } } },
{ at: 3.5, ev: { type: "tool_call", wish_id: "w_demo_tower", call_index: 0, tool: "place_building",
args: { kind: "tower", name: "Nano Spire", cx: -3, cz: 3, w: 2, d: 2, floors: 12, hue: 205, variant: 0 } } },
{ at: 3.8, ev: { type: "world_delta", feature: { id: "e_demo_tower", wish_id: "w_demo_tower",
tool: "place_building",
args: { kind: "tower", name: "Nano Spire", cx: -3, cz: 3, w: 2, d: 2, floors: 12, hue: 205, variant: 0 },
seed: 555888221 } } },
{ at: 4.7, ev: { type: "tool_call", wish_id: "w_demo_tower", call_index: 1, tool: "lay_road",
args: { cells: [[-1, 3]], klass: "street", name: "Spire Ct" } } },
{ at: 5.0, ev: { type: "world_delta", feature: { id: "e_demo_towerrd", wish_id: "w_demo_tower",
tool: "lay_road",
args: { cells: [[-1, 3]], klass: "street", name: "Spire Ct" },
seed: 31337077 } } },
// demand-driven infill: jobs outran housing β€” the engine adds ONE home
{ at: 6.2, ev: { type: "world_delta", feature: { id: "e_demo_infill", wish_id: "w_demo_tower",
tool: "place_building",
args: { kind: "house", name: "Garden Cottage", cx: -5, cz: 4, w: 1, d: 1, floors: 1, hue: 95, variant: 1 },
seed: 90210663 } } },
{ at: 6.6, ev: { type: "world_delta", feature: { id: "e_demo_infillnote", wish_id: "w_demo_tower",
tool: "note", args: { text: "New families are moving in.", kind: "infill" }, seed: 7 } } },
{ at: 7.8, ev: { type: "wish_granted", wish_id: "w_demo_tower", epoch: null,
epitaph: "Nano Spire tops out at twelve floors β€” the skyline finds its center." } },
],
};
export const SCRIPTS = [WELCOME, APARTMENTS, PARK, TOWER];
export { WELCOME };
// The traffic-fix beat: alert -> City Engineer reads telemetry -> ONE apply_fix.
// The new avenue runs cz=-6 from Main St to River Rd, bridging the river at
// (7,-6),(8,-6) β€” a believable second crossing north of the Old Bridge.
const FIX_CELLS = [
[1, -6], [2, -6], [3, -6], [4, -6], [5, -6], [6, -6],
[7, -6], [8, -6], [9, -6], [10, -6], [11, -6], [12, -6],
];
const FIX_DIAGNOSIS =
"Old Bridge carries 3.1x its capacity at rush; every river crossing funnels into one street cell. A second crossing cuts the index 78 to 41.";
export const FIX_SCRIPT = {
wish_id: "w_demo_fix",
match: "traffic|bridge|jam|congest|road",
events: [
{ at: 0.0, ev: { type: "traffic_alert", name: "Old Bridge" } }, // mock-only event type
{ at: 3.0, ev: { type: "wish_started", wish_id: "w_demo_fix",
text: "Traffic fix β€” Old Bridge is over capacity" } },
{ at: 6.2, ev: { type: "plan", wish_id: "w_demo_fix", plan: {
diagnosis: FIX_DIAGNOSIS,
choice: "F2",
blurb: "Oak Ave opens a second crossing north of the Old Bridge." } } },
{ at: 7.0, ev: { type: "tool_call", wish_id: "w_demo_fix", call_index: 0, tool: "apply_fix",
args: { action: "new_road", cells: FIX_CELLS, klass: "avenue", name: "Oak Ave Bridge" } } },
{ at: 7.3, ev: { type: "world_delta", feature: { id: "e_demo_fix", wish_id: "w_demo_fix",
tool: "apply_fix",
args: { action: "new_road", cells: FIX_CELLS, klass: "avenue", name: "Oak Ave Bridge",
diagnosis: FIX_DIAGNOSIS,
metrics_before: { traffic_index: 78, worst: "Old Bridge" },
metrics_predicted: { traffic_index: 41 } },
seed: 99182554 } } },
{ at: 9.2, ev: { type: "wish_granted", wish_id: "w_demo_fix", epoch: null,
epitaph: "Oak Ave opens a second river crossing β€” bridge load cut nearly in half." } },
],
};