Entity.tier is the authoritative discrete identity; radius is tier-derived data
Context
Phase 0 of turning glemy into a Suika-style merge puzzler (planned and approved, see the approved plan for the full multi-phase design). Entities need a discrete size/merge-progression identity ('tier') so same-tier collisions can be distinguished from different-tier ones. Two directions were available: derive tier from the existing continuous `radius` field via a tolerant lookup, or add a new discrete `tier: Int` field and derive `radius` from it instead.
Options considered
Decision
Entity gained a tier: Int field (glemy/pe/entity.gleam). New submodule glemy/pe/tier.gleam (pure, target-agnostic, matching the existing pe/vector2, pe/entity, pe/bounds, pe/collision pattern) holds tier_count (6, an MVP scope choice -- pure data, trivially extended later) and radius(tier) -> Float. entity.loosely_equals gained an exact (non-tolerant) tier equality clause. pe.spawn_entity gained a tier parameter and now derives radius from tier.radius(tier) instead of the removed pe.spawn_radius constant. Every existing Entity(...) construction across the whole codebase (production and test) was migrated to carry an explicit tier, defaulting to 0 where no other value was meaningful yet.
Verification
Purely mechanical migration, verified as behavior-preserving: gleam test and gleam test --target javascript both pass with the same set of pre-existing assertions intact (90 Erlang / 123 JS, up only by the 6 new dedicated pe/tier_test.gleam tests -- zero regressions, zero test logic changes beyond the mechanical tier:0 addition and the spawn_radius-to-tier.radius(0) rename forced by removing the now-redundant constant).
Consequences
Every future Entity constructor call anywhere in this codebase must supply a tier -- Gleam's compiler enforces this at every call site, which is the point (no way to construct a 'tier-less' entity by accident). The old pe.spawn_radius constant (5.0) is gone; tier 0's radius is now 4.0 (glemy/pe/tier.gleam), a minor, deliberate, expected value change now that tier data is authoritative.