I'm planning to over-engineer a simple game to learn about architecture and design. I explain the game mechanics and potential future features, as well as the chosen layered architecture with MVC pattern and persistence layer. Lastly, I share the lessons learned from intentionally over-engineering a project.
I'm on a mission to unleash my inner game developer and satisfy my itch for learning architecture and design. With some free time on my hands and the realization that I'm entering the 'overengineering' phase of my career, I'm excited to dive into creating simple yet over-engineered games. While over-engineering may not be a good practice, it can be a valuable learning step for this stage of my learning journey.
And what better way to learn than by starting with a childhood favourite of mine - a penguin trying to fly off a ski jump?
But this time, I'm swapping out the penguin for a ball and kicking it to achieve maximum air distance. Join me on this journey as I explore game development and gain interesting insights and lessons through over-engineering this game on purpose.
In a nutshell, the game will be about kicking a ball as far as possible. Initially, it will be a football (soccer ball for those that play football with their hands). An undulating terrain will allow the ball to pick up speed on a downward slope and lift back up when leaving an upwards slope.
In its first iteration, the game will have the following mechanics:
Kicking the Ball
To kick the ball, the player will need to select an angle and speed.
The angle will slide between 5 and 85 degrees, and the 'action' key will lock it in place.
The speed will slide between 0 and 100, and the 'action' key will engage the ball.
Once the ball is kicked, it will fly into the air in an elliptical movement. Affected by gravity and friction
The player can press the 'action' key to make the ball behave as if it was heavier, causing it to drop faster.
The ball will pick up speed and travel furt is on a downward slope.
When the ball is on a flat surface, it will retain its speed.
When the ball is on an upward slope, it will slow down and travel a shorter distance.
Future Game Mechanics
Here are some potential game mechanics that could be added in future iterations of the game:
An achievement system rewards players for reaching certain milestones or completing specific challenges.
Power-ups and items can be collected during gameplay to give players an advantage or enhance their abilities.
Different types of balls and kickers with unique characteristics and abilities.
- A dynamic sound system that changes based on the player's actions and the environment. Various backgrounds and settings can add more diversity and visual interest to the game-
- A weather system that affects the ball's movement, such as wind or rain.
Considering these potential game mechanics during the design and architecture phases, the game could be more engaging and enjoyable for players.
Why Over Engineer
I want to over-engineer this simple game because I believe all programmers go through an 'over-engineering' phase, and I want to get it out of the way. By intentionally over-engineering this game, I hope to satisfy my itch for learning architecture and design, implementing layered architecture, MVC pattern, Command patterns, and other design and architecture decisions.
Although I have a heavy risk of falling into a Big Design Up Front anti-pattern, I believe that throughout this process, I will gain valuable insights and lessons that will be useful in my future projects.
So, while over-engineering may not be a good practice in general, it can be a valuable learning step for my situation.
The general architecture I have chosen to organize the code is a Layered Architecture with an MVC pattern. On top of that, I have also decided to have a persistence layer to decouple data persistence from the game logic.
Presentation Layer (View)
Responsible for rendering game objects and visual elements on the screen. It handles graphics, animations, and sound (including background music and sound effects). Contains classes like
This layer is also responsible for listening to user inputs (button presses, touch events, etc.)
The idea behind separating this layer is to allow me to easily change the look and feel of the game (sprites, sound files, etc.)
Controller Layer (Controller)
Manages the flow of data between the Presentation Layer and the Game Logic Layer and handles user input. Contains classes like
It will act as the glue between the Game logic layer and the presentation layer, by asking the game logic layer to update the game state and the presentation layer to render said inputs
Game Logic Layer (Model)
Contains the core game logic, rules, and game object properties. Includes classes like
Terrain, and any other game objects I might introduce.
It is responsible for defining how game objects interact, how the game state evolves, and any calculations or updates needed for game progression.
A sub-layer of this layer will be the Physics Layer, which includes classes or modules for handling physics calculations and interactions.
Separating this layer will allow me to keep the game logic contained and change game mechanics and behaviours without worrying about visuals or input handling.
Persistence Layer (Data)
Responsible for loading, saving, and managing game data, such as player progress, high scores, or game settings. Contains classes or modules for handling data storage and retrieval, such as
Over-engineering may not always be a good practice, but it can be a valuable learning step for developers who want to learn architecture and design.
Starting with a simple game and intentionally over-engineering it can provide insights and lessons that can be helpful in future projects.
The proposed architecture separates the presentation layer responsible for rendering game objects and visual elements on the screen, the controller layer accountable for managing the flow of data between the presentation layer and the game logic layer, the game logic layer containing the core game logic, rules, and game object properties, and the persistence layer responsible for loading, saving, and managing game data.
UML enters the chat... ☺️😉😀