# Why `gemath` exists (and what not to “simplify away”)
This crate intentionally makes different trade-offs than “a pure linear algebra crate”.
If you’re contributing, these are the choices that keep `gemath` distinct (and worth using alongside/over other crates):
## 1) Type-level units + coordinate spaces
Core math types carry two type parameters:
- **Unit**: `Meters`, `Pixels`, or `()`
- **Space**: `World`, `Local`, `Screen`, or `()`
This gives you compile-time prevention of a whole class of bugs (“I added world meters to screen pixels”).
Rule of thumb:
- If an API represents a *position/direction/transform* in a known domain, it should preserve the tags.
- If an API deliberately “crosses domains” (e.g. projection), the conversion should be obvious at the call site.
## 2) Typed angles (no “mystery radians”)
Rotation APIs should accept `Radians` / `Degrees` rather than raw `f32`.
If a raw-`f32` API exists for compatibility, treat it as legacy and provide a typed alternative.
## 3) Explicit fallibility (and consistent naming)
When an operation can fail, make it obvious:
- return `Option` (or `Result` if error details matter)
- use naming like `try_*` / `checked_*`
See `DESIGN_FALLIBLE_OPS.md`.
## 4) Beyond vectors: game-dev geometry and collision helpers
`gemath` isn’t trying to be only a vector/matrix/quaternion crate:
- geometry primitives (`geometry`)
- collision helpers with structured hit results (`collision`)
- spatial broadphase prototypes (`spatial`, allocation-backed; prototype quality)
The intent is: if you’re writing game/engine code, you can stay in one math crate longer without reinventing the same primitives.