4. Implementation
During the implementation of Capoo, we encountered several technical and architectural challenges that significantly influenced how we structured our codebase and implemented gameplay mechanics. These challenges not only tested our ability to adapt existing libraries but also reinforced the importance of good software engineering practices such as object-oriented design, modularization, and debugging of physics simulations.
We summarize our major challenges below:
Challenge 1: Spine Model Integration
One of our key design goals was to bring the personality of Capoo to life through expressive animation. To achieve this, we used the Spine animation model from Capoo Pals. However, p5.js, our main framework for game logic, does not natively support Spine.
To solve this, we adopted a hybrid rendering solution:
- We integrated Three.js specifically to render the Spine character model.
- The game logic, UI, and gameplay rendering remained within the p5.js environment.
This introduced complexity in synchronising game state between the two rendering contexts. For example, the Capoo model’s facing direction, animation state, and position had to be manually updated based on logic handled by GameModel
and Capoo
classes in p5.js. Despite the complexity, this approach allowed us to maintain p5.js’s simplicity while leveraging Three.js’s flexibility for skeletal animation.
Key Takeaway: This integration allowed us to retain the charming animation style of Capoo, but required careful coordination between libraries and update loops to ensure smooth rendering.
Challenge 2: Object-Oriented Programming Refactor
Our initial prototype was built in a script-style format, where all logic was spread across multiple JavaScript files attached directly to the HTML. This led to tight coupling, poor reusability, and difficulties in managing the growing complexity of the game logic.
To improve code structure and maintainability, we undertook a full refactor using OOP principles:
- We created clear class hierarchies (
AbstractEntity
,AbstractTerrain
,Capoo
,Switch
,Potion
, etc.). - We used encapsulation to hide internal state and expose only necessary interfaces (e.g.,
update()
,collide()
,move()
). - We applied inheritance to create polymorphic behaviors (e.g., all terrain elements inherit from
AbstractTerrain
). - We transitioned to ES6 modules, enabling better file separation and dependency management.
This refactor took nearly a full sprint but paid off by enabling cleaner logic separation, reusable systems, and better collaboration across the team.
Key Takeaway: Refactoring for OOP was essential for scalability, especially with multiple types of interactive elements and physics objects sharing behavior.
Challenge 3: Physics and Collision Bugs
Implementing reliable physics interactions and collision detection was another significant hurdle. Early in development, we encountered several issues:
- Capoo would clip through terrain or platforms, especially at corners.
- The character could get stuck to walls, due to overlapping bounding boxes and imprecise collision checks.
- Inconsistent jump mechanics, caused by timing issues with
isGrounded
detection and terrain state updates.
To address this, we implemented:
- A more precise tile-based collision system, where each entity checks collisions using adjusted hitboxes relative to its position and sprite dimensions.
- Logical state flags (e.g.,
onGround
,canJump
) to control character state transitions and avoid unintended behaviors. - Frame-wise correction in
update()
methods to prevent multi-frame glitches caused by high speed or overlapping collisions.
After multiple rounds of debugging and playtesting, we were able to achieve consistent and stable interactions, with Capoo responding correctly to terrain, jump inputs, and puzzle objects like Switches
and Potion
.
Key Takeaway: Stable and responsive physics is critical in a puzzle-platformer. Careful tuning of hitboxes and state logic was necessary to ensure playability and fairness.
Conclusion
Each challenge forced us to adapt and improve our technical approach. From animation system integration, to architecture refactoring, to gameplay responsiveness, these implementation problems guided the evolution of Capoo and shaped its final experience. Despite early difficulties, they ultimately contributed to a more stable, engaging, and maintainable game.