Use the AeroSim technology stack
Use this reference when planning or implementing AeroSim. It records the engineering decisions provided by RootAtSkic on 2026-08-26 and the resulting terrain and 3D asset analysis. Keep architecture decisions, implementation tasks, dependency versions, asset provenance, and deployed-runtime evidence synchronized as the project advances.
Decision summary
| Area | Final decision | Status |
|---|---|---|
| Frontend application | Nebula: React, Vite, Stardust, and TypeScript | Selected |
| Backend service | Singularity: Fastify and TypeScript | Selected |
| Real-time transport | Socket.IO with shared typed contracts | Selected |
| 3D runtime | Three.js with React Three Fiber | Selected |
| Physics | Rapier with @react-three/rapier | Selected |
| VR and AR | WebXR with @react-three/xr | Selected |
| Terrain runtime | Heightmap-driven Three.js terrain with physics derived from the same normalized height data | Selected |
| Initial terrain source | 3DTexel free CC0 heightmaps and backdrops | Selected for curated assets |
| Generated terrain source | 3D Map Generator heightmaps | Selected for intentional real-world areas |
| Runtime model format | glTF 2.0, preferably binary .glb | Selected |
| Primary reusable asset source | Poly Haven | Selected |
| Secondary reusable asset source | Sketchfab assets that pass per-asset license review | Conditional |
| Additional asset source | Blendkit assets that pass per-asset license, provenance, and format review | Evaluation only |
Nebula frontend
Nebula is AeroSim's vibrant frontend layer. It uses Vite for fast local development and optimized production builds, while supporting immersive 3D, physics, and XR experiences.
| Concern | Technology | Keep in mind |
|---|---|---|
| Framework | React with Vite | Keep browser-only simulation code out of server-side assumptions and preserve optimized production builds. |
| UI library | Stardust, custom built | Treat Stardust as the shared visual-system boundary; avoid duplicating primitives inside feature code. |
| Language | TypeScript | Keep strict types across UI state, simulation state, events, and shared contracts. |
| Real-time communication | Socket.IO | Share typed event contracts with Singularity and define reconnect, ordering, and error behavior. |
| 3D rendering | Three.js and React Three Fiber | Keep low-level Three.js access isolated when React Three Fiber can own the scene lifecycle. |
| Physics | Rapier and @react-three/rapier | Use a deterministic simulation step and define ownership of transforms between rendering and physics. |
| VR and AR | WebXR and @react-three/xr | Treat XR as capability-dependent progressive enhancement and preserve a usable non-XR path. |
| Testing | Vitest and React Testing Library | Test user-visible behavior and component contracts; isolate rendering, physics, and browser API boundaries where needed. |
Nebula engineering considerations
- Define clear boundaries between interface state, scene state, and physics state.
- Budget frame time and memory for representative scenes rather than relying only on desktop development hardware.
- Handle WebGL, WebXR, controller, and device capability differences explicitly.
- Keep Socket.IO event handling independent from rendering frame rate.
- Keep Stardust components sharp and consistent with the project's zero-radius visual direction.
Singularity backend
Singularity is AeroSim's backend service. It uses Fastify for lightweight, scalable APIs and owns core business logic, persistence, data processing, and integrations.
| Concern | Technology | Keep in mind |
|---|---|---|
| Framework | Fastify | Organize routes and plugins by responsibility; validate inputs and outputs at service boundaries. |
| Language | TypeScript | Share stable contracts without coupling backend internals to frontend implementation details. |
| Database | PostgreSQL | Model transactions, indexing, migrations, retention, and recovery before production data depends on them. |
| ORM | Prisma | Review generated migrations, keep schema changes reproducible, and avoid hiding performance-sensitive queries. |
| Real-time communication | Socket.IO | Authorize connections and events, define room ownership, and plan horizontal scaling before adding replicas. |
| Testing | Vitest | Cover business logic, Fastify route contracts, persistence integration, migrations, and real-time event behavior. |
Singularity engineering considerations
- Keep transport handlers thin and place business rules in testable modules.
- Use Fastify schemas for runtime validation and API documentation where applicable.
- Define one authoritative contract for each HTTP payload and Socket.IO event.
- Treat Prisma migrations as reviewed source artifacts and verify them against PostgreSQL in CI.
- Plan connection pooling, backpressure, rate limits, authentication, authorization, observability, and graceful shutdown.
- Separate unit tests from PostgreSQL and Socket.IO integration tests so failures identify the affected boundary.
Terrain and spatial environments
A heightmap is a practical input for rebuilding spatial terrain in Nebula. Three.js displacement maps reposition mesh vertices from image values, so the same grayscale elevation data can shape a sufficiently subdivided terrain mesh.[8]
Selected terrain pipeline
- Acquire a curated or generated heightmap.
- Preserve the source file, source URL, license, geographic meaning, bit depth, and checksum in the asset registry.
- Normalize horizontal extent, vertical scale, coordinate system, and no-data behavior during an offline import step.
- Produce optimized terrain tiles, material inputs, and level-of-detail metadata for Nebula.
- Derive Rapier collision data from the same normalized height field rather than from a separate hand-authored approximation.
- Verify visual and collision alignment, tile seams, frame time, memory, and XR comfort before release.
Selected heightmap sources
3DTexel is the initial curated source. Its free landscape collection provides 16-bit PNG terrain heightmaps and backdrop textures under CC0; the page distinguishes those free assets from paid assets governed by a separate 3DTexel license.[1] Only assets explicitly marked free and CC0 enter the default AeroSim pipeline.
3D Map Generator is the generation option. Its browser tool converts real-world elevation data into downloadable grayscale heightmaps and advertises outputs up to 8192 pixels.[2] Use it when a scenario requires an intentional geographic area rather than a generic backdrop.
Terrain constraints to resolve during implementation
- Define world units, map extent, sea level, vertical exaggeration, and geographic origin explicitly.
- Preserve sufficient mesh subdivision or use a pre-generated terrain mesh; a high-resolution image cannot add geometric detail to a low-vertex plane.
- Tile and stream large terrains instead of loading one maximum-resolution map into every client.
- Generate normals and terrain materials offline when that reduces runtime cost.
- Keep distant backdrops visual-only and exclude them from navigation and collision.
- Measure precision and comfort at flight altitude, ground level, and XR eye height.
- Do not assume a source heightmap includes roads, buildings, vegetation, water behavior, or authoritative aviation data.
3D model and material assets
Use glTF 2.0 as the canonical runtime exchange format. Three.js provides GLTFLoader for glTF 2.0 and supports Draco mesh compression plus KTX2 compressed textures through the corresponding loaders.[9] Prefer .glb for deployable runtime bundles while retaining editable source files outside the runtime bundle when their licenses permit it.
Asset-source decision
Poly Haven is the primary source. It presents itself as a public 3D asset library with models, textures, and HDRIs.[3] Its asset license is CC0, permits commercial use, and does not require credit.[4] Record attribution anyway when practical so the team can trace provenance and support creators.
Sketchfab is a conditional secondary source. Sketchfab supports model sharing and embedding, while its current homepage directs model purchases to Fab.[5] Its license terms distinguish standard and editorial assets; editorial assets cannot be used for commercial or promotional purposes and carry additional restrictions.[6] Import only an exact asset whose license permits AeroSim's intended use, modification, redistribution inside a built application, and delivery method.
Blendkit remains evaluation-only. Do not treat the site-level link as permission to use every asset.[7] Approve an exact asset only after recording its creator, asset URL, license text, permitted use, attribution requirement, source format, and redistribution constraints.
Asset intake gate
Every third-party asset must have:
- immutable asset ID and source URL;
- creator and source platform;
- exact license and acquisition date;
- attribution text when required or voluntarily preserved;
- editable source format and runtime
.glboutput; - scale, orientation, pivot, naming, and material normalization;
- polygon, draw-call, texture-memory, and animation budgets;
- malware and archive-content inspection;
- evidence that the built application does not expose restricted raw source files;
- visual, physics, interaction, and XR validation where applicable.
An asset without complete provenance and license evidence does not enter the repository or build pipeline.
Cross-application contracts
Nebula and Singularity must evolve as independently buildable applications within the monorepo while sharing only deliberate contracts and reusable libraries.
- Keep shared TypeScript contracts in a focused workspace package; do not import application internals across boundaries.
- Version Socket.IO event names and payloads deliberately, including acknowledgement and error shapes.
- Decide which state is authoritative on the server and which state may be predicted or interpolated in Nebula.
- Define compatibility expectations before either application changes a shared payload.
- Test reconnect, duplicate delivery, stale state, latency, packet loss, and server restart behavior.
- Keep secrets and privileged database access in Singularity; Nebula receives only client-safe configuration.
- Record measurable performance targets for API latency, event latency, simulation frame rate, and XR comfort before using them as release gates.
Evidence expected as implementation advances
Update this page or link to the owning records when implementation establishes:
- exact application and package paths;
- supported browser, device, and XR capability matrix;
- HTTP and Socket.IO contract schemas;
- PostgreSQL schema and migration policy;
- terrain import, tiling, level-of-detail, and collision pipeline;
- asset registry schema and license-review workflow;
- authentication and authorization model;
- performance and reliability targets;
- CI test stages and required coverage;
- deployed versions and runtime verification evidence.
Sources
[1] https://3dtexel.com/landscape-backdrop [2] https://3d-map-generator.com/free-heightmap-generator [3] https://polyhaven.com [4] https://polyhaven.com/license [5] https://sketchfab.com [6] https://sketchfab.com/licenses [7] https://www.blendkit.com [8] https://threejs.org/docs/pages/MeshStandardMaterial.html [9] https://threejs.org/docs/pages/GLTFLoader.html