A practical guide to game development with MVCS
How I built a game in Unity from scratch by adapting well-known software design patterns into something new!
In 2018, my partner and I decided to build an app together in Unity. The result was Fit Me Challenges, an app aimed at taking on small fitness challenges with a slight gamified twist.
As most side projects go, the code is nothing to celebrate. However, a software design pattern that I adapted turned out to be far more helpful than I expected. This pattern was MVCS.
What is MVCS?
This particular acronym stands for models, views, controllers and services.
It is a derivative of other software design patterns, Model-View-Controller (MVC) and Model-View-Controller-Store (MVCS).
MVCS is an architectural design pattern that helps define relationships between entities within an application. When applied, it helps to breakdown larger scenarios into smaller objects and defined behaviors.
I use this pattern not as a blueprint that must be strictly adhered to, but a set of guidelines to help:
- Reduce decision making
- Reduce code complexity
- Increase code readability
- Simplify project file and folder structures
There are "rules." But some can be bent, others can be broken.
What are the rules?
The rules defined below are there to avoid any overlap in responsibility. The boundaries these rules create also ensure that classes do not grow in complexity, which improves readability.
That being said, the general rule is:
Controllers fetch models from services and present them in views.
The pattern also helps with naming conventions. Each entity type is appended to the class name and filename, allowing me to quickly navigate my project for the logic I am after.
The rules for each entity are as follows.
MODEL
- Restricted to primitive types only e.g.
int
,float
,string
etc - Can include light logic over private member variables
- Models do not reference each other directly (decoupled)
VIEW
- Can use primitive types or models
- The only entity responsible for presenting data to a user
- Notifies the controllers about user interaction
CONTROLLER
- Contains all of the "game" logic
- Fetches data from services
- Updates models based on user input
- Manages the flow between different parts of the application
SERVICE
- Handles data persistence and retrieval
- Manages external API calls
- Provides a clean interface for data access
- Can contain business logic that doesn't fit in controllers
Benefits of MVCS
When implemented correctly, MVCS provides several key benefits:
- Separation of Concerns: Each entity has a clear, single responsibility
- Testability: Individual components can be tested in isolation
- Maintainability: Code is easier to understand and modify
- Scalability: New features can be added without affecting existing code
- Team Collaboration: Different developers can work on different entities
Implementation Example
Here's a simple example of how MVCS might look in Unity:
When to Use MVCS
MVCS is particularly useful when:
- Building complex applications with multiple features
- Working in teams where code organization is crucial
- Creating applications that need to be maintained long-term
- Building applications that may need to scale significantly
Conclusion
MVCS is not a silver bullet, but it's a powerful tool for organizing code in a way that makes it more maintainable and understandable. The key is to use it as a guideline rather than a strict rulebook, adapting it to fit your specific project needs.
Remember, the goal is to write code that you (and others) can understand and maintain months or years down the line. MVCS helps achieve that goal by providing a clear structure for organizing your thoughts and code.
Happy coding!