This atlas's Widget Tree doc covered the framework a map view lives inside. This is what's inside it: one renderer that never knows whether it's drawing a normal frame, a hero mid-step, a fading object, or the puzzle screen — because it never asks. It asks a context object instead, and something else decides which context is listening.
MapView is an ordinary widget first. Everything in this doc happens underneath that.
class MapView : public BasicMapView, and class BasicMapView : public CIntObject — confirmed directly in MapView.h. It's built, activated, and shown the exact way Widget Tree already traced for any other widget; a second subclass, PuzzleMapView, reuses the identical base for the downscaled obelisk-puzzle screen. Three collaborators sit behind that one widget: MapViewModel is nothing but camera state (tile size, view center, viewport dimensions, current level — converting between map coordinates and screen pixels); MapViewCache holds the composited tile surfaces so a static frame doesn't get redrawn from scratch; and MapViewController is where the actual behavior lives.
MapRenderer composites a tile from up to eight named layers — terrain, river, road, border, fog, objects, overlay, path — and every one of those layer renderers takes the same single argument to find out what to draw: an IMapRendererContext&.
IMapRendererContext implementations exist; exactly one is active at a time, held by MapViewController in a plain context pointer. Asking for an object's transparency means one thing under FadingContext and another under AdventureContext, but MapRenderer never has an if for it — it just calls context.objectTransparency(id, coordinates) and draws whatever comes back. The same shape this atlas keeps finding under different names: swap the object answering the questions, not the code asking them.A hero's single step, the one thing Where Requests Land found CGameHandler handling inline, lands here as MapViewController::onHeroMoved() — and it doesn't just start an animation. It blocks on one.
movementContext = make_shared<MapRendererAdventureMovingContext>(*state), tracking tileFrom/tileDest/progress
a ConditionalWait, flipped busy the instant the animation starts
the calling thread checks this and, if busy, calls waitForOngoingAnimations() — a real block, not a poll
each frame nudges progress until the step completes, then the wait is released
settings["adventure"]["heroMoveTime"] for the player's own hero, "enemyMoveTime" for anyone else's — and if either is configured at or below one, the step is instant, no context swap, no wait, straight to addObject() at the new tile.This is the same instinct Wire Protocol found in battle — BattleStacksController starting an attack animation against a stack's pre-hit HP, so damage and motion don't land in the same instant — except here the wait is explicit and named. Whatever thread is driving pack processing genuinely pauses at waitForOngoingAnimations() until the walk finishes on screen; the next pack in the queue simply doesn't get processed until this one has visibly happened.
Fog of war and "whose hero is this" look like rendering concerns. Neither is decided here.
MapRendererBaseContext::isVisible(coordinates) — the method every layer renderer calls before drawing anything on a tile — is one line: GAME->interface()->cb->isVisible(coordinates). That's Asking the Game's read-side callback, itself just a local cache kept in sync by the FoWChange packs Wire Protocol already catalogued. The renderer doesn't track fog; it asks. isActiveHero() is the same shape one level down — it checks GAME->interface()->localState->getCurrentHero(), the client-only, never-broadcast memory Widget Tree's PlayerLocalState finding already named. Both questions a tile-drawing routine needs answered were already answered elsewhere in this atlas; nothing in mapView/ re-derives them.
One older piece sits underneath all of this: CMapHandler (lowercase file, an earlier naming generation than its PascalCase siblings) does nothing but fan a hero-move or object-visibility event out to a list of IMapObjectObserver* — MapViewController is one such observer, registered once and left to react. It's a plain broadcaster, not a second copy of any logic covered above.