Structures stand on a city's open ground, and the drawn land matches where they can stand #137
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "task/3558-build-inside-the-city-and-a-flat-map"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tracker: #3558
Players build where the ground looks buildable. A structure may stand on a city's ground, on any open tile that is not a street, a standing building's plot, or the monument's block (its tile and 8 capture cells). The server, the client's placement ghost and the AI all call one shared rule in
src/shared, and that rule also names which units hold a tile: a live unit that is not an aircraft. Cities grow around what stands there. The drawn ground matches the rule: no tile that refuses a structure draws as open land, and every drawn land layer keeps off the water.What the plan delivers
SiteRefusalor null: off the map, terrain, a unit, a street, a plot, the monument's block, or beyond reach. A city's open ground no longer refuses.Game.placeBuilding, the ghost, the AI and the towns bench all call it.clearOfCities,canPlaceFootprintand the replica'snearCity/clearOfCitiesare removed.placeNearAnchorand the net bench's churn case rank with every city. The AI ranks with every city too, so it keeps off every city's ground, its own, neutral or enemy, when its search ring has another site, and takes a city's open ground only when it has none.placeNearAnchor, the churn case and the AI fell trees only where their search offers no tree-free site.Every refusal on main, and what becomes of it
Decisions taken on their recommended answers (Agra may override)
Acceptance walk
Walked on this branch at
de104c3(main672fc28), on runner s32, 2026-10-24.siteRefusal/siteOpenin src/shared/site.ts are called byGame.placeBuildingandplacePreferred, by the ghost per cell and its commit (pointer.ts), by the AI'ssiteNearthroughbrainSite, and by the towns bench'sfactorySite.clearOfCities,canPlaceFootprintand the replica'snearCity/clearOfCitiesno longer exist.knownSitethe AI reads). It covered every origin, for each of the six structure types and both players, with a Gunship hovering over a city tile and a Medium spawned beside it. All 9,604 origins agree, before and afterpack/unpack. Red sees 80 open city tiles. The Gunship's tile stays open after the load, and the Medium's tile refuses as Held.placeBuildingon both home cities' open ground. Over 300 growth steps the cities grew 12 → 309 and 7 → 287 people, with nothing laid on the structures' 11 tiles. Without the structures, 11 of those 12 tiles got streets or plots.npm run towns -- --json, head against main: 20 of its 22 rows are identical, bad, bare and stalled home towns included. In the other two, "No Factory site at founding" falls from 5 to 0 of 2,370 towns at Lakes 0.9 and from 7 to 0 at Lakes 1, because a city's open ground and its trees now take a Factory.&gridof the street, woods and highway coast views at 1× and 0.5× in all four finishes, plus 1× and 0.5× against main: 40 loads with no page error.siteRefusalanswers each closed row's kind, and none for a city's open ground, a Tree tile or a tile under an aircraft. The capture cells draw paved (layer.test.ts, city-layers.test.ts), and the reach draws dimmed while placing (reach.test.ts, map.phone.ts).The 14 seeded AI matches (small 1–6 with 2 seats, medium 1–4 with 3, large 1–4 with 4) all run to their end against main's. Six end on a winner, the rest at the time limit, each with the same end as main's. 11 traces are identical to main's; medium-1, medium-2 and large-3 differ.
npm run bench(seed 11, wan): battle, economy and cities at 128 and 256 are identical to main's in every hash and byte. Churn stays within 2% for every client's raw and deflated bytes a second, the largest move being churn-128 p0 deflated −1.85%. That delta comes only from the remote players skipping the tries that the shared preference ranks below their best site, tries main's server refused. A copy of the head's bench that sends each skipped try as a refused off-map placement matches main exactly in churn-128 and churn-256: frame hash, game hash, 650 and 517 commands, and every client's raw and deflated bytes.The island's rebuild, in the Shore yard in Playwright WebKit (iPhone 15 landscape), 5 sessions of 7 interleaved runs per arm: main 25.47 ms (head's shore.ts over main's modules), head 20.53 ms. The paired delta is −4.93 ms, under main and inside the 2.2 ms budget.
The Map Yard bench by the standing method: 5 sessions of 7 interleaved runs, 10 arms (main and head at rest, plus each one's
?doom=battle,?doom=battle&spare,?doom=nukeand?doom=nuke&spare), 1,050 pages with no page error. Paired medians in ms a frame, with the phone estimate at 7.5×:At rest the head draws the same calls as main (67, 65 and 41) and fewer triangles (343,124 against 345,538 at 1×). Every session's at-rest delta lay within 0.03 ms of these. The plan leaves the destruction peaks' cost over their spare arms where main has it: head against main, −0.040 to +0.003 ms.
Game's state and the world are unchanged, so MAP_VERSION stays 19. changelog.md's Current has a bullet for each step, and the help's Build line and its Cities and Building sections say where a structure stands, that it fells trees, and that the reach dims. No Current bullet or help line still says structures stand off a city's ground.sak-gate fullonde104c3failed innpm testsix times, each only on vitest's 5000 ms timeout in the same heavy tests, while other runs and a browser tab loaded s32:git archiveof672fc28at 02:51 in the same window, failed the same way: craft's two-gunship landing test timed out, 838/839 in 48.8 s.de104c3(vitest run --mode phone), passed 180/180 in 208 s, the Map Yard coast, doom, placing and rebuild checks included.fullon this same tree (c035227) on s32 at 01:15: 895/895 in 31.0 s, then phone 180/180.fullgate on a quiet runner settles it.fullonde104c3(run 439, s32): its gate run 1 (02:56) failednpm test894/895 in 34.1 s, only on craft's "lands two gunships on their helipad in turn" at 5000 ms, a test that takes 1.50 s alone (1.52 s on main). Its gate run 2 (03:22–03:26), started on a quiet runner at a one-minute load of 1.9, passed:npm test895/895 in 32.8 s,test:phone180/180 in 197.5 s.fullonde104c3(gate run 1, 03:33–03:37 on s32, started at a one-minute load of 1.4) passed:npm test895/895 in 28.4 s,test:phone180/180 in 199.8 s.Checks
fullgate.npm run benchwithin 5% of main in the default case and in the economy, cities and churn cases, which place structures near home towns.npm run townsand the traffic bounds hold, and step 1'snpm run towns -- --jsonrows match main's.landLoops,buildSurface, the shore field and one render on a known 256² map in WebKit.Structures stand on a city's open ground, and the drawn land matches where they can standto Tracker: [#3558](https://sak.swipelab.com/tasks/3558)Tracker: [#3558](https://sak.swipelab.com/tasks/3558)to Structures stand on a city's open ground, and the drawn land matches where they can stand