Investigate float/long for position & vector types (currently int px + Q16.16 fixed) #78
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#78
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Positions are integer pixels and velocities are
fixed(Q16.16). For a general 2D engine this may be limiting: sub-pixel movement, large/scrolling worlds, camera zoom, precision.Investigate / RFC: an f32/f64 and/or i64 option for Position and the Vector type; the tradeoffs; and whether Position should be a typed Vector rather than raw int fields.
Determinism note: fixed-point was likely chosen for deterministic replay/lockstep netcode — any float option must preserve that deterministic path (or be opt-in).
Investigated and decided — see docs/RFC-POSITION-TYPES.md (commit
7f55554).Decision: keep the deterministic integer + Q16.16 core; no hardware floats.
Closing as resolved with the recorded rationale. Pairs with #77 (Position now shipped canonically from ludic.core).
Reopened and shipped a real, tested implementation (
6a83c28), not just the RFC.Camera.zoom(scale)— a deterministic Q16.16 render-time zoom. It scales every draw about the screen centre through the same two framebuffer chokepoints (rt_put_px / rt_fill_rect) that already carry the camera offset, so it composes with Camera.set/follow/shake.1.0= none,2.0= 2x in,0.5= out;1.0turns the path back off.Backward-compatible by construction: gated behind an internal
rt_cam_zoomedflag so any game that never zooms takes the original int-subtraction blit path and renders byte-for-byte identically — all golden renders unchanged, C-free bootstrap fixpoint intact, full suite 105/0.Verified with
examples/library/camera_zoom.ludic(pixel-readback: draws a box, zooms 2x, confirms it moved+scaled to the predicted screen cell, then zoom(1.0) restores it) wired as a feat_case.This is the concrete outcome of the investigation: the world coordinate types stay integer px + Q16.16 velocity (hardware floats rejected — they'd desync lockstep/replay/world_save), and zoom is delivered where it belongs, as a render-time transform on the camera. Sub-pixel motion was already solved (Body.rx/ry accumulators); i64 world extent (
Position64) remains a clean additive opt-in to add only when a real game needs >±2e9 px. Rationale recorded in docs/RFC-POSITION-TYPES.md.