D4 CLOSED with a fix: 8/108 gig plans placed a spine poster inside a NON-nearest edge's carriageway (worst 1.78m inside a main, northbridge seed 42, behind a kerbless arcade at 1.45m) — the exact filing, reproduced before touching anything. gigs.js onCarriageway now tests inside-ANY-edge; selfcheck's poster arm asserts minimum clearance over ALL edges. After: 0/108. Poster counts 0 diffs across all 108 plans; synthetic byte-identical. The 7 REAL_TOWN_GIG_GOLDENS re-pinned (D4 explicitly required it; old hashes in comments). D1 A-side CLOSED: chunkIndexByCoverage is canonical (chunkIndex kept as verified alias); the naive swap would multi-build 258/681 lots — measured, documented in CITY_SPEC. D2 RE-FILED to F (isOpen still 0 importers; divergent predicate at index.html:541). D3 RE-FILED to B (SHOP_REGISTRY missing pub/band_room/rsl; 81 venue lots wear op-shop signage; bite drifted to buildings.js:465). Both re-filings carry numbers and a reason. selfcheck ALL GREEN 157,647/157,647; fingerprint 0x5f76e76 and GIG_GOLDEN frozen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
3.3 KiB
JavaScript
45 lines
3.3 KiB
JavaScript
// PROCITY citygen — canonical Lane A public entry point (barrel).
|
||
//
|
||
// Consumers import the whole CityGen API from here (not from plan.js directly), e.g. Lane B's shell:
|
||
// const citygen = await import('./js/citygen/index.js'); citygen.generatePlan(seed) → CityPlan
|
||
// Keep this the stable import surface for the lane; internals may move between files behind it.
|
||
//
|
||
// (Originated as a Lane F integration shim because the shell imports ./js/citygen/index.js while the
|
||
// generator ships as plan.js; adopted here as the real Lane A entry point, per the shim's own note.)
|
||
|
||
// R40 (§40.2 D1): `chunkIndexByCoverage` is the canonical name — AABB-coverage bucketing, plain-object
|
||
// container, id elements; answers "which cells does this thing touch?". It is NOT shape-compatible with
|
||
// Lane B's runtime `world/planutil.js chunkIndex(plan)` (centre-cell / Map / objects — the streamer's
|
||
// question). `chunkIndex` remains as a compat alias of the coverage form for existing importers.
|
||
export { generatePlan, chunkIndexByCoverage, chunkIndex, chunkKey, CHUNK, lotCorners, obbOverlap, isOpen } from './plan.js';
|
||
export { shopName, townName, bandName } from './names.js';
|
||
export { generatePlanOSM, osmTownKeys, registerTownCache, getTownCache, validateTownCache, MIN_TOWN_SHOPS,
|
||
medianShopSpacing, MAX_MEDIAN_SPACING_M } from './plan_osm.js';
|
||
export { withGigs, gigKeyFor, POSTER_CLEAR } from './gigs.js';
|
||
// v9 THE ADDRESS LAYER (ROUND39 item 39.1). Pure, no THREE, no fetch, no plan mutation — it derives
|
||
// from a plan and never writes to one, so it cannot move a golden. ONE consumer contract across both
|
||
// town types: print `localityOf(shopId).label`, never branch on `plan.source`. Full contract in the
|
||
// header of address.js and in LANE_A_NOTES §39.
|
||
export { createAddresses, STREET_TOLERANCE_M } from './address.js';
|
||
// The street-corridor law + venue vocabulary, re-exported so consumers get the whole Lane A contract
|
||
// from one import (ROUND13). `roadWidth`/`vergeBand`/`poleOffset` are the road-vs-verge split of
|
||
// `edge.width` — see the note in registry.js; `gigKeyFor` is the one and only genre→audio-key mapping.
|
||
export { SHOP_TYPES, VENUE_KINDS, genreForVenueKind, roadWidth, vergeBand, poleOffset } from '../core/registry.js';
|
||
|
||
// planSource selector (round 6; multi-town round 8). Default 'synthetic' → the byte-identical
|
||
// golden-hash generator; 'osm' → the real-data fixture importer. Lane F wires ?plansrc=osm (+ optional
|
||
// &town=<key>) to these args so the shell bootstrap picks the producer/town without B–F caring which
|
||
// ran. Unknown source → synthetic; unknown town → the default town.
|
||
import { generatePlan as _synth } from './plan.js';
|
||
import { generatePlanOSM as _osm } from './plan_osm.js';
|
||
import { withGigs as _withGigs } from './gigs.js';
|
||
export function generatePlanFor(seed, source = 'synthetic', opts = {}) {
|
||
const plan = source === 'osm' ? _osm(seed, opts.town, opts) : _synth(seed);
|
||
// v3 gig layer, gated: ?gigs=1 → shell passes { gigs:true, customBands } and we augment; otherwise
|
||
// the base plan is returned untouched (byte-identical, goldens frozen — CITY_SPEC prime flag law).
|
||
return opts.gigs ? _withGigs(plan, seed, opts) : plan;
|
||
}
|
||
|
||
// Convenience default so `citygen.default` also resolves to the (synthetic) generator.
|
||
export { generatePlan as default } from './plan.js';
|