Building a Multiplayer Card Game with React & Firebase in 3 Days
I find that one of the best ways to learn a new language or framework is by building a small project. Games in particular are fun to build and due to the complexity of having a lot of business logic (the game rules) and UI interactions, are typically great projects to get started. I had a 3 days weekend during early COVID days and decided to learn the React framework by porting one of my favorite board games - Century Spice Road - to the web using React and Firebase.
Introducing: "The Spice Trader"
Setting-up Github, Trello, Visual Studio Code, Node.JS
Defining the entities for the game (card, resource, deck)
Building the game rules and sequence of actions
Populating the data for the game (all the resource cards and victory cards)
All in pure js, no UI, testing with Nodejs console logs only
Building the UI with React
Implementing various UI components(player status, cards, victory points, resources, ...)
Implementing User actions and turn mechanics
Hotseat multiplayer (playing on the same computer)
Integration with Firebase real-time database (Firestore)
Integrate with Firebase authentication to log-in and define stable player IDs
Store game state on Firebase and rebuild React widgets on state update
Lock actions when viewer is not active player
Integrate with Chrome/HTML5 Notification API
Added game log with moves history
CSS and user experience tweaks
Day 3+1 (some time later)
Implemented a Lobby system for users to invite each other and start gaming sessions
Minor tweaks to the UI (based on player feedback)
I published the 20-min video on the YouTube channel where I run through the process in more details giving some tips along the way. You can also find the Github repository for the game code here: here.
Enjoy and let me know in the comments if you are using the code for your own projects and what you build with it :)
Using Unity Scriptable Objects for Conditional Triggering
I described in my previous post about ScriptableObjects in Unity, how you can use ScriptableObjects for various cases, specifically as a replacement for enums. I also like to use ScriptableObjects for implementing conditional triggering of effects in the game. For example you want an effect to only apply when an enemy is killed, or when the player takes damage or if the player took damage from an enemy with Fire resistance. Using enums here would lead to too many cases or a lot of hardcoded ifs.
By combining the serialized fields of the ScriptableObjects and methods that have access to the game state, you can implement basic conditions for your game to replace all those nasty hardcoded cases.
The Unity editor allows you to visualize all these properties (the data) while the ScriptableObject code defines how it uses that data. This enables non-programmers to change the behavior of your game entities (cards, magic effects, enemies) by adding triggers based on conditions that are created in the editor rather than in code, following the template behaviors that you created in code with only a few lines of code.
On top of Conditional Triggers for your game, you can also create Dynamic Values ScriptableObjects which uses their methods, serialized fields and the passed-in game state to compute and return an int value that other game systems can consume.
For example, you could create a dynamic value that gives the player an attack value based on the number of enemies they are facing, or based on the number of wounds they have taken or blocked, etc.
This follows the same concept as conditional triggers, where a few lines of code allows the ScriptableObject to inspect the game state to count the number of entities matching the condition and returning it.
You can also easily compose those values for example by giving the player an attack value equal to the number of enemies defeated multiplied by the number of wounds taken.
These are very powerful concept that can make configuring your game behavior and data extremely easy for programmers and non-programmers alike.
As usual, I have published a short deep dive video on the topic, sharing demo and code snippet.
Please have a look, like and subscribe and I hope you enjoy the content!
Using Unity Scriptable Objects for Game Data
As part of building my game on Unity, I have been playing around with Scriptable Objects, which are a type of asset ideal for managing shared data between the components of your scene.
I have not formally introduced my game yet but the tl;dr is I am bringing mechanics from boardgames like Mage Knight and Gloomhaven and porting them to PC.
I use Scriptable Objects in the game for everything: Enemies, Player, Cards, Effects, Costs, Mana, Colors, etc. They are amazing data containers that can handily replace your enums by providing associated data for each of the values.
For example, instead of having an enum for the various magical elements of your game (lightning, fire, ice, etc.) then having switches everywhere on each value, you could group the common properties for each element (images, particle effects, sound effects) and behavior of that element - for example how it reacts against other elements (weaknesses/resistances) all in one container object.
Using carefully placed annotations in your Scriptable Object properties you can surface each of these values as configurable variables in the Unity Inspector, as well as integrate with the Unity menu to allow quick and easy creation and edition of all your game data. This also enables non-programmers to add content to the game.
The added bonus is that if you package your ScriptableObjects in bundles under the Unity Addressable Assets system you can turn those into downloadable content (DLCs) or enable modding of your game data for Steam Workshop. Imagine distributing new pack of cards, new enemies or new battle arenas.
I published a quick video (~15min) going through my use of ScriptableObjects to define the game cards and associated magic effects and do a short dive into the code to see how things are wired up. I will be publishing more on that topic as I find it fascinating and it is really helping me a lot as a game developer.
Have a look a don't hesitate to subscribe and comment it helps tremendously :)