Check the original blog post at The Gamedev Guru: The KISS Command Pattern for Unity
In this post, you will learn about the lovely KISS Command Pattern in Unity I can’t live without in my games. This pattern will empower you to easily connect your gameplay systems without all the complexity that comes from asynchronous systems. Best of all: it is truly KISSimple!
Table of Content
- This KISS Command Pattern is Pure Gold
- Why You Need the KISS Command Pattern in Your Unity Project
- The KISS Command Pattern in Unity
- What's Next?
This KISS Command Pattern is Pure Gold
You must have heard already of dozens of patterns in software development, right?
There are so many patterns that we have to group them into categories: creational, behavioral & structural.
My biggest issue with patterns is that they often are shiny objects we programmers feel TOO attracted to. And if they lure you in, they quickly lead to complexity, frustration and table flips.
For example: did you ever want to integrate just one pattern... and yet ended up integrating a bunch more so this pattern would fit perfectly in your project?
Things quickly go out of hands and you end up spending weeks implementing patterns rather than working on the gameplay features your players pay you for.
That’s the dreaded complexity shitstorm many developers fall into by mistake (myself included).
Because engineering feels cool. And overengineering sometimes too.
Listen, I just don’t follow the trend of making simple things complex. And I think you shouldn’t either. I dislike overengineering and fight every day to keep things simple stupid (KISS). Because you ain’t gonna need it.
I prefer being just 80% correct and getting the right job done within the day... rather than being 99% correct but delaying my project for yet-another-month.
That’s why I recently kickstarted the KISS patterns series with a post on KISS Dependency Injection for Unity.
Today you’ll learn about the KISS Command Pattern for Unity that I consistently use in the projects that I work on. Projects that are production-ready and millions of players are already enjoying.
This is one of the few “plug & play” patterns that don’t end up with the just-let-me-add-10-more-patterns tornado.
Ok, let’s Keep this Post Simple Stupid and get started.
Why You Need the KISS Command Pattern in Your Unity Project
Here are the top reasons I use the KISS Command Pattern in my Unity projects:
- Simple handling of asynchronous behavior: you often need to start something and wait for it to finish.
On player level up, start fireworks and wait for it to finish before proceeding to the next screen. - Crafting readable steps: once something finishes, you start something else.
After the fireworks, you open a level up popup and wait for the user to press “continue”. - Achieving friendly cooperation between unrelated systems: sometimes you need independent systems to cooperate towards a goal. For that, they need a “coordinator”.
The level up process needs systems like fireworks, UI, backend for player level updates, block input, etc..
Surprise: you can accomplish all three requirements with the KISS Command Pattern for Unity.
A “level up command” may look like this:
ExecuteLevelUpCommand()
{
UpdatePlayerProfile()
SyncWithBackend()
BlockKeyboardInput()
wait HandleLevelUpParticles()
wait HandleLevelUpPopup()
UnblockKeyboardInput()
}
Just an example, of course, but this code shows you the three reasons I stick to the KISS command pattern in Unity: coordination of simple, asynchronous & independent systems.
Now, why is the KISS part so relevant in this pattern?
If you surf around the internet for the command pattern, you’ll find tons of implementations.
Well, I don’t like most of them.
Most implementations aim to be generic by introducing complexity, which means that they are too generic for your specific game.
This complexity would make:
- Your games hard to maintain. Too many details!
- Your new commands frustrating to create. Too much overhead!
Listen, you ain’t gonna need it.
It’s better to start simple and expand as you need... rather than the other way around. Simple!
So let’s look at an implementation you can start using TODAY.
The KISS Command Pattern in Unity
Here we go:
public interface ICommand
{
IEnumerator Run();
}
That’s it. A KISS command pattern for Unity, as I promised.
Let’s see an example:
public class LevelUpCommand : ICommand
{
[Inject] IBackend _backend;
[Inject] IInput _input;
[Inject] IPlayerProfile _playerProfile;
public IEnumerator Run()
{
_playerProfile.LevelUp();
_backend.Sync();
_input.BlockKeyboard();
yield return (new HandleLevelUpParticles()).Run();
yield return (new HandleLevelUpPopup()).Run();
_input.UnblockKeyboard();
}
}
As you can see, this pattern works damn well with the KISS Dependency Injection system, but you don’t need it.
There are many variations, but simple is always the way to go.
What’s Next?
You see how simple and readable the KISS Command Pattern for Unity was?
What’s better, you can easily adapt it to your project needs:
- Want redo/undo functionality? Just store them in a list.
- Implementing replays? Save them in a file
- Trying to repro bugs? Simply log the commands you execute
Just a warning: be careful using this example in production games.
You must be aware of the memory pressure it puts into your garbage collector. This may slow down your game or worse, freeze your game for a few seconds when the GC kicks in.
To see the KISS command pattern in detail with more possibilities & examples, you can watch the full lesson on the KISS Command Pattern in the Week #017 of the Unity Performance Taskforce.
See you next time!
Ruben (The Gamedev Guru)