Billy Basso on code architecture of Animal Well!
Audio Brief
Show transcript
This episode covers Billy Basso's seven-year solo development journey creating his game Animal Well, from building a custom engine to his pragmatic architectural philosophies.
There are four key takeaways from this conversation. First, rapid iteration, especially through hot-reloading, provides a massive productivity boost for solo developers. Second, a robust and stable architecture can be achieved through simplicity, organizing all program data based on its lifetime. Third, adopting a pragmatic "simplest thing first" approach avoids premature optimization and maintains momentum on long projects. Fourth, unconventional, simple techniques can effectively solve complex development challenges.
Basso champions hot-reloading game code as the single biggest win for solo development. This technique allows for extremely quick iteration without needing complex editor GUIs, significantly boosting productivity and enabling a fast feedback loop. His design philosophy also emphasizes discovery, with Animal Well intentionally mysterious, foregoing tutorials to encourage player-driven exploration.
The game's exceptional stability comes from a data-oriented architecture organized by data lifetimes. Memory is structured into Global, Game, and Screen states, ensuring clear boundaries and simplifying memory management. This barebones C-style approach avoids complex C++ features like constructors and inheritance in favor of plain data structs for greater control.
Basso's development strategy is to "do the dumbest, most obvious thing first." He only refactors or builds complex systems when they become a clear bottleneck, avoiding over-engineering. This pragmatic approach is crucial for maintaining momentum on a demanding solo project, especially when facing a "live with it" philosophy after one or two revisions.
For solving complex problems, Basso leverages simple, unconventional techniques like C preprocessor X-macros for data-driven design. This trick allows defining lists of game entities, shaders, or strings in one place. By redefining a macro, he can auto-generate code for various contexts, streamlining content creation efficiently without complex code generation tools.
The episode highlights that focusing on core principles like data lifetime, pragmatic iteration, and embracing simplicity were key to bringing Animal Well to fruition as a solo endeavor.
Episode Overview
- Billy Basso discusses the seven-year solo development journey of his game Animal Well, from its origins as a side project to a fully-realized title.
- The episode explores Basso's core technical philosophies, including building a custom engine from scratch, embracing a simple C-style approach, and leveraging hot-reloading for rapid iteration.
- Basso details his game's unique architecture, which is organized around data lifetimes to ensure stability and simplify memory management.
- The conversation covers a clever C preprocessor "X-Macro" trick used for data-driven design, and Basso's pragmatic approach of implementing the simplest solution first.
- Basso shares personal insights into his work ethic, his relationship with his publisher videogamedunkey, and his plans for future projects.
Key Concepts
- Design Philosophy of Discovery: Animal Well is intentionally mysterious, providing no tutorials or hand-holding to encourage player-driven exploration, a reaction against the slow starts of many modern games.
- Barebones C-Style Programming: Basso champions a simplified C++ approach, avoiding complex features like constructors and inheritance in favor of plain data structs and explicit functions for greater control and clarity.
- Data-Oriented Architecture: The game's memory is structured into three main lifetimes: Global State (application-level), Game State (save file-level), and Screen State (transient). This design is key to the game's exceptional stability.
- Iterative and Pragmatic Development: Basso’s strategy is to "do the dumbest, most obvious thing first," only refactoring or building complex systems when they become a clear bottleneck, thus avoiding over-engineering.
- The Power of Hot-Reloading: Identified as the "single biggest win" for a solo developer, hot-reloading game code allowed Basso to iterate extremely quickly without needing complex editor GUIs.
- Data-Driven Design via X-Macros: Basso used a C preprocessor trick to define lists of game entities, shaders, and strings in one place. By redefining a macro, he could auto-generate code for various contexts (updating, drawing, etc.), streamlining content creation.
- Solo Development Philosophy: To maintain momentum and finish the game, Basso adopted a rule to "live with" systems after one or two revisions rather than getting trapped in an endless cycle of perfecting them.
Quotes
- At 2:33 - "I was getting kind of frustrated with a lot of modern games that... had a really slow start and they would... load you down with just like tutorials and... exposition." - Basso on his motivation to design a game that respects the player's intelligence.
- At 29:23 - "The biggest thing that has helped me keep the code organized is really having a solid understanding of... the lifetime of where data lives." - Basso explains that his primary architectural principle is organizing data and memory based on when it's needed during gameplay.
- At 59:17 - "I was happy to make the dumb version first and just like see how far it took me, and then when it actually became an issue... I had to try harder and make something more complicated." - Summarizing his philosophy of iterative design, where he avoids over-engineering and only builds complex systems out of necessity.
- At 1:06:22 - "It's a way to almost get like code generation without actually needing to do anything difficult, you're just kind of abusing the C preprocessor." - Basso acknowledges the unconventional but effective nature of his macro technique.
- At 1:40:15 - "He's like actually really shy and soft-spoken in real life and the opposite of what you would expect." - Basso describes his surprise upon meeting his publisher, videogamedunkey, for the first time.
Takeaways
- Prioritize rapid iteration over complex tools; features like hot-reloading can provide a massive productivity boost, especially for solo developers.
- A robust and stable architecture can be achieved through simplicity, such as organizing all program data based on its lifetime.
- Adopt a pragmatic "simplest thing first" approach to development to avoid premature optimization and maintain momentum on a long project.
- Don't be afraid to use simple, unconventional techniques like C preprocessor macros to solve complex problems like code generation.