Skip to content

ADR-050 — Tiangong Explorer low-end fallback (?view=list + heuristics)

Status · Accepted Date · 2026-05-07 Closes · RFC-014 (with ADR-048, ADR-049) TA anchor · §components Related · ADR-042 (the ISS analogue, copied verbatim), ADR-025 (accessibility), PRD-011

Context

RFC-014 OQ-3 requires a non-WebGL path and automatic degradation on weak devices for /tiangong. The decision mirrors ADR-042 verbatim — same detection rules, same URL override, same single-reactive-viewMode UX.

Decision

URL override

?view=list forces list mode: alphabetical module + visitor list, same src/lib/components/StationModulePanel.svelte content (the renamed/generalised panel — see Phase E of the rollout plan). No WebGL initialisation — no THREE.WebGLRenderer, no proxy build.

Auto-fallback

After 3D mode starts, measure FPS for ~2 s via requestAnimationFrame deltas. If sustained < 20 fps, switch to list mode and dispose renderer, scene, and module group geometry.

If navigator.deviceMemory is defined and < 4, skip 3D and open in list mode immediately (Chrome/Android hint).

If WebGL context creation fails, list mode.

UX

Single reactive viewMode: '3d' | 'list' — same flicker-avoidance discipline as /iss: decide mode before first paint when URL/device hints demand list, otherwise fall through to 3D.

Toggle

HUD control syncs URL (view search param) so shareable links reproduce mode.

Consequences

Positive: Accessibility + low-end coverage without maintaining two full feature sets. Identical fallback contract across /iss and /tiangong reduces test surface.

Negative: navigator.deviceMemory is non-standard — treated as optional signal only.

Implementation notes

FPS sampler runs only when viewMode === '3d' after buildTiangongProxyStation() returns. Disposal path mirrors the ISS stopThree() helper.

Orrery — architecture documentation · MIT · No tracking