Character panel:
- Width 44 -> 52, height 44 -> 62
- Text rows spaced 8 apart (was 6) — no more squished text
- HP/XP bars 38 wide (was 32)
- Stats with double space between pairs
- Inventory section at bottom with more room
HUD bar:
- Height 18 -> 28
- Rows at y_top+2, +12, +22 (was +1, +7, +13)
Inventory overlay:
- Slots 12x10 (was 8x6), gap 3 (was 2)
- Panel auto-sizes larger
- Click hitboxes in main.rs updated to match
Fixed depth_shown_in_hud test for new HUD height.
All 171 tests + 14 scenarios pass.
New entity: Slime (EntityKind::Slime)
- 19 parts: blobby body (3x5) + 2 glowing eyes
- Green translucent colors, brighter center
- HP: 25, spawns every 45 ticks (max 2 alive)
Slime AI (update_slime_ai):
- Jumps toward player every 60 ticks when within 40 cells
- Jump power scales with proximity (closer = stronger)
- Pauses horizontally between jumps (50/50 hop-stop cycle)
- Uses set_horizontal_vel + set_vertical_vel (vector movement)
Combat system (update_combat):
- AABB overlap check between player and all alive enemies
- Goblin: 8 damage per 20 ticks on contact
- Slime: 5 damage per 20 ticks on contact
- Knockback: player pushed away from enemy on hit
- Player.take_damage() called, death possible from enemies
World gen: try_spawn_slime() spawns at surface, 18 cells from player
Renderers: slime rendered as 's' in ascii/terminal, green blob in graphics
6 new tests (122 total, 0 failures)
Entities are now ~3x larger and more detailed:
Player (47 parts, was 15):
- Hat: 3 top + 2 brim (dark purple)
- Head: 3x2 face (lavender skin)
- Belt: golden accent across torso
- Shirt: 3x2 torso + arms out to 3 cells each side
- Hands: 4 cells (2 per arm, pale lavender)
- Pants: 3 wide hips + 5 wide legs + split
- Boots: 3 cells + 2 foot tips (dark purple)
- half_w=4, half_h=6 (was 2.5x3.5)
Goblin (41 parts):
- Pointed ears (2 cells)
- Ragged shirt (green, darker shade)
- Bare feet (green skin, no boots)
- Loincloth (dark green)
Auto-constraints: all parts connected to all others (n^2)
- Simplified from manual constraint lists
- Works for any template shape
- Ragdoll will look natural — all parts hold together
macro_rules! p! for compact part definitions
117 tests, 0 failures
BodyTemplate: JSON-serializable entity body definition.
- parts: Vec<BodyPart> with x, y, color, label
- constraints: Vec<(usize, usize)> connecting parts
- half_w/half_h/radius: collider and physics params
Built-in templates:
- humanoid_player: purple wizard (15 parts)
- humanoid_goblin: green (15 parts)
- boulder: 4x4 rock (16 parts)
API for AI agents:
- BodyTemplate::to_json() / from_json() — serialize/deserialize
- BodyTemplate::preview_ascii() — text preview of silhouette
- BodyTemplate::apply_to(&mut entity, cx, cy) — build entity from template
- template_for_kind(EntityKind) — get template by entity type
- Custom templates: create any shape (snake, dragon, boss) from code or JSON
Entity::build_humanoid() now delegates to template_for_kind().apply_to()
— single source of truth for body layout.
7 new tests for template system (116 total, 0 failures)
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
- Replace per-body collision with single AABB collider for rigid entities
- Entity has half_w/half_h defining the collider box
- Separate axis resolution: X first (min-penetration push), then Y
(velocity-direction push to handle floor/ceiling correctly)
- Sliding: when hitting a wall, only X velocity is zeroed, Y continues
- check_on_ground uses AABB bottom edge, not individual bodies
- Fix: X resolution uses minimum penetration (was velocity-based,
which pushed player through walls when velocity was zero)
- Default scene: added water pool, lava pool, wood structure, sand dune,
acid pool, stone wall obstacle
- 28/28 tests passing
- Entity: rigid body mode for alive entities (single object, no wobble)
- Center position + velocity, bodies positioned from rest offsets
- Collision: all 16 bodies checked, push applied to center
- Movement: velocity applied to center, all bodies move together
- Entity: ragdoll mode for corpses (loose Verlet constraints)
- kill() switches rigid->ragdoll, gives each body inherited velocity
- Constraints go slack (stiffness=0), bodies fall independently
- Player: move_left/right now applies velocity to entity center (was: head only)
- Physics: lava heat conductivity 0.05 (was 0.5), initial temp 1500 (was 1200)
Lava cooling threshold 400 (was 800), heat transfer rate 0.1 (was 0.5)
Lava stays hot long enough for entities to take damage
- Tests: 28/28 passing, updated for new lava and rigid body behavior