CAGD 377 - Blog Post 3
- Els Fouche
- Oct 10, 2025
- 6 min read
Plague Break
Plague Break is a match 3 game with combat and roguelite elements where you play as a survivor struggling against the zombie hoard. Creating matches allows you to damage enemies; special tiles can be mixed into a match to do bonus damage or to heal yourself. Managing your board state carefully is critical to your survival.
Build
During this sprint we created several builds for our playtest. These builds went quite well. The initial issues we experienced attempting to build the application using an earlier version of our game engine were entirely eliminated by upgrading to a more recent release. Of additional note regarding our choice of engine, Unity, a security bug required us to update again during this sprint. In both cases the upgrades caused no issues for the code base and testing indicated that the application remained fully functional after each.

More on the security vulnerability can be found here.
Playtest
We completed one playtest during this sprint. Our sample size was limited in number (n<15) and demographics (college students, majority (>90%) male, all ages ~20 - 27). The playtesters provided valuable feedback, especially regarding issues that were encountered with the game.
The primary issues encountered were:
Players were able to deal damage to enemies despite not creating a match,
Creating matches with more than three pieces did not deal additional damage,
The damage timer did no reset when completing a wave,
The game resolution did not adapt properly to common phone aspect ratios,
The reliance on colors for matching made it unnecessarily difficult for one color-blind playtester, and
The minimum API level was not set appropriately, resulting in some testers being unable to play the game.
As programmer for the project I was pleased that players enjoyed the game but I primarily concerned myself with noting and prioritizing bugs. I'll discuss how I approached these issues further below.
Scene Management
Our team has been pushing to get level selection and the mid-run shop in place ahead of our alpha build. As part of this I implemented a basic level selection screen following the rough draft of our designer. Of note is that I was temporarily blocked when attempting to get this completed due to not having an example map to base the level selection layout on.

This was, as may be expected, not complicated to set up once I knew how things should be laid out. I allowed myself to become distracted with implementing a different paradigm for scene selection than usual. The system I implemented allows for the designer to select the desired level type for each of the buttons on the level select screen with a drop-down menu.

Ordinarily this is impossible due to Unity's UI buttons not allowing for enumeration items to be selected. The workaround shown above is for the button to, instead of passing the desired value to the chosen function directly, pass a reference to a script that contains the enumeration you'd like to be exposed to the designer.
In this case, the LevelSelectButton script holds a public enumeration variable. This can be adjusted by the designer in an easy to use way and, when the button is clicked, a reference to the script is passed to the function that will respond based on which enumeration value was set.

In addition to the above, I implemented an additive scene loading system. This system allows low performance devices to load a scene without hanging (and potentially freezing due to e.g. insufficient RAM). This is accomplished with Unity's asynchronous scene management system. Once the new level is loaded the previous level is unloaded and play may resume.
There is still a small kink in this system to work out, however. Unity expects there to be exactly one each of the event system, audio listener, and main camera in a scene. This is a simple issue to fix, one needs only to create a scene that is loaded additively when the game begins and which holds the requisite components. This scene is then never de-loaded when transitioning between levels. It does require thorough testing to ensure each scene is set up correctly and is properly accessible, however, which meant this issue had to be postponed until the next sprint.
Victory & Defeat
As part of the level setup I added basic victory and gameover screens.

You'll note the addition of a red timer circle in the upper left of the screen, shown above. This ticks down continuously during play. When it fully empties the player is damaged and, if they run out of health before defeating all the enemies, they are defeated and sent to the gameover screen.

As shown above the time between attacks is adjustable by the designer when setting up a level. This is one of the many different knobs and levers I've added to make it easy for the designer to tweak the game to fit their desires. I've adopted this strategy in order to compensate for the insufficient time our designer was allotted to document the game's design as well as to allow for rapid iterations on the game's balance following future playtests.
Pseudo-Random Piece Generation
Per genre convention and designer request, I implemented code to prevent generating more than two matching pieces in a row for new game boards. Currently this works the vast majority of the time.
I have, very rarely, noticed that board resets such as when the player advances a wave will result in newly-generated pieces that have matches of three or more. I believe this is due to the fact that I have not added code to slow down board generation on reset, as I have for when the board is generated the first time. There may also an issue with in-place modification of a list during enumeration. This is a very low priority bug that I'll address when there's time. Speaking of bugs, there were several that I resolved during this sprint.
Addressing Issues
Issue #00: Players were able to deal damage to enemies despite not creating a match.
Notes: This was a very, very silly one. I did not include a check for a match when calling the damage function. Those checks were being made, but the call to the method was outside of them.
Action: Correcting this was extremely quick and easy, I simply moved the damage function call so that it's only called if the checks say it should be.
Issue #01: Creating matches with more than three pieces did not deal additional damage.
Notes: This issue was more complex than the previous one. Correcting it required me to reassess my damage formula entirely. Previously, all matches were being pooled into a single value and passed to the damage function and were not utilizing the base damage value of the match appropriately.

Solution: The graph above shows the reworked damage formula. Any match of 3 or more begins accumulating a damage multiplier such that the base damage is increased by 100*(1+(x-s)/c)) percent where:
x is the number of pieces in the match,
s is the number of pieces required for a match, and
c is a constant value that can be used to adjust difficulty.
When x-s is equal to c, the player deals double damage. Thus, if c were five (as shown in the example above), if the player creates a match of four they will deal 20% more damage.
Issue #02: The damage timer did not reset when completing a wave.
Solution: This should have been a simple one but while adding the code necessary to reset the timer I found a more serious bug.
Sub-Issue #02a: When advancing waves the player receives increased damage.
Notes: Whenever the player advanced a wave another damage co-routine would begin running.
Action: In order to resolve this I implemented a system that ensures there can only ever be exactly one damage co-routine running at a time.
Issue #03: The game resolution did not adapt properly to common phone aspect ratios.
Action: This issue was marked as low priority and will be addressed in the next sprint.
Issue #04: The reliance on colors for matching made it unnecessarily difficult for one color-blind playtester.
Action: This issue was marked as low priority and will be addressed in the next sprint.
Issue #05: The minimum API level was not set appropriately, resulting in some testers being unable to play the game.
Action: This issue will be addressed during our next build.

Comments