STUPID ZOMBIES 3

The zombie apocalypse has wiped out the majority of the human race, and the last remaining survivors must strike back in Stupid Zombies 3. Visually striking graphics and a range of powerful new weapons appeal to fans of the franchise and new players, alike. Zombies spawn randomly on every playthrough, as players blast their way through more than 100 new challenging levels.

SUMMARY OF RESPONSIBILITIES

  • Collaborated with team to evolve core Stupid Zombies gameplay defined by previous titles in the franchise

  • Primary programmer for all game features

  • Coordinated with artists to develop the look of the game through custom shaders

  • Implemented Facebook and cloud save integration

  • UI setup and animation


DETAILED BREAKDOWN

Stupid Zombies is GameResort’s most popular franchise, and after working for a year on Adventure Beaks, it was time to capitalize on its success, once again. Previous Stupid Zombies titles had performed extremely well in the charts and with user retention, though less successfully with IAP conversion. Our main goal with Stupid Zombies 3 (SZ3) was to increase player IAP, while retaining the same style of gameplay that had skyrocketed the franchise to success.

At the time, Candy Crush was monetizing exceptionally well and featured gameplay and design that were roughly analogous to previous Stupid Zombies titles, in a broad sense; both were casual, level-based and featured light puzzle gameplay. For inspiration, the team played more Candy Crush than any of us would care to admit, and we developed several key observations:

  • Heavy randomization of levels. Winning often depended more on the pieces you were given, rather than how well you played.

  • Level difficulty did not ramp linearly. Most levels could be beaten on the first try, but levels of varying difficulty were interspersed throughout. This included “blocking” levels that were heavily stacked against you and took many tries to complete.

  • Win or lose, levels generally took 2 minutes to play through. It took just as long to lose a level as it did to win one.

We incorporated these gameplay principles as the primary goals for SZ3, and they defined much of my work for the project.


LEVEL EDITOR

For the level editor, I expanded on the tile painting tool that I developed for Adventure Beaks. Levels were tile-based, with square tiles for main level shaping and triangular tiles for defining angled corners. Tiles were created with a single mesh per tile and were assigned to a set.

Tile set. Images on the left show conditions for each tile.

Tile set. Images on the left show conditions for each tile.

The tile painting tool supported basic painting, erasing and filling. It was only necessary for the designer to paint the type of tile in each space (square or triangle), while the tile mesh was chosen algorithmically, based on the rules in the set. This also allowed us to re-theme levels easily, whenever necessary. 

Tiles were textured in world space, with a tiling texture overlaid across all of them. The texture used depended on the tile set defined in the theme settings. 

City theme settings.

City theme settings.

Previous Stupid Zombies games featured single-screen levels that were solved by killing all enemy zombies. For SZ3, we decided to try levels that consisted of a series of connected screens. At each screen, the player takes a single shot, attempting to kill as many zombies as possible. For the final screen, the player has two shots to complete the level. This satisfied our goal of maintaining a consistent level length, no matter if players win or lose, while also allowing levels to be longer without being boring. After the player takes a shot, the character moves 1/3 of the way across the screen, and the camera re-centers the view for the next shot.

The level editor provided a tool for editing the player’s movement path through the level. It was possible for the designer to adjust the height of each firing point in the level, then tweak the player’s movement between firing points. When the next point was positioned higher than the previous firing point, a ladder would be placed for the character to climb up. If the next point was lower, the character would either fall a short distance or use a pole to slide down.

Comparison of player path in level editor to same section in-game.

Comparison of player path in level editor to same section in-game.

Rather than killing all enemies (as in previous Stupid Zombies games), each level is SZ3 defines objectives for how many zombies a player needs to blast in order to win.

Zombie goals in a typical level. This player isn’t doing very well.

Zombie goals in a typical level. This player isn’t doing very well.

A key goal for this project was having the ability to fine-tune the difficulty of each level, based on analytics gathered during soft launch and post-launch. I developed a number of different tools to assist with this process.

Enemy spawn points in SZ3 were painted in the level editor from a set that defined which types of zombie could generate at each point. Each point also defined whether or not a zombie would be able to respawn. If a zombie could respawn, a port-o-potty was created at that location, and a new zombie would come out of it on every turn when a previous zombie was killed.

Example of zombie spawn settings for a level. The orange settings are repeating spawns.

Example of zombie spawn settings for a level. The orange settings are repeating spawns.

