What Zelda taught me about models and software development
Sticking to models really does pay off
The Legend of Zelda: Tears of the Kingdom is not just a game but a source of inspiration for me. I am fascinated by its intricate detail, the boundless creativity it allows players, and the sense of realism it evokes. The multitude of ways to solve puzzles using different mechanics and resources is a testament to the game's depth. Even watching YouTubers experiment with the game is a source of entertainment and learning for my kids and me.
Recently, I stumbled upon a presentation by the lead developers at the Game Developers Conference 2024. Their ability to create such an immersive world in Tears of the Kingdom, while staying true to two underlying principles (multiplicative gameplay and building a system that makes fun things happen), was truly inspiring. It made me ponder what we can learn from this for 'typical' software development. The potential for learning and growth is immense.
Where do models exist in software development?
The term model strikes fear in many professionals, but in reality, they exist all around us in software engineering:
In code as 'frameworks' that implement patterns. These include generic language frameworks (Spring, Rails, etc.) and domain-specific frameworks that teams build for themselves (e.g. this is how we model different types of users).
System architecture, including how various domains and services are defined and interact, and sources of truth for specific data models. Effective modelling minimises unnecessary coupling between teams and services that can compromise performance and development velocity.
Data and API models, such as third-normal forms of database schemas and API specifications. These require high-quality modelling to ensure users can continue interacting with our systems even as we extend them.
Conceptual models that guide how our company's products and features should fit together. This is critical to ensure our products are coherent to users and platforms can be built to serve all products.
The game's guiding principles
I highly recommend watching their presentation (it's a lot of fun and an excellent example of a well-structured talk that breaks through language barriers). They repeatedly talk about two concepts:
Multiplicative gameplay: Players can combine ('multiply') actions and objects to create many different ways to play.
Building a system that makes fun things happen or enabling unique interactions without dedicated implementation.
To achieve this, the entire world was rule-based. For example, object models had physical properties like mass and inertia, and the system computed their interactions. In contrast, the more straightforward solution would be faking it with intelligent animations.
It's not about the models; it's about the outcome
The principles discuss the outcomes of how players interact with the game. Leveraging models is the means to achieve multiplicative gameplay and infinite unique interactions that make the game fun.
Models can only be successfully implemented if all stakeholders buy into them. Conceptual models need to be understood by product managers, designers, and other cross-functional partners so that the entire team can build solutions that leverage them. Even code frameworks that only engineers usually care about need to be understood by managers who question why we are spending time on them. Starting with the value we're trying to unlock is critical. For example, our products must integrate with many third-party systems, so we need a flexible extensibility model. Or we want to satisfy sophisticated users who wish to plug-and-play features, so we need composable components without testing infinite combinations.
Models must be understood and adopted by the entire team
The presentation discusses the importance of all team members understanding and adopting the models: developers, game designers, artists, and the sound team. Game designers and artists help build and refine the model alongside developers based on reality. I see parallels to how product managers and designers should interact with engineers to incorporate multiple perspectives of real-world requirements into models.
A common anti-pattern is engineers 'owning the modelling' rather than being a true cross-functional collaboration. While this works for low-level models in code, it dooms API and conceptual modelling from the start. Engineers can focus on unnecessary edge cases that overcomplicate models and fail to prioritise happy paths. Without a good understanding of the models, product managers can design customer solutions that fail to leverage a model's flexibility. Try to avoid this situation by getting buy-in first and focusing on value. Unfortunately, not everyone appreciates the need for collaborative model development, and if this is the case, set your expectations lower.
Incremental steps to a complete model
Designing and implementing complete models takes significant time and resolve. One of the presenters talked about their dread when they realised how much work it would be to build a full physics model and that developers were questioning their resolve to see the world fall apart due to the mix of physics and non-physics modelling during development. Their solution was a continual belief in the underlying principles and a pattern of prototyping specific areas using simpler non-physics modelling before translating to physics models for the objects.
More generally, I relate this to incrementally building out models by domain. This breaks the overall system into smaller manageable chunks, and eventually, the entire system is modelled over time.
Escape hatches through model customisation
"All models are wrong, but some are useful". Many of us may remember this statement from studying statistics, but I was surprised to hear how this was true in the Tears of the Kingdom physics models, as we know a lot about real-world physics. Flat objects like boards or slabs appear thicker in the game than the physics model parameters suggest. This was done to help players grab these objects in the game. Another example was adding suspension to wheels, which doesn't exist in real life.
I take away two points:
The overarching goal (of gameplay) trumps the purity of the model. We can't tell users 'the model says X' if it doesn't make sense to them.
Changes were made by tweaking the parameters of models, not an 'anything goes' hack, like incorporating non-physics models. We need to build escape hatches into our models by sticking with well-defined interfaces. In this case, the interface is model parameters, and the escape hatch is per object model definitions.
Knowing when to stop
We can plot a graph of model value versus model complexity, and we aim for the peak. If a model is too simple, it won't match the real world and will be unsatisfactory. We then add more to the model, and eventually, it becomes too complex with too many variables to consider. The presentation discusses how simple models for sound attenuation based on distance are insufficient (or we'd be able to hear a rooster call from Mt Fuji in Tokyo). The team then added air attenuation, low-pass filtering and reverb to mix in ambient sounds to provide a more realistic and valuable model.
Sometimes, we can apply step changes to increase a model's value without affecting its complexity. In this talk, the presenter discussed the need to embrace raytracing and 3D voxel models to automatically gather parameters for a more sophisticated sound model, including echos and obstructions.
I believe the same applies to typical software engineering. If a model is too abstract and hand-wavy, it serves limited value, probably just some high-level alignment between teams. We add more details to make them practical (more data fields, examples, rules, and explicit codification to avoid ambiguity). Eventually, models become too complicated, and we must decide whether to invest in a step change (e.g., new concepts or perhaps auto-generation) or simply stop.
Acceptable model complexity depends heavily on the stakeholders who need to understand it. Remember that product managers, designers, other functions, and even all engineers on the team need to understand the model. This is another reason why collaboratively developing models with cross-functional partners is critical.
Summary
Thinking in models and abstraction is not always well appreciated. Seeing this talk and the outcome of a great game gives me more resolve to stick to my guns and keep pushing for model-based systems, provided we achieve the value we set out to.