2DBonk
Systems Design | Gameplay Programming | UI/UX Implementation | Content Pipeline
Play The Game →Summary
2DBonk is a humor-focused 2D survivors-style roguelike prototype built in Unity in ~2.5 weeks.
The game combines horde survival combat with increased player agency through inventory management
and rhythm-based “Aura Post” challenges that reward powerful stat upgrades during a run.
The project was designed as a systems showcase: modular weapons, scalable stat architecture,
data-driven enemy spawning, and a full run loop across multiple stages with build-defining rewards.
The prototype was later presented at the FIEA Industry Review, where it was selected as a finalist
and received recognition in the “Most Addictive Game” category.
Project Details
Content
3 playable characters with unique starter weapons and level-scaling bonuses
5 weapons with unique behaviour modular upgradeable stats (damage, rate, duration, size, etc.)
12 inventory items with rarity tiers and unique behaviors
9 bobblehead passives obtained through level progression
10+ enemy types including bosses and final swarm encounters
3 stages following a progression loop (Aura Posts → boss → portal)
Systems
Modular stat architecture supporting stacking modifiers from multiple gameplay systems
Data-driven enemy spawn tables with timed events (boss spawns, swarms, final swarm state)
Object pooling system supporting large enemy counts (1000+ active enemies at ~90 FPS)
Aura Post rhythm challenge system granting build-defining stat rewards
Full run UI suite including menus, inventory, shops, reward selection, and HUD
Team and Time
Team Size: 1 (Solo project)
Time: ~2.5 weeks
Constraint: 2D-only production requirement
Goals
The goal of 2DBonk was to design and implement a complete survivors-style roguelike loop within a short
production
window while experimenting with systems that give the player more agency than typical games in the genre.
Inspired by titles such as Vampire Survivors and Megabonk, the project focuses on large-scale enemy
encounters and
build-driven progression. However, the design introduces additional decision-making layers through an
inventory
system, collectible passive items, and Aura Post challenges that require players to complete
musical-rhythm-style
inputs
while surviving enemy waves in real time.
From a technical design perspective, the project aimed to build a scalable systems architecture capable of
supporting large enemy counts, multiple stat modifiers, and modular gameplay content such as weapons,
items, and
enemy behaviors. These systems were designed to remain flexible so that new content could be introduced
quickly
during development.
The prototype was developed over approximately 2.5 weeks under a 2D production constraint, with a strong
emphasis
on rapidly implementing interconnected gameplay systems that could support a full run loop across multiple
stages.
Systems
Stat Architecture
Centralized stat architecture managed through a dedicated Stat Manager system
Each stat stored as a structured value containing base value, flat modifiers, and percentage modifiers
Supports both absolute increases (+5 HP, +1 projectile) and relative scaling (+10% damage, +20% fire rate)
Multiple gameplay systems feed into the same stat pipeline, including leveling rewards, Aura Post bonuses,
inventory
items, bobbleheads, and permanent shop upgrades
Weapon stats inherit relevant player modifiers while maintaining independent stat definitions when needed
Designed to keep stat updates consistent and predictable while enabling complex build synergies
Weapon Framework
Modular weapon framework with a shared interface supporting multiple firing patterns
Weapon execution styles include constant (always active) and cooldown-based (triggered
attacks)
behaviors
Each weapon controls its own behavior via prefab-driven logic (spawns, hitboxes, projectiles, targeting
rules)
Upgrade pipeline applies only relevant scaling stats per weapon (e.g., Big Smile ignores projectile count)
Designed for rapid weapon iteration without rewriting core combat code
Inventory, Items, and Bobbleheads
Limited-slot inventory system designed to increase player decision-making during runs
Items feature rarity tiers (uncommon → legendary) and provide build-defining stat bonuses or unique
effects
Item effects implemented as ScriptableObjects with behavior prefabs (e.g., periodic XP vacuum,
kill-scaling damage)
Bobbleheads act as upgradable passive rewards that modify key stats and influence build direction
Built to support rapid content expansion through data-driven definitions
Spawning, Events, and Performance
Data-driven spawn table system per stage using ScriptableObjects (weights, time windows, caps, boss rules)
Event system supports special phases such as boss windows, timed swarms, and a permanent final swarm mode
Enemies pooled on level start to avoid runtime instantiation spikes and support high entity counts
Stress-tested with 1000+ active enemies at ~90 FPS (1700+ at ~60 FPS in editor testing)
Aura Post Rhythm Challenge
“Aura Posts” introduce an active skill challenge inside a survivors-style run loop
Rhythm-input mini-game grants stat rewards while enemies remain active (risk/reward tension)
Rewards scale by rarity and are influenced by the player’s Luck stat (which can be upgraded)
Rewards integrate directly into the stat architecture to enable build synergy and progression spikes
Designed to increase player agency beyond typical auto-attack survivor mechanics
Technical Challenge: Scalable Stat Architecture
2DBonk features a large number of gameplay statistics and multiple systems that modify them during a run,
including leveling rewards, Aura Post bonuses, inventory items, bobbleheads, permanent upgrades, and
weapon
scaling.
Because many of these systems interact simultaneously, maintaining consistent stat values across gameplay,
UI, and weapon logic became a major technical challenge. Without a centralized system, stat updates could
easily
become fragmented or produce inconsistent results when multiple modifiers stacked together.
The goal was to create a stat architecture that allowed many independent gameplay systems to modify player
statistics while keeping the final values predictable and easy to query across the codebase.
Solution
I implemented a centralized Stat Manager responsible for calculating and exposing all runtime stat
values.
Each stat is stored as a structured value containing a base value, accumulated flat modifiers, and
percentage
modifiers.
Final values are calculated using a consistent formula:
final = (base + flat modifiers) * (1 + percentage modifiers).
Gameplay systems modify stats through the Stat Manager rather than directly editing gameplay variables.
This allowed systems such as items, aura rewards, leveling bonuses, and permanent upgrades to stack
cleanly
while remaining independent from one another.
Weapons maintain their own upgrade definitions but inherit relevant player stats through the same
pipeline.
For example, attack speed, damage multipliers, and duration are shared, while weapon-specific attributes
(such as projectile count or pierce) are only applied where relevant.
Systems query final stat values through a consistent API (e.g.
StatManager.GetStat(StatTypes.Damage)),
ensuring that gameplay behavior, UI feedback, and weapon calculations all reference the same computed
values.
Outcome
This architecture allowed multiple progression systems to interact simultaneously without creating
conflicting gameplay behavior. New items, weapons, and stat bonuses could be added quickly during
development
while maintaining predictable stacking rules.
The centralized stat pipeline also simplified integration between combat, inventory, leveling rewards,
and UI systems, enabling rapid iteration during the short 2.5 week development window.
Technical Challenge: Large-Scale Enemy Spawning
As a survivors-style game, 2DBonk required large numbers of enemies to appear simultaneously on screen.
During testing, the game frequently maintained hundreds of active enemies while continuing to spawn new
waves based on progression events such as bosses, swarms, and final survival phases.
Instantiating enemies dynamically during gameplay quickly became a performance bottleneck, especially
when enemy counts increased into the hundreds. A spawning system was required that could support large
entity counts while maintaining stable frame rates.
Solution
I implemented an enemy spawning architecture built around ScriptableObject spawn tables combined
with
an object pooling system.
Each level references a spawn table defining which enemy types can appear, their spawn weights, time
ranges,
and special conditions such as boss encounters or swarm phases.
At level initialization, enemies are pre-instantiated and stored in pools grouped by enemy type.
The spawn system retrieves enemies from these pools rather than creating new instances at runtime.
The spawn tables also support event-driven spawning behavior, including:
• Boss encounters that temporarily pause normal spawns
• Swarm phases that increase spawn intensity for a limited duration
• A final survival phase that triggers continuous enemy waves when the level timer expires
Outcome
This system allowed the game to support large numbers of enemies simultaneously while maintaining stable
performance. During testing, the prototype was able to sustain approximately 1000 concurrent enemies at
~90 FPS, with stress tests reaching roughly 1700 enemies at ~60 FPS in the editor.
The spawn table architecture also allowed enemy encounters to be tuned through data rather than code,
enabling rapid iteration of pacing and difficulty during development.