The core of the game is a simple but difficult choice: push deeper into the dungeon for better loot, or extract now and keep what you've found. Gear you extract goes back to your personal lobby - a customizable home space where you display your trophies, store your best weapons, and prepare for the next run. But another choice emerges: do you risk bringing your hard earned trophies back into the dungeon for a stronger start and a chance at even greater rewards? Extraordinary prizes await, but at the cost of losing everything you take with you.
Rooms scale in difficulty as you descend, with enemy types, gear, and encounters tuned to match. No two runs feel the same thanks to a pool of community-built rooms and a difficulty system that adapts to how deep you dare to go.
Build rooms with a powerful in-game editor that puts full creative control in your hands. Place terrain, enemies, traps, and obstacles on a 3D grid with intuitive controls to craft exactly the challenge you envision. Wire together reactive elements like pressure plates that trigger enemy waves, timed doors that lock players in until they survive, and patrol paths that send enemies marching through corridors. And finally publish your creation to unleash it on the world. The builder is designed to be approachable for anyone, but deep enough to create rooms that surprise even experienced players.
Built out the full patrol path visualization system and made y clipping available in all editor modes.
Big patrol path day. The nav-aware visualization was the main piece — instead of dumb straight lines between waypoints, the paths now trace the actual navigation graph edges so you can see exactly where an enemy will walk. The dashed shader gives each segment its own length value which looks much cleaner than a uniform dash pattern. Moving y clip out of placement mode was a small change with outsized impact since you no longer have to switch modes just to see a specific floor level.
Implemented a lava flow simulation with procedural shader and added admin bypass points for the publisher.
The lava system was the big push today. The flow simulation runs on the grid and respects room boundaries, which sounds simple but required some careful bounds checking. The procedural shader turned out nice — it’s entirely math-driven with scrolling noise layers so there’s no texture memory cost. The admin bypass stuff was a late-night addition to make it easier to edit and republish rooms without hitting the normal validation gates.
Massive day of builder cleanup covering free item handling, delete previews, move operations, and a full legacy bridge removal.
This was one of those grind-it-out days where you just keep fixing things until the builder feels right. The free item handling was the main thread — move, delete, selection, and placement all needed to go through the same material-swap pipeline that grid items use. Removing the legacy bridge system was cathartic. The unified pointer targeting refactor touched a lot of files but makes the codebase much more maintainable going forward.
Broke the monolithic builder into focused controllers across seven refactor phases, plus selection UI and free item work.
This was a late-night marathon. The builder had grown into a single massive file that was getting painful to work with, so I broke it apart systematically. Each phase was its own commit so I could verify nothing broke between steps. The record-based placement approach for clipboard and move operations is cleaner than the old proxy-based system. The compile-time GameConfig constants change is small but removes a bunch of runtime lookups.
Introduced the reactive visual system, rebuilt selection around grid cells, and fixed a 5-second lag on bulk operations.
The performance fix was the highlight. The root cause was simple but brutal: every cell change during a bulk operation triggered OnCellChanged, which cascaded into RefreshAllPillars, which called FindObjectsByType 25,000 times. The SuppressChangeEvents flag lets bulk operations skip all that and fire a single notification at the end. Went from 5 seconds to near-instant. The reactive visual system is the proper long-term fix — instead of scanning every object in the scene, it tracks reactive items by column index and only updates what’s actually affected.
Built the chunked mesh rendering pipeline, binary room format, and grid-based runtime build path in one massive push.
This was probably the biggest single day of the chunk refactor. Going from per-cell GameObjects to chunk-based greedy meshing is a fundamental architecture change. The binary format (DBGR) uses palette compression per chunk and gzip — a 2MB JSON room file becomes about 4KB. The DDA raycast swap means we don’t need physics colliders on terrain at all anymore, which is a huge simplification. Getting the runtime playtest path working on the new grid system meant the whole pipeline is now unified from editor to play.
Added copy/paste and multi-item move with previews, plus selection quality of life improvements.
The copy/paste system stores entries as cell-relative offsets from a pivot point, so pasting works regardless of where you copied from. The move preview reuses the same ghost rendering as placement mode. The AABB nudge with Shift+WASDQE is one of those small additions that makes a big difference when you’re building rooms — you can fine-tune your selection box without having to re-drag it.
Added multi-selection support to the builder along with room settings UI, lava floor controls, and layer clip improvements.
Multi-selection was the big feature. It uses a HashSet for deduplication and stores entries as cell coordinates rather than object references, which fits the new proxy-free architecture. The room settings panel gives level designers control over things that were previously hardcoded — manual ceiling height is especially useful for rooms that don’t need the full default height. Layer clip perimeter draws a visible boundary at the clip plane so it’s obvious where the cutoff is.
Built the puzzle door and pressure plate system from scratch with animations, context menus, and plate assignment UI.
The door system uses metadata to link pressure plates to their target doors by ID. When a plate is activated at runtime, it looks up its assigned door and triggers the animation. The context menu integration lets you click a door, see which plates are assigned, and add or remove connections. This was a clean build from the ground up — the old trigger naming was confusing so I renamed things while I was in there.
Built a full patrol path editor with waypoint placement, path editing mode, and delete support.
The patrol path editor lets builders define waypoint routes that enemies follow when not in combat. You enter PathEdit mode, click to place waypoints, and they chain together into a path. Each path can be selected, modified, or deleted. The waypoint system integrates with the existing enemy goal system — patrol is just another goal that walks the enemy through the waypoint list. Debug logging was added early because waypoint ordering bugs are hard to spot visually. The scene reorganization into 01-Scenes was overdue for keeping things tidy.
Cleaned up files and started on new particle effects.
Short day. Mostly housekeeping and early work on some new particles that will get finished in a later session.
Added muzzle flash VFX, a SpellVFX pool, and soft-lock debug visuals for spell targeting.
The SpellVFX pool keeps particle systems alive and recycles them instead of instantiating new ones per cast. The muzzle flash fires at the cast origin and scales with spell tier. Soft-lock debug visuals draw the targeting cone and highlight what the auto-aim is locking onto, which was really helpful for tuning the targeting feel. The file reorganization moved VFX assets into a proper folder structure since they were getting scattered across the project.
Built the new spell system from scratch with projectile travel, AoE tiers, roll ranges, and debug tooling.
The spell system uses four axes to generate variety: element determines damage type and visuals, shape controls whether it’s a projectile, cone, or AoE, modifier adds effects like piercing or bouncing, and tier scales power. Roll ranges mean enemies and loot tables can generate spells within a tier range, giving natural progression. The DebugConfig editor was a productivity win — being able to spawn specific loot and spells from an editor window instead of playing through rooms saves a ton of testing time. Had to fix a subtle bug where aimed spell projectiles weren’t checking their lifetime correctly, causing them to persist forever.
Refactored the ranged charge and zoom system, balanced weapons and enemies, and designed the spell system.
The ranged charge refactor replaced the old multiplier system with a MinChargeSpeed approach. Instead of scaling damage by a charge multiplier, arrows now have a minimum speed they need to reach before firing. This feels more intuitive — you hold the draw until the bow is taut, then release. The spell system design doc lays out a 4-axis system where spells have element, shape, modifier, and tier dimensions. Implementation starts next session.
Massive weapon system rewrite across six phases -- new melee and ranged combat, dual-slot equipping, knockback, and overhauled animations.
This was a marathon session that touched almost every part of combat. The old weapon system was bolted on incrementally and had become a mess of special cases. The new system has clean data separation: CombatProfile defines timing, damage, knockback, and sweep parameters. Weapons reference a profile and provide their own prefab and animations. The horizontal vs vertical sweep split lets swords swing side to side while hammers come down from above, each with their own hit detection shapes. Knockback finally feels right — enemies react to hits with proper force and direction. The aim zoom for ranged weapons adds a nice tactical feel when lining up shots.
Quick update to the debugger configuration.
Light day. Just a small config tweak to the debug tooling.
Continued the AI rewrite with a parallel goal system, atomic goals, mutex flags, and a major enemy sensing and pathfinding refactor.
The mutex flag system was the key insight here. Goals like “attack” and “move” can run in parallel, but “melee attack” and “ranged attack” should be mutually exclusive. Flags let goals declare what resources they need, and the scheduler prevents conflicts. Moving pathfinding into goals means each goal can have its own pathing strategy — the melee goal paths directly to the target while the ranged goal tries to maintain distance. The sensing refactor gives enemies proper awareness of the player with detection ranges, line of sight, and search behavior when they lose track.
Built a goal-based enemy AI system from scratch with EnemyDefinition, debug gizmos, movement, and stair-down navigation edges.
This is the foundation of the new enemy AI. Instead of a monolithic state machine, enemies now have a goal-based system where each goal (attack, chase, patrol, search) is a discrete unit that can be swapped and combined. EnemyDefinition lets us configure different enemy types with different behaviors, speeds, and attack patterns. The debug gizmos were essential during development — you can see exactly what each enemy is thinking, where it wants to go, and what goal it’s executing. Stair-down edges in the nav graph mean enemies can now path downstairs instead of only going up.
Refactored the inventory to a 2-slot equip plus backpack system, added playtest return flow, and completed the RoomDefinition migration.
The inventory refactor was overdue. The old system was a flat list — now it’s two equip slots (main hand and off hand) plus a 3x5 backpack. This maps better to the combat system where you want quick weapon swapping. The RoomDefinition migration is a big deal: rooms are no longer Unity ScriptableObjects but serializable data that can be saved, loaded, shared, and uploaded. The playtest-before-publish requirement ensures builders actually test their rooms before inflicting them on other players.
Built the lobby with persistence, alcoves, and spawn markers, plus room pooling and confirmation dialogs.
The lobby is the player’s home base between dungeon runs. It needed its own persistence so customizations stick between sessions. Room pooling was important for performance — instead of destroying and recreating rooms on every transition, we now pool them and just reset their state. The alcove system lets the lobby have special spots for vendors, upgrade stations, and other interactables. Confirmation dialogs got a proper singleton so any system can pop one up without managing its own UI.
Added object selection with context menus, a builder hotbar, playtest mode, and overhauled camera controls.
Big builder UX day. The selection system lets you click on placed objects to select them, see their properties in a context menu, move them, or swap their variant. Pillar auto-height was a nice quality-of-life feature — pillars now automatically stretch from floor to ceiling instead of requiring manual height adjustment. Playtest mode is the star feature: hit a button in the builder and you’re immediately playing your room. No need to publish or switch scenes. Camera controls got a full overhaul to feel more responsive during building.
Grouped bridges by row, added drag volume wireframes, and built an enemy crowd separation system.
Bridge grouping was necessary because bridges placed in a row should look like one continuous span, not individual pieces. The reconstruction on load had to figure out which bridges were adjacent and merge their visuals. The drag wireframe is a simple box outline that shows the volume you’re filling — small thing but it makes mass placement way more usable. Enemy separation uses a simple repulsion force between nearby enemies so they spread out naturally during combat instead of all standing on the same tile.
Introduced a full 3D navigation graph with drop-down tracking and hallway extensions, plus a builder objectives system.
The 2D nav grid was hitting its limits — multi-floor rooms needed real 3D pathfinding. The new graph uses Vector3Int nodes with edges for lateral movement, stair traversal, and drop-downs. Getting the grid aligned correctly with the actual room geometry was the hardest part; stairs especially needed careful coordinate mapping. Hallway extensions let the nav graph reach into the connecting corridors between rooms so enemies can chase players through doors. The objectives system gives builders a way to set win conditions per room.
Pushed through four phases of the room refactor in one marathon session -- Supabase integration, catalog service, and async runtime room building.
This was a long session but the room pipeline is now end-to-end. You can build a room in the editor, publish it to Supabase, and another player can fetch and play it at runtime. The async build path was tricky — rooms need to generate meshes, set up colliders, and spawn items without freezing the game. The catalog service acts as a local cache so we don’t re-download rooms we’ve already fetched. Phase 3 had some gnarly bugs with mesh face generation and stair placement that took a while to track down.
Started the RoomAsset refactor with Phase 1, applied GUIDs to placeables, and moved GameConfig.
This is the beginning of a big refactor. The old room system used ScriptableObject assets directly, which made it hard to share rooms between players or save them to a server. Phase 1 introduces a serializable RoomDefinition format that can be saved as JSON and loaded back. Every placeable now gets a stable GUID so we can reference them reliably across save/load cycles. More phases coming soon.
Fixed a pile of bugs for the build, added an objectives system with timers, and tuned weapon feel.
This was a cleanup and stabilization day. The objectives system supports different goal types per room — kill all enemies, survive for a timer, reach an exit, etc. Per-room MaxBuildHeightCells lets each room define its own vertical limit instead of using a global value, which is important for rooms with different themes. The weapon tweaks were mostly about making hits feel more responsive and removing the spear which wasn’t fitting the combat style we’re going for.
Rewrote player animations and combat code, added melee swing hold, and built the run-complete UI.
The animation refactor was the big one today. The old combat code had animations tangled up with gameplay logic, making it hard to tune either independently. Now animations are driven by state and the combat system just sets state. The melee swing hold adds a satisfying charge mechanic. The run-complete flow gives players a proper ending screen with stats and a power meter showing their progression. Moving prompts to screen space means they stay readable regardless of camera angle.
Added a pooled room lighting system and improved melee sweep hit detection.
The room lighting controller manages a pool of lights that get placed based on room layout. Pooling was necessary because instantiating and destroying lights per room was causing hitches during transitions. The melee sweep improvement adds proper hit detection across the swing arc with de-duplication so enemies don’t get hit multiple times by the same swing. Combat profiles now have more options for tuning how sweeps feel.
Added placeable variant support, an audio system, scene loading, game settings, and a brightness controller.
Lots of systems work today. The variant system lets a single placeable definition have multiple visual options — in the builder you can pick which variant, and at runtime it spawns the right one. The audio system is intentionally simple: a manager that pools emitters, definitions that describe sounds, and emitters that play them. Scene loading needed a proper system instead of raw SceneManager calls so we could show loading UI and handle transitions cleanly. The options UI is basic for now but having the settings infrastructure in place means adding new options later is trivial.
Added bridge placeables, drag-based mass placement, and healing rooms to the builder.
The mass placement drag system lets you click and drag to fill or delete a volume of blocks at once, with a preview showing what you’re about to place. Bridges needed special handling since they group together visually — placing one bridge next to another needs to look like a continuous span. The BuilderInputManager refactor pulls all the scattered input handling into one place, which makes it much easier to add new placement modes going forward. Healing rooms are a simple flag on the room asset but they needed UI and runtime support wired up.
Big environment art push with lava glow, dust motes, stone textures, and a ballistic solver for enemy ranged attacks.
The lava glow system uses a custom shader that samples a generated lava map to determine glow intensity per cell. It took a couple iterations to get the colors right — there was a bug where everything was just green. The dust motes and torches really sell the dungeon atmosphere now. On the gameplay side, the ballistic solver gives enemies the ability to lob projectiles in an arc, which feels much better than the old straight-line shots. The debug toggle centralization was overdue — having scattered debug flags was getting hard to manage.
Late night session fixing navigation, room rotation, and moving debug controls around.
This was a short late-night session focused on quality-of-life fixes. The nav system needed adjustments to handle level-based steps properly, and there were some raycast issues that were causing buttons to not register correctly. Also shuffled the debug controls to a more accessible location and built out a test room to verify everything was working together.