docs(workspace): add adr for split-coordinate entity positions
This commit is contained in:
parent
4399e88412
commit
45c3351d7d
|
|
@ -37,6 +37,7 @@ Each subsystem note should name the design topic it implements (by title, e.g. "
|
||||||
- [`adr/0005-namespaced-content-ids.md`](adr/0005-namespaced-content-ids.md): namespaced content IDs.
|
- [`adr/0005-namespaced-content-ids.md`](adr/0005-namespaced-content-ids.md): namespaced content IDs.
|
||||||
- [`adr/0006-base-game-on-modding-api.md`](adr/0006-base-game-on-modding-api.md): base game built on the modding API.
|
- [`adr/0006-base-game-on-modding-api.md`](adr/0006-base-game-on-modding-api.md): base game built on the modding API.
|
||||||
- [`adr/0007-declarative-content-via-modding-api.md`](adr/0007-declarative-content-via-modding-api.md): declarative content loads through the modding API.
|
- [`adr/0007-declarative-content-via-modding-api.md`](adr/0007-declarative-content-via-modding-api.md): declarative content loads through the modding API.
|
||||||
|
- [`adr/0008-split-coordinate-entity-positions.md`](adr/0008-split-coordinate-entity-positions.md): split-coordinate entity positions.
|
||||||
- [`adr/template.md`](adr/template.md): template for new decisions.
|
- [`adr/template.md`](adr/template.md): template for new decisions.
|
||||||
|
|
||||||
Subsystem notes:
|
Subsystem notes:
|
||||||
|
|
|
||||||
26
docs/adr/0008-split-coordinate-entity-positions.md
Normal file
26
docs/adr/0008-split-coordinate-entity-positions.md
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# 0008. Split-coordinate entity positions
|
||||||
|
|
||||||
|
- **Status:** Accepted
|
||||||
|
- **Date:** 2026-07-07
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
In a procedurally generated voxel world, an entity's position cannot be robustly represented by a single global single-precision floating-point vector (`f32` or `Vec3`). At large distances from the origin, the spacing between representable floating-point numbers increases, leading to spatial jitter, physics instability, and rendering artifacts.
|
||||||
|
|
||||||
|
While double-precision floats (`f64`) postpone this issue, they double the data size and are not uniformly or natively supported on GPUs, which expect `f32` vertices and transforms. The engine requires a spatial representation that maintains sub-millimeter precision universally across a theoretically unbounded world, without coupling the simulation state directly to GPU limitations or paying the cost of `f64` everywhere.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
The engine uses a split-coordinate representation for entity positions, encapsulated by the `EntityPos` type. An entity's absolute position is defined by two discrete components:
|
||||||
|
|
||||||
|
1. A `chunk` anchor (`ChunkPos`): The integer coordinates of the chunk containing the entity.
|
||||||
|
2. A `local` offset (`Vec3`): A single-precision floating-point vector describing the entity's exact position relative to the chunk's minimum corner.
|
||||||
|
|
||||||
|
When an entity moves, the movement is applied to the `local` offset. A normalization step (`EntityPos::renormalize`) then carries any overflow beyond the chunk boundaries into the integer `chunk` anchor, ensuring the `local` offset always remains strictly within the bounding box of a single chunk (`[0.0, CHUNK_SIZE)`).
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- **Uniform Precision:** Entities maintain exact `f32` precision regardless of how far they travel from the world origin, as the active floating-point magnitude is strictly bounded by the size of a single chunk.
|
||||||
|
- **Rendering Stability:** The renderer can compute relative matrices by defining the camera's current chunk as the origin. This allows the GPU to process all vertex data and transforms in standard `f32` without any spatial jitter.
|
||||||
|
- **Math Complexity:** Code manipulating spatial positions (like physics integration and distance checks) becomes more complex. It is no longer possible to simply subtract two global vectors; logic must handle both the chunk offset and the local offset simultaneously.
|
||||||
|
- **Serialization:** `EntityPos` serializes as a compound struct, ensuring save files do not lose coordinate precision for distant entities.
|
||||||
Loading…
Reference in a new issue