Each level featured a button to calculate the approximate difficulty of every zombie spawn point. This was achieved by casting several rays from each firing point in a full arc. Each spawn point was given a score based on how many rays crossed it, as well as how many bounces it took for each ray to reach it. Higher scoring spawns were considered easy and lower ones hard. It was possible to visualize the results of this in the editor.

Visualization of approximately how difficult each grid space was to shoot in this level section.

Visualization of approximately how difficult each grid space was to shoot in this level section.

Each level was assigned spawn weights that were used to tune difficulty. Instead of spawning all zombies at the beginning of the level, each section spawned just prior to a player moving to it. This allowed difficulty to adapt to how well a player was doing as they were playing through each level. 

Hard settings. When a goal is almost met those zombies spawn in hard to shoot places.

Hard settings. When a goal is almost met those zombies spawn in hard to shoot places.

The “needed” weight dictated how much preference was given to zombies types that you currently needed to win. For instance, if you had 2/25 red zombies and 19/25 blue zombies, it would prioritize spawning red zombies if the value was high. The “easy/hard difficulty bias” would dictate whether a level would prefer to put zombies in the easy or hard spawn points, as determined using the method above. The “difficulty weight” determined how much effect the difficulty bias setting had on zombie spawning. The “difficulty needed bias” was used to place zombies you needed into the harder spawn points. Finally, the “reclaimed percent” was what percentage of zombies you failed to kill would be added back to the total amount of spawned zombies and respawned later.

Easiest settings. Any zombies you miss re-appear later. You have to actually try to lose.

Easiest settings. Any zombies you miss re-appear later. You have to actually try to lose.

Each setting could also be constant or scaled, based on either a player’s progress through the level or progress towards completing all level goals. These settings made it possible to engineer situations where players would lose by only one or two zombies, encouraging them to purchase extra shots at the end of a level.

There are also several decorative visual elements in each level, including ivy, hanging chains, plants and windows. These were all placed procedurally, depending on the layout of the blocks in a level. The cast gradient shadows are meshes that were also procedurally calculated for each level. The gradient is achieved by using vertex colors, and they are clipped to the background using the stencil buffer.

Comparison of level in editor to in-game with procedural shadows and decorations.

Comparison of level in editor to in-game with procedural shadows and decorations.

Simple authoring assets were used for the decorative visual elements. This included an option to exclude elements from Android devices, since Androids are generally less powerful and less graphically capable than iOS. 

The grass is always greener on iOS.

The grass is always greener on iOS.

SZ3 featured two hundred levels by the time we were done updating the game. To help balance difficulty progression and keep the levels organized, I built a level browser window. 

Level browser used to order and track levels in SZ3.

Level browser used to order and track levels in SZ3.

The graph at the top shows level difficulty and can also highlight different level properties. The list of levels shows some basic info about each level and also allows for re-ordering of levels. When selected, additional information about the level (like zombie types) is displayed below.


Rendering & Animation

Each character in SZ3 is drawn using a 3 pass shader, which includes one pass for the main color, one pass for the cast shadow behind the character, and a final pass to apply an outline. The cast shadow is the character’s geometry rendered with an offset and clipped to the background, using the stencil buffer. The outline is the character’s geometry extruded along its normals and clipped by the stencil value written by the main character geometry pass. This required the normals to be completely smooth, but since there was no other lighting applied, this wasn’t an issue.

Screenshot showing outlines and cast shadows.

Screenshot showing outlines and cast shadows.

These passes could be toggled on or off, depending on device quality.

The artists authored a series of animations for each character action: run, climb, fall or slide down a pole. This included stop and start animations for each action. I wrote a tool that sampled the foot and hand positions for the running and climbing animations, calculating the total distance the character would move over the course of the animation. I was also able to create an inverse of this curve that described approximately at what point in the animation a character would have traveled a certain distance.

Example of run animation movement curves and character mover component with all animation types.

Example of run animation movement curves and character mover component with all animation types.

Since the way the character moved through a level was predetermined, I was able to use these calculated values to determine exactly how much to loop each animation before blending to the next one. This allowed the character animations to feel grounded and precise while the character was navigating through the level. This also allowed our artists to only make a handful of animations for each character, freeing them up for other tasks. Finally, this also allowed us to add a powerup later in the game that rewound your previous turn, with a fun effect.

Previous
Previous

Adventure Beaks

Next
Next

Doom-Style Level Editor