💡 Inspiration

We have always been huge fans of roguelike deckbuilders, specifically the genre-defining Slay the Spire. We were fascinated not just by the gameplay, but by the underlying architecture: How do you efficiently manage a deck state? How does a discard pile shuffle back into a draw pile without losing data? We built Chambers to deconstruct these mechanics and rebuild them from the ground up, focusing on creating a robust system that handles card interactions seamlessly.

🃏 What it does

Chambers is a turn-based survival card game.

  • The Loop: Players start with a basic deck and face waves of enemies.
  • The Strategy: Every turn, you draw a hand of cards. You must decide whether to spend your energy attacking the enemy or blocking incoming damage.
  • The Economy: Between combats, players visit a Shop where they can buy powerful new cards or pay to remove weak ones, constantly refining their deck for better synergy.
  • The Goal: Survive as long as possible against increasingly difficult odds.

🛠️ How we built it

We approached this project with a heavy focus on architecture and Test-Driven Development (TDD):

  1. Core Logic (TypeScript/Jest): We started by writing the game framework in a purely logical environment using Node.js. This allowed us to write unit tests for every single card interaction, shuffle mechanic, and damage calculation to ensure the backend was bug-free.
  2. Game Engine (Unity & C#): We translated these systems into Unity, using ScriptableObjects to manage card data and creating a clean UI to visualize the deck states.
  3. State Management: We implemented a strict state machine to handle the phases of battle (Draw Phase -> Play Phase -> Discard Phase -> Enemy Turn).

🏔️ Challenges we ran into

  • Cyclical Deck Logic: Handling the moment the Draw Pile empties was trickier than expected. We had to ensure the Discard Pile was shuffled and moved over correctly without interrupting the player's turn or causing null reference errors.
  • UI Synchronization: Keeping the visual representation of the hand in sync with the actual data backend was a challenge. Animations often lagged behind the logic, requiring us to implement event-based updates.
  • Balancing: Creating cards is easy; making them fair is hard. We struggled initially with "infinite loops" where a player could draw their whole deck in one turn.

🏆 Accomplishments that we're proud of

  • The Shop System: We successfully implemented a fully functional economy system where players can buy and purge cards, which updates the deck in real-time.
  • Robust Framework: We are proud of the code structure. Separating the data logic from the visual layer means we can add new cards in seconds just by defining their values, without writing new code.
  • Playable Web Build: Getting the game optimized and running smoothly on Unity Play (WebGL) so anyone can play it instantly in a browser.

🧠 What we learned

  • The power of TDD: Writing tests for our card logic before putting it into Unity saved us hours of debugging.
  • Game Design: We learned that "randomness" in games needs to be controlled. True RNG feels unfair; "bag" systems (like shuffling a discard pile) feel much better to play.
  • Scope Management: We learned to prioritize core mechanics (the battle loop) over flashy graphics to ensure we delivered a finished product.

🚀 What's next for Chambers

  • Relics & Artifacts: Adding passive items that persist between battles to allow for deeper builds.
  • Visual Polish: Adding particle effects for attacks and more "juice" to the card movements.
  • New Enemies: introducing enemies with complex intent patterns (buffing themselves, debuffing the player).
  • Mobile Port: The touch controls are already simple, so we plan to optimize the UI for mobile screens.

Built With

Share this project:

Updates