development → staging - #748
Merged
Merged
Conversation
…entre Map.tsx's walker animation loop rebuilt the entire GeoJSON source (buildings/roads/fields/boundaries) every 16ms even though only character positions change per frame. Split buildVillageSourceData into buildStaticVillageFeatures (memoized, rebuilt only when features change) and buildCharacterPointFeatures (per-frame). The animation loop is now also gated on there actually being walking characters, instead of running unconditionally. Separately, useMap.ts's initial-camera logic assumed a single seeded village and picked "the first population centre" from the full population-centres list, which is now stale with multiple villages imported from locations/data/. Added a lightweight InitialMapCentreView (/map/initial-centre/) that returns just enough (id/name/bbox) to frame the camera, preferring the population centre of the requesting player's actively linked character (Player.active_link) and falling back to the lowest-pk centre otherwise. Frontend now fetches this cheaply before the bbox-scoped viewport poll takes over as the source of truth. Backend: locations/tests/test_initial_map_centre_view.py (3 tests). Frontend: MapPage.test.tsx updated for the new fetchInitialMapCentre mock; also fixed a flaky prefetch effect that used a dynamic import() for fetchPopulationCentreMap, which could race and skip the vi.mock when prefetching two different villages concurrently - now a normal static import.
Watabou's village generator can export a "squares" MultiPolygon (open outside communal space, e.g. a market square/plaza) that import_watabou_village previously ignored entirely, like "greens" and "prisms" still are. Add a "square" Subzone.usage choice and a _import_squares helper (watabou_import.py) that imports it the same way _import_fields already imports "fields" - one LandArea wrapping the union of the polygons, one Subzone per polygon - refactored the shared logic into _import_polygon_subzones. Unlike a crops Subzone, a square has no FieldCrop growth cycle or other economy behaviour attached; it's purely a map feature. Wire it into both map views (PopulationCentreMapView, MapViewportView): they now query Subzone with usage__in=["crops", "square"] instead of usage="crops" alone, since SubzoneFeatureSerializer already returns None for every crop_* field when there's no attached FieldCrop. Frontend: styledPolygonFeatures gives usage="square" subzones a distinct warm/paved fill (geojson.tsx) instead of falling through to the crops-green/building-grey styling, and the tooltip labels them "Square" instead of the raw bookkeeping name.
When --x/--y are omitted, import_village now picks the first VILLAGE_LAYOUT slot with no existing PopulationCentre on it, instead of requiring coordinates to be hand-picked. Passing only one of --x/--y now raises a clear CommandError instead of silently doing something unintended. This lets ad-hoc imports outside the setup_world/import_villages pipeline (e.g. trying out a village file not in locations/data/) claim spare grid space without colliding with the pipeline's own slots - though it's not persistent across a setup_world rerun, which wipes and reimports only locations/data/'s contents. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C6BX7dFJWn2xMYn9qggdos
GameContext now primes useInitialMapCentre's and useMapWorldBounds's
query cache entries as soon as fetch_info resolves, instead of only
firing them once the player navigates to the map page. Both are
cheap, one-shot fetches, so warming them at login lets MapPage skip a
network round-trip on mount for players who go on to open it.
Extracted the {queryKey, queryFn, staleTime, gcTime} for each into
exported query-option objects in useMap.ts, reused by both the hooks
and GameContext's prefetch, so the two can't drift onto different
cache keys.
Deliberately doesn't prefetch /map/viewport/: it needs a bbox only the
mounted map component can produce, and starts a 2s poll once enabled -
prefetching it at login would poll map data in the background for
every session regardless of whether the player ever opens the map.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6BX7dFJWn2xMYn9qggdos
…al-centre perf: stop rebuilding map source per frame, fix stale initial centre, prefetch at login
feat: import watabou "squares" as communal-space Subzones
feat: auto-pick an unused village_layout slot for import_village
# Conflicts: # frontend/src/pages/MapPage/MapPage.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User-visible improvements (UVIs)
Features
Fixes and UX improvements
Developer experience and quality
import_villagenow auto-picks an unused layout slot instead of requiring one to be specified manuallyTechnical notes
No migrations or env var changes. Map rendering now only rebuilds the changed GeoJSON source instead of the whole map source per frame. Initial-centre and world-bounds map data are now prefetched right after login.
Test plan