Hangar and battle lifecycle

Account and avatar events select a broad context; view-ready events and page lifecycle hooks own the actual window. These are different responsibilities.

Boundary Recommended responsibility
onAccountShowGUI Select or prepare the lobby context. Do not assume the current main window is already ready.
GUICommonEvent.LOBBY_VIEW_LOADED Create or recreate the hangar overlay against the current loaded lobby main window.
onAvatarBecomePlayer Select battle context and invalidate stale lobby-owned state. Do not create against the possibly still-loaded lobby parent.
Battle shared page _populate After the original method, create the battle overlay against the populated battle main window.
Battle shared page _dispose Destroy the battle overlay before the page and parent are released.
onAccountBecomeNonPlayer Remove state that no longer belongs to the account context.
onDisconnected Destroy windows, advance generation tokens, and cancel pending work.

Composable page hooks

Wrap page _populate and _dispose only when needed, call the previously installed method exactly once, and restore only a wrapper still owned by the mod. Public player events own context; page hooks own the actual parent-view lifetime.

Lobby route visibility

An active account entity means the client is somewhere in the lobby, not necessarily on the normal tank garage page. A garage-only overlay should follow the lobby state machine's visible route.

  • Subscribe to the current lobby state machine's visible-route change event after the lobby is ready. In current builds this may be exposed as onVisibleRouteChanged.
  • Show the window only when the visible state is the registered normal hangar state, commonly represented by DefaultHangarState.
  • Optionally recognize a legacy hangar state, such as LegacyHangarState, only when that mode is actually supported by the target build.
  • Hide it in loadout, all-vehicles, store, missions, and other lobby routes even though the account is still in the lobby.
  • Unsubscribe on battle entry, disconnect, and finalization.

State classes, event names, and module paths are private and version-sensitive. Verify the current client and keep a graceful fallback that hides the feature when the expected route contract is unavailable.

Replay rewind and time-warp recovery

A replay seek can rebuild battle entities, controllers, pages, and UI without reproducing the normal live-battle event order. Treat rewind as a separate lifecycle boundary rather than assuming ordinary battle startup will repair the feature.

  • At rewind start, cancel owned callbacks and animation loops, clear stale entity and controller references, and mark the current UI generation invalid.
  • Destroy raw roots or child views whose normal owner may disappear without running its usual teardown.
  • At rewind finish, defer recovery to the next client callback, then reacquire the current battle page, parent window, model, and player entity.
  • Rebuild model data from authoritative replay-visible state; do not reuse cached live entity objects.
  • Make repeated forward and backward seeks converge to one window, one child view, one listener set, and one callback loop.
  • Preserve disabled or hidden state. Recovery must not force-enable a feature that was off before the seek.
  • Verify one seek, repeated seeks, pause/resume, seek while hidden, and normal playback separately.