Entity cell_pos — integer logical position decoupled from render position #295

Closed
opened 2026-03-15 00:30:04 +00:00 by john · 1 comment
Owner

Summary

Add an integer logical position (cell_pos) to entities, fully decoupled from the float render position (x/y). This eliminates the floor() asymmetry problem during movement animation and provides unambiguous cell membership for turn-based logic.

Problem

Entity positions are sf::Vector2f floats. During animated movement:

  • Moving left/up: floor() puts the entity at the new cell as soon as the coordinate changes by any amount
  • Moving right/down: floor() keeps the entity at the previous cell until animation completes
  • Diagonal moves: appear "L-shaped" due to x/y crossing integer boundaries at different times

This makes spatial queries unreliable during animation and forces workarounds for turn-based games.

Proposed API

entity.cell_pos    # Vector(int, int) — logical grid cell
entity.cell_x      # int — X component
entity.cell_y      # int — Y component

Relationship to existing properties

Property Type Purpose Used by turn system?
cell_pos (int, int) Logical grid cell (NEW) Yes — all game logic
x / y float Render position in tile coords No — visual only
grid_pos (int, int) Becomes alias for cell_pos Yes

C++ backing

// UIEntity.h
sf::Vector2i cell_position;  // logical grid cell (top-left for multi-tile)
// existing: sf::Vector2f position;  // render position (for animation)

Behavior

  • Initialization: Both cell_position and position set from constructor args
  • Decoupled: Setting cell_pos does NOT update x/y; setting x/y does NOT update cell_pos
  • Spatial hash: Switches from float-based to cell_pos-based lookup
  • grid.at(x, y).entities: Returns entities whose cell_pos includes (x, y)
  • Multi-tile (#236): Entity with tile_size=(2,3) and cell_pos=(5,5) claims cells (5,5) through (6,7)

Dependencies

  • Interacts with #236 (multi-tile entities claim multiple cells)
  • Interacts with #252 (Grid/GridView overhaul)

Files likely affected

  • src/UIEntity.h/cpp — add cell_position, property accessors
  • src/SpatialHash.h/cpp — switch to integer cell-based tracking
  • src/UIGridPoint.cpp.entities property uses cell_pos
  • src/UIEntityCollection.h/cpp — entity insertion sets cell_pos
## Summary Add an integer logical position (`cell_pos`) to entities, fully decoupled from the float render position (`x`/`y`). This eliminates the `floor()` asymmetry problem during movement animation and provides unambiguous cell membership for turn-based logic. ## Problem Entity positions are `sf::Vector2f` floats. During animated movement: - **Moving left/up**: `floor()` puts the entity at the new cell as soon as the coordinate changes by any amount - **Moving right/down**: `floor()` keeps the entity at the previous cell until animation completes - **Diagonal moves**: appear "L-shaped" due to x/y crossing integer boundaries at different times This makes spatial queries unreliable during animation and forces workarounds for turn-based games. ## Proposed API ```python entity.cell_pos # Vector(int, int) — logical grid cell entity.cell_x # int — X component entity.cell_y # int — Y component ``` ### Relationship to existing properties | Property | Type | Purpose | Used by turn system? | |----------|------|---------|---------------------| | `cell_pos` | `(int, int)` | Logical grid cell (NEW) | Yes — all game logic | | `x` / `y` | `float` | Render position in tile coords | No — visual only | | `grid_pos` | `(int, int)` | **Becomes alias for `cell_pos`** | Yes | ### C++ backing ```cpp // UIEntity.h sf::Vector2i cell_position; // logical grid cell (top-left for multi-tile) // existing: sf::Vector2f position; // render position (for animation) ``` ### Behavior - **Initialization**: Both `cell_position` and `position` set from constructor args - **Decoupled**: Setting `cell_pos` does NOT update `x`/`y`; setting `x`/`y` does NOT update `cell_pos` - **Spatial hash**: Switches from float-based to `cell_pos`-based lookup - **`grid.at(x, y).entities`**: Returns entities whose `cell_pos` includes `(x, y)` - **Multi-tile (#236)**: Entity with `tile_size=(2,3)` and `cell_pos=(5,5)` claims cells `(5,5)` through `(6,7)` ## Dependencies - Interacts with #236 (multi-tile entities claim multiple cells) - Interacts with #252 (Grid/GridView overhaul) ## Files likely affected - `src/UIEntity.h/cpp` — add `cell_position`, property accessors - `src/SpatialHash.h/cpp` — switch to integer cell-based tracking - `src/UIGridPoint.cpp` — `.entities` property uses `cell_pos` - `src/UIEntityCollection.h/cpp` — entity insertion sets `cell_pos`
Author
Owner

Roadmap context

Part of the Grid & Entity Overhaul Roadmap (docs/GRID_ENTITY_OVERHAUL_ROADMAP.md), Phase 2 (Entity Data Model Extensions).

Breaking change: grid_pos becomes an alias for cell_pos, decoupled from x/y. Code that reads grid_pos expecting it to track the float position must be updated. See roadmap for full migration details.

Foundation for the entire behavior system — all behavior movement operates on cell_pos, and the spatial hash switches to integer cell-based tracking.

## Roadmap context Part of the Grid & Entity Overhaul Roadmap (`docs/GRID_ENTITY_OVERHAUL_ROADMAP.md`), **Phase 2** (Entity Data Model Extensions). **Breaking change**: `grid_pos` becomes an alias for `cell_pos`, decoupled from `x`/`y`. Code that reads `grid_pos` expecting it to track the float position must be updated. See roadmap for full migration details. Foundation for the entire behavior system — all behavior movement operates on `cell_pos`, and the spatial hash switches to integer cell-based tracking.
john closed this issue 2026-03-16 11:21:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
john/McRogueFace#295
No description provided.