Redesigned entity from solid 5x5 block to humanoid silhouette:
Shape (23 bodies, was 27):
H H H (head, 3 wide)
H H H
A T T T A (shoulders + arms, 5 wide)
A T T T A
T T T (torso, 3 wide)
L R (legs, split with gap)
L R
Per-part colors (Noita-inspired):
- Player: head=bright yellow, torso=golden, arms=amber, legs=dark gold
- Goblin: head=bright green, torso=green, arms=olive, legs=dark green
- Corpse: desaturated browns
SubBody now has color: [u8; 4] field, set by build_humanoid.
All renderers (terminal, ascii, graphics) use b.color directly.
Fire effect: flickering orange overlay on burning entities.
half_w adjusted from 3.5 to 3.0, half_h from 2.5 to 3.5
(taller shape, narrower than old block).
109 tests, 0 failures
Cells reduced from 16x16 to 10x10 pixels. Same window size now
shows more of the world — finer detail, more cells visible.
Adaptive viewport recalculates grid_w/grid_h from new cell size.
109 tests, 0 failures
Each cell now stores its own fg/bg color inline, instead of looking
up from MaterialRegistry every frame.
Cell struct:
- fg: [u8; 3] — foreground color (for rendering)
- bg: [u8; 3] — background color (for rendering)
- temp: f32 — temperature (already there)
- material: MaterialId — for physics property lookup
- variant: u8 — visual/behavioral variant
- updated_this_tick: bool — CA flag
Colors are copied from MaterialRegistry at Cell::new() time.
This allows per-cell color variation in the future (water depth
shading, lava gradient, damaged materials, etc.) without registry
changes.
MaterialRegistry still stores physics properties (density, solid,
liquid, flammable, etc.) — looked up only during CA/physics steps,
not during rendering.
Renderers (terminal, ascii, graphics) updated to use cell.fg/cell.bg
directly — no more registry lookup in render path.
Cell size: ~16 bytes (was ~12). 250x250 grid = 1MB (was 750KB).
126 tests, 0 failures
Wayland surface always reports current_extent as 0xFFFFFFFF (undefined),
meaning the swapchain size is determined by the application, not the
surface. Previous code returned early when this happened, so resize
never worked — cells stretched to fill the window.
Fix: when current_extent is 0xFFFFFFFF, use winit's window.inner_size()
to get the actual pixel dimensions. This works on both X11 and Wayland.
Both renderers (ascii + graphics) updated.
109 tests, 0 failures
Both renderers (ascii + graphics) now support dynamic window resize:
- check_resize() called at start of every render() frame
- Compares surface capabilities with current swapchain extent
- If changed: recreates swapchain, image views, framebuffers, command buffers
- Recalculates grid_w/grid_h from new extent / cell_size (16x16)
- Reallocates instance buffer if grid cell count changed
- Old swapchain properly destroyed after new one created
- Handles window minimize (skip if extent = 0)
- physical_device field added back to both renderers (needed for surface caps query)
main.rs: vw/vh queried every frame from renderer.grid_w()/grid_h()
instead of cached once at startup. Camera center uses dynamic dimensions.
Result: resize window → more/fewer cells visible, cells stay 16x16 pixels.
109 tests, 0 failures
Square cells:
- CHAR_W and CHAR_H both 16 (was 8x16, non-square)
- Window size updated to 160*16 x 50*16 = 2560x800
- Applies to both ascii and graphics renderers
Slope stepping collision:
- Before resolving X, check if new position overlaps solid
- If overlap, try stepping up 1 cell — if clear, snap up (walk up slope)
- If can't step up, resolve X normally (wall block)
- aabb_overlaps_solid() helper for fast overlap check
- Player can now walk up 1-cell-high steps and slopes
109 tests, 0 failures
Three render modes:
- --mode terminal: pure ANSI ASCII in terminal
- --mode ascii: Vulkan window with ASCII characters (glyph atlas)
- --mode graphics: Vulkan window with colored cells (no glyphs, each
material = unique base color, no lighting yet)
Graphics renderer:
- Same Vulkan pipeline as ASCII but without glyph atlas
- Simpler shaders: graphics.vert/frag just output instance color
- No descriptor set, no texture sampling
- Each cell = colored quad, material color fills entire cell
- Entities rendered as colored shapes (player=yellow, goblin=green)
Default mode changed to --mode ascii
109 tests, 0 failures