Mini Post Mortem on the Season 3 ARG and Open Sourcing the Code!
Greetings brawlers! While we recap our Greatest Hits in Season 5, why not join me for a mini retrospective on the Season 3 ARG?
My name is Carlo del Mundo, I’m a programmer here at Velan Studios, and today I will be giving you some insight into the development of the web game that was part Knockout City’s Season 3 “Z3R0 City” ARG. In fact, for the especially curious, we are releasing the entirety of the main web game’s code on GitHub, which you can find here: https://github.com/VelanStudios/z3r0-city-arg/
Ideation and Planning
An Alternate Reality Game is an interactive live experience, most often an elaborate puzzle, that is treated as in-universe with a reward for players who complete it at the end. As part of Season 3 “H@cked,” we thought an ARG would fit the theming very well while helping us boost player engagement and experiment with a very different kind of game.
When starting development, it’s important to understand the “scope” of your game and anything that might restrict it. Adding features increases the scope of your game, and therefore increases the amount of work you will need to do to complete it. I only set aside a few hours to complete this, so adding the Cage Ball for example, which would require adding the concept of balling up, would be chopped.
We knew that we wanted to incorporate a QR code in to the ARG, so we had the idea of making a QR code with some areas missing, and each of the screens of the web game could fill in one of those areas. This fit well with the glitchy pixelated aesthetic of the Season 3 “H@cked” theme as well as, you guessed it, limiting the amount of time needed for the art. The art for the game was originally going to be much simpler, but Eric, Knockout City’s Narrative Director, stepped in to provide his 8-bit inspired art.
One hurdle that needed to be jumped before starting was how we would prevent players from cheating. When we were first talking about making the game, the idea was to have the room randomly generate when a player entered them unless they went in a specific pattern. If there was any trace of what combination we were looking for in the code, there would always be the risk of someone decrypting the game files and reading the directions the game was looking for bypassing the actual puzzle. To prevent this from happening the entire game world is generated at once using a script that is not included in the files when we release a build. Without the script, there would be no way to tell which tiles were created by hand!
What Makes a Brawler, a Brawler?
Z3R0 City was created using the Godot game engine. You’ll need to download it here; it’s free and open source, with no installation required! Once you have Godot and the files in the Git downloaded, launch Godot and select the “Import” option on the right sidebar. Click on the browse button to find, or paste the path to the “.godot” file included in the Git. Once you’ve done that open the project.
Loading the initial starting level might take some time; as mentioned in the section above the world is pre-generated and is very large in an effort to prevent brute forcing the ARG’s answers.
I will now dive in to a brief summary of the main components of the game. To follow along, you can click on the clapperboard to open the scene for the node or the scroll to open its script.
Player
The player is a Kinematic Body which gives it collision with the world, specifically the black tiles. The Area2D is used to determine if the player is in range to pick up a ball or is has been hit by an enemy. Note that inputs in Godot are controlled under Project → Projects Settings → Input Map. They can be called on by name and can be assigned multiple inputs, which is how we’re handling both keyboard and controller input. For fun, try searching for a ball and replacing the one that the player starts with; see if you can follow how that ends up in the players hands at the start of the game!
Ball_Normal
Godot’s inheritance is largely handled in script (though technically you might consider nesting one node in another a kind of inheritance). Since every ball in the game can be picked up, thrown, and hit bots, all balls inherit most of their function from Ball_Normal. If you take a look at the Ball_Moon.gd and Ball_Sniper.gd scripts you can see this in action very plainly. The Sniper Ball has a higher speed multiplier, and when thrown rotates itself in the direction it’s going. The Moon Ball has a smaller speed multiplayer, but gives the player a movement bonus when held (since a lower gravity jump isn’t an option, I figured the movement speed buff would help players searching for specific spots on the map).
Brawler Bot
The way the Brawler Bot pathfinds to the player is frankly archaic but as I mention in the header comment, that was actually fine. Godot has A* pathfinding built-in, but it would be a bit of a chore to set up and this was faster to implement. Basically, the bot looks some distance in front of it in the direction of the player: if there is nothing blocking the bot within that distance it moves in that direction, else it will try to turn itself a number of times to move around whatever is blocking it to reach the player.
Player Camera
Naturally, it has some Area2D’s to pan the camera when the player has moved to another room. It also has a KinematicBody2D that collides only with balls to keep them in the current room (it’s collision layer and mask are set to a specific “boundary” value). Living under our Player_Camera is the Spawn_Manager which creates the balls and enemies in each of the rooms. We also have the Score_Counter which displays the number of bots a player has defeated. And lastly at the bottom is an unused code display prompt. The original idea was to give the player a code for holobux if they found Chonky early, but the idea was scrapped since finding Chonky is its own reward.
Chonky
I would be remiss if I didn’t at least mention something about Chonky’s code. As mentioned above finding Chonky was originally going to reward you with a code. However to get the code, you would have to pet him 42 times (the number of PLEASE_PET). As you started petting him you would earn titles of describing how amazing you are for petting Chonky. The variables still exist in code, but lay dormant and instead as a reward after petting Chonky he creates hearts above him to show is appreciation.
Wrap-Up
It’s a pretty simplistic game, but it fit the scope of what we were looking for. If game development interests you, I hope you’ll take the time to play around in Godot whether you are a programmer or are just looking to swap out the png files to make the art of the game your own!
It was a blast to see everyone frantically searching through the game, trying to solve the next puzzle in the ARG. If you want to chat about this at all or find other interested in all things Knockout City, you can usually find me hanging in the Discord as “Velan — Carlo” (@neoxid501).
Thanks for reading! If you enjoyed this blog post, perhaps you would be interested in this blog that Douglas Applewhite wrote about the rollback netcode. If you managed to understand all of that, maybe consider checking out our careers page? :)