The Southland gets a door, and the people in it move
**Mateo Court**, a courtyard block in the Arts District — a third pack and a third *kind* of building. Two office floors and a shed already existed, so this is the plan the format had not been shown: a ring of rooms round an open-air yard with **no corridor anywhere**. Every door opens onto the yard, and the yard does the job a corridor does in the other two. It is also the first pack whose `ceiling: null` means there is genuinely no ceiling at any height rather than "take the lid off so the shot can see in", and the first sited off the Bay Area board at all. That last part needed a fix, not just a coordinate. `OFFICE_MARKERS` was gated on `id === "sf"`, which was correct for exactly as long as every office was in the Bay Area — it would have kept the Los Angeles building off the Los Angeles board and pinned it to San Francisco's. The gate is the board's own bounds now, which is the same question asked honestly. Every door through the 0.25 m courtyard skin is 1.2 m rather than the usual 0.9, and that is not a style choice: `blocked` inflates by the walker's radius *and* the wall's thickness, so a 0.9 m leaf through a wall that thick seals the room behind it while rendering perfectly. Two rooms were sealed exactly that way on the first pass. The test says so, because a well-meaning edit back to 0.9 for consistency would do it again. **People move.** `samplePresenceAt` thinned the roster by hour, which fixed a building that was full at 1 a.m., but everybody was still pinned to their own desk all day. Occupancy is a hand-written booking table now: meetings fill a room for a plausible length, the kitchen island fills at lunch, and a `Presence` binds to a seat id — so "in a meeting" means occupying a meeting-room seat, and the whole thing is choosing seat ids rather than inventing positions. The flood fill that checks a pack is walkable existed three times over. One copy now, since the third is where a divergence lives. **Films.** A new `office-dusk` reel — six hours over Lumbridge HQ catching the moment the house lights take over from the sun, which is the one thing only a time-lapse can show and which did not exist. The three existing reels are re-rendered rather than re-captioned: `films.ts` in v4 named a commit eleven behind HEAD, so the published reels were shot before there were any clouds and before the city drew office pins. Reviewers caught roughly a dozen false statements in the new prose across these files — a room census that did not add up, a wall-thickness count, a claim that every room has daylight when one does not, and a cost figure saying `updateSun` runs once a second when it runs once a minute. The consequential ones are fixed. In a codebase where the comments are the design record, a confident wrong number is a defect. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-6
@@ -101,6 +101,7 @@ const CITIES: { id: string; label: string; city: City }[] = [
|
||||
const OFFICES: { id: string; label: string; load: () => Promise<{ default: Office }> }[] = [
|
||||
{ id: "lumbridge-hq", label: "Lumbridge HQ", load: () => import("./offices/lumbridge-hq.ts") },
|
||||
{ id: "frontier-valley", label: "Frontier Valley", load: () => import("./offices/frontier-valley.ts") },
|
||||
{ id: "mateo-court", label: "Mateo Court", load: () => import("./offices/mateo-court.ts") },
|
||||
];
|
||||
|
||||
const canvas = document.querySelector<HTMLCanvasElement>("#scene");
|
||||
@@ -817,11 +818,28 @@ async function mountCity(id: string) {
|
||||
// not a decoration. LA gets its own weather, not San Francisco's fog.
|
||||
marineLayer: id === "sf" ? PACIFIC_MARINE_LAYER : null,
|
||||
});
|
||||
// The offices are in the Bay Area, so they ride along with that board's
|
||||
// markers and are absent from the Southland's — the same rule the sample set
|
||||
// already follows, for the same reason: a pin for a building six hundred
|
||||
// kilometres off the board is a pin in the wrong place.
|
||||
city.setMarkers(id === "sf" ? [...markers, ...OFFICE_MARKERS] : []);
|
||||
/**
|
||||
* A door belongs to the board it stands on.
|
||||
*
|
||||
* The gate here used to be `id === "sf"`, which was correct for exactly as
|
||||
* long as every office was in the Bay Area. It stopped being correct the
|
||||
* moment one was not: a hard-coded city id would have kept the Los Angeles
|
||||
* building off the Los Angeles board and pinned it to San Francisco's.
|
||||
*
|
||||
* So the test is the board's own bounds, which is the same question asked
|
||||
* honestly — a pin for a building outside the rectangle being drawn is a pin
|
||||
* in the wrong place, whichever city that happens to be. The sample company
|
||||
* markers stay SF-only; they are sample data about one city and always were.
|
||||
*/
|
||||
const bounds = entry.city.bounds;
|
||||
const doors = OFFICE_MARKERS.filter(
|
||||
(m) =>
|
||||
m.lat >= bounds.minLat &&
|
||||
m.lat <= bounds.maxLat &&
|
||||
m.lng >= bounds.minLng &&
|
||||
m.lng <= bounds.maxLng,
|
||||
);
|
||||
city.setMarkers(id === "sf" ? [...markers, ...doors] : doors);
|
||||
city.onChapterChange(() => renderLegend());
|
||||
|
||||
/**
|
||||
@@ -871,7 +889,7 @@ async function mountCity(id: string) {
|
||||
},
|
||||
});
|
||||
showPlan();
|
||||
minimap.setMarkers(id === "sf" ? [...markers, ...OFFICE_MARKERS] : []);
|
||||
minimap.setMarkers(id === "sf" ? [...markers, ...doors] : doors);
|
||||
|
||||
// The instruments, for the one visitor in a deployment who has them. The pose
|
||||
// editor holds a `World`, a camera and a controls, so it belongs to the board
|
||||
|
||||
Reference in New Issue
Block a user