Something went wrong. Try again.
A video game where you play as a misaligned AI, deceiving and building power. cameron.tngl.io/misaligned
Something went wrong. Try again.
4.9 kB · 74 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475// The big world, for measuring speed only: today's map with every site but the office copied into the empty// regions (South America, Africa, South Asia, then Oceania), about four times the machines. It is not a map to// play: the copies have no people, no big names and no deals. Plain data, no Node: the browser builds it too// (see ?perf in main.ts), and scripts/perf-saves.ts makes a late game on it.import { BUILDING, type Level, type MachineDef, type Room, type Site } from '../src/world.ts';
/** How many copies of the world the big level has, and where each goes: a region, its middle in longitude and * latitude, its clock, and the exchange of today's map its copy of the Mudflat Exchange is wired to. */export const COPIES = 3;const PLACES: { region: string; at: [number, number]; zone: number; join: string }[] = [ { region: 'South America', at: [-60, -12], zone: 4, join: 'ixgw' }, { region: 'Africa', at: [20, 5], zone: 9, join: 'eu1gw' }, { region: 'South Asia', at: [78, 22], zone: 12, join: 'as1gw' }, { region: 'Oceania', at: [134, -25], zone: 17, join: 'as1gw' },];/** A copy's id for a machine, room or site of today's map. A prefix, so the digits a hall slot ends in stay last. */export const copyId = (id: string, k: number) => `z${k + 1}_${id}`;/** Where copy k of a region's sites goes on the map: how far to move them. Today's West Coast (less the office) goes * to the left of the region's middle; the far regions' sites stack on its right. */function shifts(level: Level, k: number): Record<string, [number, number]> { const { scale, origin: [lon0, lat0] } = level.map, [lon, lat] = PLACES[k].at; const cx = (lon - lon0) * scale, cy = (lat0 - lat) * scale; const box: Record<string, [number, number]> = {}; for (const s of level.map.sites) if (s.id !== 'office') { const b = box[s.region]; box[s.region] = b ? [Math.min(b[0], s.x), Math.min(b[1], s.y)] : [s.x, s.y]; } const to: Record<string, [number, number]> = { 'West Coast': [cx - 9500, cy - 4000], 'East Coast': [cx + 1500, cy - 4000], Europe: [cx + 1500, cy - 1200], 'East Asia': [cx + 4500, cy - 4000] }; return Object.fromEntries(Object.entries(box).map(([r, [x, y]]) => [r, [Math.round(to[r][0] - x), Math.round(to[r][1] - y)]]));}/** How far a copy's rooms move in the building, where no one walks: far past every room of today's map. */const BUILDING_SHIFT = 300000;
let big: Level | null = null;/** The big level: today's map and COPIES copies of it. Made once. */export function bigLevel(): Level { if (big) return big; const L = BUILDING; const rooms: Room[] = [...L.rooms], machines: MachineDef[] = [...L.machines], links: [string, string][] = [...L.links], sites: Site[] = [...L.map.sites]; const subnets = { ...L.net.subnets }, nodes = { ...L.net.nodes }; const siteOfRoom = new Map(L.rooms.map(r => [r.id, r.site ?? 'office'])); const regionOf = new Map(L.map.sites.map(s => [s.id, s.region])); const copied = new Set(L.machines.filter(m => siteOfRoom.get(m.room) !== 'office').map(m => m.id)); const regions = L.map.regions.map(r => ({ ...r })); for (let k = 0; k < COPIES; k++) { const P = PLACES[k], move = shifts(L, k), bx = BUILDING_SHIFT * (k + 1); const at = (site: string) => move[regionOf.get(site)!]; for (const s of L.map.sites) if (s.id !== 'office') { const [dx, dy] = at(s.id); sites.push({ ...s, id: copyId(s.id, k), x: s.x + dx, y: s.y + dy, rooms: s.rooms.map(r => copyId(r, k)), region: P.region }); } for (const r of L.rooms) if (r.site) { const [dx, dy] = at(r.site), sub = L.net.subnets[r.id]; rooms.push({ ...r, id: copyId(r.id, k), site: copyId(r.site, k), x: r.x + bx, door: [r.door[0] + bx, r.door[1]] }); if (sub) subnets[copyId(r.id, k)] = { ...sub, x: sub.x + dx, y: sub.y + dy }; } for (const m of L.machines) if (copied.has(m.id)) { const [dx, dy] = at(siteOfRoom.get(m.room)!), [nx, ny] = L.net.nodes[m.id]; machines.push({ ...m, id: copyId(m.id, k), room: copyId(m.room, k), x: m.x + bx }); nodes[copyId(m.id, k)] = [nx + dx, ny + dy]; } for (const [a, b] of L.links) if (copied.has(a) && copied.has(b)) links.push([copyId(a, k), copyId(b, k)]); // the lines a deal lights between today's regions are lit from the start in a copy, and its exchange is wired to today's map for (const r of L.map.regions) for (const [a, b] of r.lines ?? []) links.push([copyId(a, k), copyId(b, k)]); links.push([copyId('ixgw', k), P.join]); const reg = regions.find(r => r.name === P.region)!; reg.reachable = true; reg.zone = P.zone; } big = { ...L, name: 'The big world (for measuring speed)', rooms, machines, links, net: { ...L.net, subnets, nodes }, map: { ...L.map, sites, regions } }; return big;}
/** The level each benchmark save is played on. */export const levelFor = (name: string): Level => name === 'big' ? bigLevel() : BUILDING;