🌸 Sat, May 2, 2026 🌸
Refactor post-processing pipeline and centralize fullscreen logic
- Consolidated blur compute shaders with 2x downsampling support.
- Moved post-processing buffers (Bloom, SSAO, Blur) to half-resolution.
- Renamed combine-vs.sc to fullscreen-vs.sc and removed redundant vertex shaders.
- Introduced settings uniform to control AA, AO denoising, and Bloom.
- Disabled AA and Bloom by default for performance.
- Improved FPS label smoothing and fixed UI positioning.
I’m giving up on the blur algorithm for now. It feels like a huge waste of time. I could have implemented a bunch of game-related features and assets, but instead I spent it on AA, bloom, and AO denoising. I feel kind of bad about it. So I’ll keep the code for now but leave all the features disabled. I might revisit it later and find a more performant way to do blur with the same quality. I really like how the AA is looking, though—especially how it handles dithered transparency.
🌸 Sat, May 2, 2026 🌸
Implement Anti-Aliasing (AA) with compute shaders
- Added AA mask pass to identify edges based on depth and normals.
- Implemented adaptive horizontal and vertical blur shaders for AA.
- Refactored Render class to incorporate AA in the deferred pipeline.
- Added screen-space pass to blit the combined buffer to the backbuffer.
- Moved perspective near and far constants to near-far.hpp for consistency.
- Various code cleanups and bug fixes in shaders and C++ code.
Spent the rest of the day implementing AA. I probably shouldn’t be messing with this so early in development, but I just couldn’t help myself. FPS tanked down to 120, but it looks pretty sweet. I’ll sleep on it and see if I can find a way to optimize it. Something feels a bit off with the compute shaders—maybe I’m passing some wrong parameters? Intuitively, it shouldn’t be this expensive.
🌸 Fri, May 1, 2026 🌸
Refactor blur shaders into separate R8 and RGBA8 versions
- Create specialized R8 and RGBA8 wrapper shaders for compute blur.
- Rename existing blur compute shaders to .sh for inclusion.
- Update Render class to load and dispatch the appropriate blur programs for Bloom (RGBA) and SSAO ®.
Gemini reviewed my code and mentioned it’s not a good idea to mismatch pixel formats. For the SSAO buffer, I was passing R8 values, but the blur shader was expecting RGBA. Everything worked fine for me, but it might have fallen apart on different hardware or driver combinations. I’ve refactored the shaders to use separate R8 and RGBA8 versions just to be safe.
🌸 Fri, May 1, 2026 🌸
Refactor rendering pipeline with compute shader blur and move shader compilation to Chef
- Implement compute shader-based recursive blur for Bloom and SSAO.
- Significant refactor of Render class and Deferred rendering setup.
- Rename bgfx handles to shorter forms (e.g., HTexture -> HTex, HProgram -> HProg).
- Move shader compilation from Makefiles to the chef asset processor.
- Fix initialization order in Source constructor to match declaration.
- Update gameplay.json and crystal group point light radii.
I can’t get the idea of compute shader blur out of my head. Logically, I don’t need it at this stage—SSAO looks fine and bloom looks great. But there was an itch, so I decided to go for it. Not sure why, but FPS went down from 400 to 250 no matter what I did; just enabling the compute shader reduced the performance. Anyway, I might need it for something else later—AA, for example, or a better transparency pass.
perf: optimize audio system and implement sound prioritization
- Refactor Source/Sink to use pre-allocated buffers and reduce heap churn in audio thread.
- Implement priority-based sound mixing with a limit of 16 concurrent sources.
- Move 3D sound attenuation updates to a 30 FPS timer in Scene.
- Add randomized walk speeds for LiveRock mobs.
- Remove atomic gain/pan in favor of synchronous updates under sink locks.
I’ve been working on optimizing the sound system, and it’s been quite a challenge. I’m not sure how this is typically handled, but I ended up limiting the number of simultaneous sound sources to 16 and implementing a prioritization system. I also attempted to reduce memory allocations by reusing buffers, although it didn’t seem to make a huge difference. I decided to keep those changes anyway as they’re slightly more efficient and I’d rather not revert them now.
refactor: optimize mob AI and physics performance
- Enhance Timer class to support recurring tasks and robust cancellation.
- Refactor LiveRock to use standard dynamic physics bodies instead of CharacterVirtual for better performance.
- Implement randomized AI tick frequency (25-35 FPS) to distribute computational load.
- Re-enable VSync by default for improved rendering stability.
- Add “info:” prefix to Chef cooking time logs.
feat: move animation baking to Chef pipeline and refactor consts
- Offload skeletal animation baking to the Chef tool, reducing game load times to ~1.5s.
- Update AnimAsset to load pre-calculated .anim and .anim.bin assets.
- Relocate global constants to libs/shared/consts.hpp.
- Refactor Chef to use a centralized GLTF scene loader.
- Improve Makefile PCH management and add clean-all target.
- Extract BGFX reset flags and disable VSync by default.
- Update mob task list in todo.md.
feat: implement animation baking and update gameplay
- Implement animation baking in AnimAsset to pre-calculate matrices at 120 FPS, improving runtime performance.
- Populate gameplay.json with additional LiveRock mob instances for performance testing.
- Adjust player starting equipment levels.
feat: implement Life Rock mob (WIP) and its animations
- Add LifeRock class for the new mob type.
- Include Life Rock assets: mesh, textures, and idle/run animations.
- Update asset lists and gameplay configuration to incorporate Life Rock.
- Perform minor cleanup and refactoring in CrystalSanctuaryGuardian.
feat: implement incremental asset caching in Chef
- Integrate MurmurHash3 for input-based cache key generation.
- Implement FuncCache for function-level memoization of asset cooking tasks.
- Add file tracking (path, size, mtime) to detect source asset changes.
- Refactor MeshAsset cooking to use incremental caching for collision shapes.
- Reduce game startup time to ~1.7s by avoiding redundant asset processing.
- Update .gitignore to exclude the new .chef/ cache directory.
- Update development journal with latest performance metrics.
feat: implement real-time 3D audio spatialization
- Refactor Snd3d to update gain and panning in real-time via the Ticker interface.
- Use std::atomic for gain and pan to ensure thread-safe updates between the main and audio threads.
- Fix logic errors in stereo panning calculations within Sample and Sink.
- Implement ticker cleanup in Scene to prevent leaks and crashes.
- Adjust CrystalGroupBlue light color to purple to match its visual model.
- Update project TODO list and refine the development journal entry.
refactor: introduce asset cooking pipeline and shared library structure
- Create ‘chef’ utility for pre-processing assets and baking collision shapes.
- Implement ‘libs/shared’ to house physics and asset processing logic used by both the game and chef.
- Move asset declarations to shared ‘process-assets.hpp’ for single source of truth.
- Update MeshAsset to load pre-compiled Jolt (.jph) collision shapes from disk.
- Integrate ‘chef’ into the main Makefile as a build dependency.
- Configure ‘coddle’ with a local repository for the new shared library.
- Update documentation with future plans for boss minions and ability mechanics.
feat: implement 3D spatial audio, boss SFX, and optimize audio loading
- Add Snd3d class for spatialized audio with distance attenuation and panning.
- Rename SoundWave to SndWav and integrate with audio sinks in Scene/Gameplay.
- Implement Crystal Sanctuary Guardian SFX: attack, damage, death, intro barks, and animation-synced footsteps.
- Optimize audio loading by removing the normalization pass and reusing buffers.
- Improve SkMesh::getAnimTime for precise animation-to-SFX synchronization.
- Add Bitwig source projects and raw WAV assets for new sound effects.
- Create doc/journal.md and update doc/todo.md with progress on rendering and boss completion.
- Update .gitignore to exclude auto-backups.
Optimize light pass with scissors, enhance Scene Editor, and add crystal assets
- Implement screen-space scissoring for light passes in deferred rendering, control it with a radius parameter
- Add debug visualization for light scissors (toggled with ‘L’)
- Support 2D alignment modes (XY, XZ, YZ) in Scene Editor using Shift modifier
- Allow adding specialized nodes (Lights, etc.) from the Editor asset menu via NodeTypesRegistry
- Fix skeletal mesh normal/tangent skinning and view-space depth reconstruction
- Add crystal group assets (Blue, Purple, Red) and associated textures
- Refactor getModelMat() to getModelMtx() and add double-sided material support
- Remove collider from mushroom nucleus, roots, and shrubs
- Render point light and spotlight meshes in editor mode
- Make rng shader function that returns values from 0 to 1 and use it instead of PCHHash
- Implement dithered transparency
- Fix artifacts on the screen edges with the SSAO and bloom
- Implement support for two-sided materials
- AI removed gamma correction, not sure why, but I like the result
Optimize asset loading and unpack Blender textures for LFS
- Improved asset loading time from 36s to 4s by caching Assimp scenes in Assets.
- Unpacked textures from Blender files into separate PNGs for better Git LFS support.
- Reused texture loading buffer and reserved memory for mesh vertices/indices.
- Switched to steady_clock for more accurate loading telemetry.
Reverse depth, 32-bit indices, cave assets, loot point lights
- Switch to reverse depth (far=0.05, near=500) to address z-fighting
- Switch mesh and sk-mesh index buffers to 32-bit (BGFX_BUFFER_INDEX32)
- Merge t_metallicRoughness and t_normals combine uniforms into one
- Remove Deferred::geom(); set geometry state per draw call instead
- Add full cave asset library (walls, floors, pillars, decor, etc.)
- Filter scene editor asset list to cave/SM_Wall variants
- Update gameplay.json with cave wall and archway pieces
- Add point lights to EntropyLoot (red), EssenceLoot (green), HarmonyLoot (blue)
- Add point light to BhsProjectile
- Return last inserted node from loadJsonInternal; fix duplicate in editor
- Clamp physics collision steps to max 5 per frame
- Hide mobUi by default in Player constructor
- Log asset load path in Assets::load
- Log texture dimensions on load
Implement normal mapping and octahedron normal encoding
- Add support for tangent space normal mapping across static and skinned meshes.
- Update vertex layouts and Assimp import flags to calculate and include tangent data.
- Implement octahedron normal encoding for G-buffer optimization, storing geometric normals in the metallic-roughness target and pixel normals in the normal target.
- Refactor material system to use bitmasks for shader settings instead of individual floats, reducing uniform overhead.
- Consolidate skinned mesh and static mesh fragment shaders to use a unified
geom-fs.sc. - Integrate
shaderlib.shfor shared decoding/encoding utility functions. - Add
metallicRoughnessCombinesampler to the deferred combination pass to support new normal reconstruction logic.
3x14=42 Pi is the meaning of the life.
Mushrooms, cave level, separate physicsTick from tick
- Add mushrooms.blend with 31 mushroom mesh variants
- Add cave.blend with CrystalSanctuary mesh and dedicated collision
- Place 31 mushroom instances in gameplay.json near starting area
- Update CrystalSanctuary path from world/ to cave/ with separate coll
- Filter scene editor asset list to mushrooms only
- Extract Scene::physicsTick from Scene::tick for clarity
I noticed instead of clicking on the cross in the top right to close the app, I usually fish for the Exit or Quit menu, because that fricking cross button, in 50% of cases, does not close the app and does something weird, like putting it in the background.
Ticker mixin, Particle VFX, Staff/Bhs attack logic, Scene ticks
- Add Ticker mixin with pure virtual tick(double dt)
- Remove virtual tick from Node; only Ticker subclasses tick
- Scene maintains tickers map; dispatches tick to all Ticker nodes
- Add Particle: physics sphere that despawns after 1 second
- Spawn particle rings on hit and crit for BHS and Staff
- Add virtual getDmg/isCrit/onAttack to Weapon as pure virtuals
- Remove attackCb lambda from Weapon::Ctor; replace with overrides
- Implement Staff::onAttack with sphere collision query and VFX
- Implement Bhs::onAttack with projectile spawn and crit support
- Add lvl field to Weapon::Ctor; scale damage via exponential formula
- Add Staff::Ctor and Bhs::Ctor with lvl parameter
- Rename applyDamage to applyDmg on Mob and CrystalSanctuaryGuardian
- Rename weapon to weaponMesh in Player for clarity
- Extract Player::animTick for weapon mesh sync and anim state machine
- Fix curWeapon null init in Player
- Remove Node::tickInternal; use Scene::tick for all ticking
- Replace scene➡️tickInternal(dt) with scene➡️tick(dt) in gameplay/editor
- Add particle/Particle mesh asset
- Fix todo: mark staff icon, BHS VFX, inventory UI as done
Weapon attack callbacks, timer cancellation, Staff mesh
- Add Weapon::attackCb and timeOfAttack for per-weapon attack logic
- Move BHS projectile spawn into Bhs::attackCb lambda
- Add Timer::cancel with CancellationToken to abort deferred calls
- Add Player::onAttack: validates weapon slot still active before firing
- Store attackCancellationToken in Player; cancel on weapon switch
- Cancel attack timer on setCurWeapon to prevent stale callbacks
- Add Staff mesh (alara/Staff/OneBone as SkMeshAsset) and StillAnim
- Wire Staff idle and attack anims to StillAnim placeholder
- Remove weapon position offset from setCurWeapon (handled by socket)
- Assert mesh non-null in Player::tick instead of early return
- Clean up Player::tick: remove redundant mesh lock, simplify branches
- Fix weapon.cpp: remove stray #pragma once
Pie menu, weapon system, Btn node, weapon slots wired to player
- Replace
RadialMenuwithPieMenu: 12-segment pie with visibility bits - Add
pie-menu-uifs.scwith per-segment visibility and hover highlight - Add
Btnnode with hover highlight shader andonClickcallback - Add close button to
InvUiviaBtnnode - Add
Weapon::Ctorwith mesh, idle, attack, and player attack anims - Wire
StaffandBhsconstructors toWeapon::Ctorwith anim paths - Add
Player::setCurWeapon: spawns weaponSkMeshfrom Weapon item data - Add
Player::onPieMenuSelected: routes pie selection to weapon/inv/etc Player::secondaryTrigopens pie menu and centers/hides cursor- Pie menu closing restores cursor and HUD visibility
- Remove hardcoded BHS anim refs from Player; use
curWeaponinstead - Weapon slot null-guard: only attack if
curWeaponand weapon exist - Add typed
Slot<I>::getItem()returningconst I* - Add
BaseSlot::getItem()returningconst Item* - Add
InvUiweapon slot getters for pie menu visibility checks - Add
isVisibleguard tomouseBtnDown/Up/WheelinNodeUi - Fix
TileViewleft click to returnonTileClickresult - Remove unused
hp-icoandmana-icofrom asset preloads - Remove log statements from loot, crystal sanctuary guardian
- Assert on texture load failure instead of logging
WIP Radial menu, label alignment, Item tex as string, clangd config
- Add RadialMenu node with bg/fg shader and mouse angle highlight
- Add radial-menu-uifs.sc: 12-segment angle shader
- Add radial-menu-bg and radial-menu-fg assets
- Add Label horizontal/vertical alignment support (HAllign, VAllign)
- Fix InvItemTile count label to use right alignment within bounds
- Change Item::tex and Item::Ctor::tex from Ref to string
- Resolve item tex via getAsset in Hand, Slot, InvItemTile
- Remove Assets dependency from Entropy, Essence, Harmony, Staff, Bhs
- Remove test inventory items from Player constructor
- Add RadialMenu to Player UI
- Defer UI mouse motion to main loop tick instead of event handler
- Skip invisible nodes in mouseMotionInternal
- Fix TileView: set isVisible=false on tiles before removing them
- Add .clangd config for IDE integration
- Add intermediate icon PNG assets for slots
Ctor-based add() API, font by string, asset by string in Ctor
- Change
Node::add<T>(args)toadd(Ctor{}, args)usingCtor::Talias - All node
Ctorstructs now carryusing T = NodeTypefor type deduction - Separate node-specific
Ctorfrom positionalNode3d/NodeUi::Ctorargs Mesh::CtorandSkMesh::Ctornow take asset as stringLabel::CtorandMenuItem::Ctornow take font as stringFpsLabelno longer requiresFontreference in constructorBaseSlot::Ctorseparated fromSlot<I>::CtorwithNodeUi::Ctoras argInvUi::Ctorcarries Items reference instead of passing via constructor- All node registrators updated to use new
add(Ctor{})pattern - Fix
TileViewscrollmax: use(size-1)/nColinstead of(size-nCol+1)/nCol - Update all slot, loot, player, mob constructors to new pattern
- Update icon assets for equipment and weapon slots
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56 - 57 - 58 - 59 - Next