Logo

dev-resources.site

for different kinds of informations.

Architecture design of my game My Pixel Plant

Published at
1/2/2024
Categories
gamedev
games
videogame
devlog
Author
jorensm
Categories
4 categories in total
gamedev
open
games
open
videogame
open
devlog
open
Author
7 person written this
jorensm
open
Architecture design of my game My Pixel Plant

Hi dear readers!

Recently I published my small browser game My Pixel Plant. Developing it was lots of fun and so I thought I'd share some insights into how I was making it. I'm willing to guess that many (or at least some) of us here are also game developers, so I thought this would make for an interesting read!

In this article I will share with you the architecture design behind my game.

Source code

Overview

The code is written purely in TypeScript/HTML/CSS, and it took me around 30 hours to write it. I'm using Webpack to bundle my code. When writing my code, I tried to keep portability in mind to allow for easy porting to other platforms, if needed.

The architecture

So the basic architecture of my game is like so: I have a base Game class, and that Game class has several "manager" component classes that manage different parts of the game.

The current manager classes are as follows:

  • UIManager
  • SaveManager

I am planning to refactor the Game class to also have a PlantManager that manages the plant behavior, as the code for that currently resides in Game, which violates the Single Responsibility Principle

I know that the manager pattern has received some critique in the past, but I found that it worked very well in my game as a means of organizing and decoupling code.

In addition to manager classes, I also have several low-level modules that handle stuff like rendering and cache. These classes don't 'manage' anything, but give access to low-level functionality such as rendering and storage. I want to eventually implement an interface for each of the low-level classes, so that they can be swapped for others, for example for another renderer. This would allow for my game to be more easily portable to other platforms.

There are the following low-level classes:

  • Renderer
  • Cache
  • Storage

Additionally, I have a Plant class that holds the data and behavior of the plant.

Low-level classes

The low level classes are the classes that handle the low level behavior such as rendering and storage. These classes are cruicial for allowing for easy porting of the game.

Renderer

The Renderer class is the one responsible for rendering. It holds methods such as drawPlant, drawSprite, drawRect, drawProgressBar. It uses the HTML canvas for rendering. It should be possible to easily swap it for a different renderer class that uses something other than Canvas (OpenGL/WebGL) for example. I plan to accoplish this by creating a Renderer interface/abstract class that the subclasses must implement, so the game can work with any type of renderer.

Source code for the Renderer class

Storage

The Storage class is the class responsible for persistent data storage, which is the save data in the case of this game. This class uses the browser's localStorage, but just like Renderer, should ideally be swappable with other types of storage such as file storage

Source code for the Storage class

Cache

The Cache class is responsible for storing non-persistent, per-session data. This is so that the game runs faster and doesn't have to re-download an image each time it is needed. Under the hood it is basically just an object that can be accessed through Cache's getter and setter

Source code for the Cache class

Manager classes

The managers manage different parts of the game and its behaviors

UIManager

The UIManager class manages the UI of the game, - initializes it, adds event listeners to buttons, and changes it depending on game's data. In order to decouple UIManager from the rest of the code, I used a global event system. When a button is clicked, for example, instead of directly calling the appropriate function, the button click emits an event that can be read by the Game class, and then the Game class reacts appropriately to the event. This has drastically lowered the amount of dependencies that the UIManager requires.

Source code for the UIManager class

SaveManager

The SaveManager class is responsible for handling the saving of data. It uses the Storage class to save the data into localStorage

Source code for the SaveManager class

Utility classes

Utility classes are the 'unit' classes that are completely independent from the rest of the game, and could potentially be reused in other games.

GameObject

The GameObject class is the basic unit of the game. Currently it only holds a single property - position. In hindsight this class may be redundant at the current stage of the project.

Sprite

The Sprite class holds information about a sprite, its dimensions, texture and position. Renderer has a drawSprite() method that allows you to draw a sprite

Source code for the Sprite class

Plant

This is the central, and probably the most interesting class of the game. The Plant class holds information about the plant, its water levels, stages, sprites, etc.

Source code for the Plant class

Data

Each plant type is stored in a .json file, which get fetched upon game load. It stores information such as growth rate, water levels, plant name and ID. When creating a new Plant instance, I pass the plant .json file to Plant's fromJSON() method, and an instance gets created from that plant file. Sprites for the plants are stored in folders named after the plant IDs, and each sprite has a name such as 1.png or 4.png, the number indicating the growth stage.

Conclusion

In this post I talked about the architecture behind my game My Pixel Plant. I hope it was informative and that you learned something new from it. If you're interested in learning more, feel free to check out the source code

devlog Article's
30 articles in total
Favicon
My Study Schedule for 2025
Favicon
My (highly caffeinated) journey to unlock the hidden knowledge of AI.
Favicon
How to Impress Passengers and Earn Rewards in Cabin Crew Life Simulator - Devlog #7
Favicon
How to Quickly Level Up and Earn Money in Cabin Crew Life Simulator - devlog#6
Favicon
Turning VSCode Into an Art Program (sorta)
Favicon
Ranking System and Career Progression in Cabin Crew Life Simulator - Devlog #5
Favicon
DEVLOG[0]: Journey into making no-code Flutter IDE
Favicon
Decoding Airplane Seat Mysteries in Cabin Crew Life Simulator - Devlog#4
Favicon
BandBoard App
Favicon
Exploring the Galley of Cabin Crew Life Simulator – Inside the Aircraft Cabin - Devlog #2
Favicon
DevLog 1: 10/15/2024 Desguon Room
Favicon
How I built PeerSplit: A free, peer-to-peer expense-splitting app—from idea to launch in just 2 weeks
Favicon
Сентябрьское обновление
Favicon
I'm Starting a dev log
Favicon
KrissVector Update
Favicon
Minecraft Modpack Development Update: Beta Test and Musical Additions
Favicon
My Dream Game Engine
Favicon
I made a Infinite Tic Tac Toe , and its amazin....
Favicon
Pokemon Battle Simulator/Showdown Clone Devlog#0
Favicon
Maiu Online - Browser MMORPG #indiegamedev #babylonjs Ep22 - Map editor
Favicon
#babylonjs Browser MMORPG #indiegamedev Ep21 - Spatial Hash Grid Area of Interest
Favicon
Pathfinding
Favicon
Let's create an Opensource Headless E-learning using Symfony
Favicon
Dev Log D-05&06. Forward Propagation Implemented.
Favicon
RuntDeale DevLog : ...1?
Favicon
1. Building an RTS game in Unity - Basic Unit Navigation and selection tool
Favicon
Architecture design of my game My Pixel Plant
Favicon
Failure and fit
Favicon
Luna Compiler Devlog #1
Favicon
Context and complexities

Featured ones: