Emil
9ce45cff4a
feat: audio system with 15 procedurally generated sounds via soundgen
...
- AudioEngine with rodio (WAV playback, throttling, volume, toggle)
- 15 embedded sounds: jump, shoot, hit, explosion, death, pickup, descend,
powerup, step, lava_bubble, acid_sizzle, water_splash, fire_crackle,
ui_click, goblin_growl
- Sound events: shoot, hit, explosion (fireball), pickup, descend, powerup,
jump, combat hit, ambient material sounds (lava/fire/acid/water)
- M key toggles audio in GPU modes
- Ambient sounds: scans 15-cell radius around player, plays throttled sounds
for nearby lava/fire/acid/water
- AudioEngine gracefully degrades when no audio device available
- All 185 tests + 14 scenarios pass
2026-06-22 00:03:27 +03:00
Emil
a5436897ed
wip: current project state
2026-06-21 22:27:20 +03:00
Emil
357db17c2f
feat: GPU optimization — lighting, viewport CA, benchmark mode, 531 FPS
...
- Resolution: 8x8 world cells, 2x2 UI cells (UI_SCALE=4)
- GPU lighting: vertex-shader computed, light source list buffer (max 64)
instead of O(N×R²) grid scan, O(N×S) per cell
- Viewport-aware CA: iterate only active chunks, not all 250×250
- Flat array entity/item/shadow maps instead of HashMaps
- Flat 128-entry ASCII atlas array instead of HashMap lookup
- Partial grid upload: viewport + 30-cell margin only
- Pre-allocated viewport arrays in renderer structs (zero alloc/frame)
- Skip CPU lighting for GPU modes (pass None)
- Benchmark mode: --mode benchmark with per-subsystem timing
- GpuLightSource struct, light_count in push constants
- gather_sources_in_range() for viewport-scoped source gathering
Benchmark (600 ticks, release):
Graphics: 531 FPS (was 386, +38%), render 1013us (was 1699us, -40%)
ASCII: 402 FPS (was 313, +28%), render 1502us (was 2346us, -36%)
All 171 tests + 14 scenarios pass.
2026-06-21 16:09:45 +03:00
Emil
019ae8f090
feat: three render modes — terminal, ascii, graphics
...
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
2026-06-21 00:59:19 +03:00
Emil
139b60b8af
fix: flip Y in vertex shader, dynamic viewport/scissor, clean debug
...
- Fix: Y coordinate was inverted (1.0 - 2.0*y → 2.0*y - 1.0)
Vulkan clip space Y is already down-up, no need to flip
- Fix: dynamic viewport/scissor with viewport_count(1) + scissor_count(1)
Required by validation layer even with dynamic state
- Clean: removed debug eprintlns, restored default clear color
- Shaders recompiled to SPIR-V
2026-06-21 00:41:34 +03:00
Emil
6e9e90fb34
feat: Vulkan renderer with instanced rendering (Phase 4)
...
VulkanRenderer using ash 0.38 + winit:
- Instance with KHR_surface + xlib + wayland extensions
- Physical device selection (first GPU with graphics+present)
- Swapchain (FIFO present mode, B8G8R8A8_UNORM)
- Render pass with color attachment
- Graphics pipeline with instanced rendering:
- Vertex buffer: unit quad (4 verts, 6 indices)
- Instance buffer: 8000 CellInstance structs (32 bytes each)
- 2 vertex bindings: per-vertex (quad pos) + per-instance (grid pos,
atlas UV, fg/bg colors)
- Push constants: screen size + cell size
- Glyph atlas: R8_UNORM texture, uploaded via staging buffer
- fontdue rasterizes DejaVu Sans Mono at startup
- Linear filtering sampler
- Descriptor set: combined image sampler for atlas
- 2 frames in flight with semaphores + fences
- Persistent mapped instance buffer (zero-copy per frame)
Shaders (pre-compiled SPIR-V):
- cell.vert: positions quad from instance data, maps to clip space
- cell.frag: samples atlas alpha, blends fg/bg
--mode vulkan: tries Vulkan, falls back to softbuffer window mode
109 tests, 0 failures
2026-06-21 00:34:01 +03:00
Emil
68f6292c4d
feat: Verbatim MVP - terminal renderer, cellular automaton, Verlet physics
...
- World: 250x250 grid with 14 materials (sand, water, lava, stone, wood, etc.)
- Physics: cellular automaton for materials + Verlet solver for entities
- Entity: multi-cell humanoid (7 sub-bodies with distance constraints)
- Render: terminal renderer with ANSI colors and diff-based updates
- Game loop: fixed 60Hz timestep with accumulator pattern
- Input: WASD movement, number keys for material painting
2026-06-20 18:21:26 +03:00