![](https://static.wixstatic.com/media/85cc2a_67ff9185ec3b416186553d0d912cf024~mv2.jpg/v1/fill/w_1250,h_800,al_c,q_85,enc_avif,quality_auto/85cc2a_67ff9185ec3b416186553d0d912cf024~mv2.jpg)
![Screen Shot 2023-06-01 at 6.25.45 AM.png](https://static.wixstatic.com/media/85cc2a_0e9793e48461448bb88c6c321dbec254~mv2.png/v1/crop/x_0,y_9,w_2790,h_1057/fill/w_980,h_371,al_c,q_90,usm_0.66_1.00_0.01,enc_avif,quality_auto/Screen%20Shot%202023-06-01%20at%206_25_45%20AM.png)
Mailman and Cerberus
In this game the player plays as a mailman delivering the mail as a giant Cerberus hunts them down.
The goal of this game is to get the highest score by delivering letters to their corresponding houses. Throughout the game, the player will be slowed down and will have to use the abilities they have been given in order to get away from Cerberus. The player can employ the use of their sprint, treats they collect, and weaving between houses in order to deliver more letters and get away from Cerberus.
​
I scripted this short game in Unreal 4.27 using Unreal's Blueprinting system. I have mainly used third-party models, with the exception of the street sign.
Address System
The player will be delivering their mail to specific destinations based on the address of the envelope. When the player tries to deliver a letter to a house, that delivery will only be successful if both addresses match.
​
To be able to determine where to deliver a letter to, blueprints that have an address will change in look depending on the address:
-
Houses, mailboxes, and envelopes will change color depending on the section that they are in.
-
Envelopes have a dynamic material that will change the text for the number and street name on the envelopes depending on the address.
-
Envelopes have the corresponding color icon in the inventory bar.
-
The nameplates on houses will reflect the number of the address.
Additionally, there are street signs located at the corners of each intersection which inform the player which street they're on. ​
![](https://static.wixstatic.com/media/85cc2a_c25155d7fc9149ed9bc5b49de827cea5~mv2.png/v1/crop/x_0,y_53,w_2880,h_1651/fill/w_434,h_249,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_c25155d7fc9149ed9bc5b49de827cea5~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_e0ce1d1f81364ae89c5c426d673adedd~mv2.png/v1/fill/w_438,h_254,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_e0ce1d1f81364ae89c5c426d673adedd~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_5a185884181049468ad06206f007be9e~mv2.png/v1/fill/w_412,h_172,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_5a185884181049468ad06206f007be9e~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_0da4a67124104066a47e026e1e3936f0~mv2.png/v1/crop/x_0,y_0,w_1383,h_754/fill/w_413,h_225,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_0da4a67124104066a47e026e1e3936f0~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_67dd734a8d7f49ecba50d1fd90d6a623~mv2.png/v1/crop/x_0,y_0,w_1387,h_404/fill/w_412,h_120,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_67dd734a8d7f49ecba50d1fd90d6a623~mv2.png)
Address Data Structure
The address structure is split into 3 input fields: The number, the street, and the region.
​
The number is an integer value that represents the number of the address. On the map, there will be odd-numbered houses on one side of the street and even-numbered houses on the other side of the street. Each side of any road would ascend both the odd and even side. The number displays on the house plates as well as on the top of the envelope.
​
The street is an enumeration data value. There is a list of predetermined street names that can be given to an address. Each street has its own name, and the player can tell what street they are on by looking at the signs that are located in the corners.
​
The region is also an enumeration value. There are 4 regions: Red, Yellow, Blue, and White. These 4 regions are in 4 different sections of the level. This makes it easy for the player to tell if there are in the correct area for an envelope at a glance.
![](https://static.wixstatic.com/media/85cc2a_5b08a2db52da4a80986e2a4f35149b7e~mv2.png/v1/fill/w_523,h_302,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_5b08a2db52da4a80986e2a4f35149b7e~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_408e2bfb63b84542a0020f8731aa7ebe~mv2.png/v1/fill/w_523,h_301,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_408e2bfb63b84542a0020f8731aa7ebe~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_a9b3cfc93c754eb59bf1e69467ca65d3~mv2.png/v1/fill/w_524,h_99,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_a9b3cfc93c754eb59bf1e69467ca65d3~mv2.png)
Treat System
The treats are something that the player can obtain and use to help them gain space between themselves and Cerberus. The player can place treats on the ground to guide Cerberus away. When players place treats, Cerberus will follow the treats instead of the player until he reaches the treats and eats them or until they disappear after a certain amount of time after being placed.
​
After the player places the treats, they get added to an array of treats in the blueprint for Cerberus. Next, the movement for Cerberus is stopped. This is done so that the current AIMoveTo node returns a fail and restarts the logic for Cerberus' pathing.
​
When the pathing logic is called again for Cerberus, if there is at least 1 treat in the level, Cerberus will pathfind to that treat using AImoveTo.
![](https://static.wixstatic.com/media/85cc2a_66566433000a49ebb59cf186547f844b~mv2.png/v1/fill/w_529,h_129,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_66566433000a49ebb59cf186547f844b~mv2.png)
Player Movement
![](https://static.wixstatic.com/media/85cc2a_8b909ad815384316aeaf48f96a2f93c5~mv2.png/v1/crop/x_750,y_1318,w_1304,h_224/fill/w_361,h_62,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_8b909ad815384316aeaf48f96a2f93c5~mv2.png)
At base, the player moves at a slow walking speed. While walking at this speed they are slower than Cerberus, which allows Cerberus to catch up. However, there is a limited amount of sprint, which is indicated by a green bar on top of the inventory. When the player presses the button to sprint, they move faster than Cerberus, but only by a small amount. This can help the player get out of tight spots, and can also add a level of thrill to the game as the player is able to escape at the last second in some cases. When the player runs out of sprint, they need to wait for the sprint bar to fully replenish before sprinting again.
Cerberus Vignette
As Cerberus gets closer to a player, a red vignette will appear and get more intense the closer Cerberus is. This gives the player a heads-up that Cerberus is nearby if the player isn't looking at him. It gives the player a short amount of time to react in a way that feels fair to play, but nerve-wracking if you suddenly see the red.
![](https://static.wixstatic.com/media/85cc2a_f1c40a2f99844ef6b143b192d5c04bcc~mv2.png/v1/fill/w_516,h_294,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_f1c40a2f99844ef6b143b192d5c04bcc~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_398bcc01376a4552a4713aade922625b~mv2.png/v1/fill/w_248,h_248,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_398bcc01376a4552a4713aade922625b~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_8998cd488ac647248847c4d08bde3713~mv2.png/v1/fill/w_351,h_204,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_8998cd488ac647248847c4d08bde3713~mv2.png)
Level Design
The level was designed in a purposeful way to promote a balance between putting space between the player and Cerberus, as well as closing that space in order for the player to feel the tension. In the center of the map, there are many intersections that loop into one another. In this section, the player can walk around the roads and flee between houses if Cerberus gets too close. This allows the player to feel a sense of agency over their environment and can ease the feeling of being chased by putting their fate in their own hands. Additionally, there are many dead ends that back the player into a corner in which Cerberus will chase them down. If a player has a treat, then they have a chance of luring Cerberus away as they make their escape.
Minimap
To be able to help the player navigate through the space, I made a minimap. The map moves in different directions depending on where the player is. The player icon rotates depending on which direction they're facing. The minimap shows simple shapes to depict the houses and roads. Houses on the map are colored according to which section they are in, and they are numbered according to the number of their addresses. Roads have the text for their names on them.
​
In addition to the minimap, the player can pull up the full map for the level by pressing M. This way they can see the full scope of the level and familiarize and strategize in that way.
​
I made the minimap by taking an overhead picture of the level from the editor view in Unreal and then bringing that screenshot into Photoshop. I then replaced the houses and roads with simplified icons for each. Next, I added the road name on top of their respective roads and the house numbers on their respective houses. I then made another texture to make it a circle cut out by making a texture with a white circle with a transparent background. Next, I made the player icon with a transparent background behind that as well.
![](https://static.wixstatic.com/media/85cc2a_bf535d3110664db38030b3346ad1b4a4~mv2.png/v1/fill/w_185,h_186,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_bf535d3110664db38030b3346ad1b4a4~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_398bcc01376a4552a4713aade922625b~mv2.png/v1/fill/w_262,h_262,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_398bcc01376a4552a4713aade922625b~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_9fcce8bd9f544ce29336c9cb8d9329b1~mv2.png/v1/fill/w_940,h_480,al_c,q_90,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_9fcce8bd9f544ce29336c9cb8d9329b1~mv2.png)
I transferred my textures in Unreal and applied them to a UI-based material. I used lerps to place the player icon on top of the map and to make the map a circle. I multiplied texture coordinates with a value between 0 and 1 to make the map zoomed in. I next had input values for the x and y offset so that the map could move depending on input from the player. I also used a custom rotator to place an input for the player icon rotation.
![](https://static.wixstatic.com/media/85cc2a_31f6c9486d9940a1882606e3c1247a39~mv2.png/v1/fill/w_529,h_233,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_31f6c9486d9940a1882606e3c1247a39~mv2.png)
In order to figure out how to adjust the offset of the map, I used some math to determine what the x and y equations would be from the player position to the UV offset. I got two sets of positions and would get the coordinates for the world space of where that position would be, and what the UV offset would be. By getting the coordinates of two points on the map I was able to extract the equation between the two. This made it so that the minimap offset would accurately react according to the player's position in the world.
Initial Inventory
![](https://static.wixstatic.com/media/85cc2a_8b909ad815384316aeaf48f96a2f93c5~mv2.png/v1/crop/x_759,y_1356,w_1290,h_256/fill/w_277,h_55,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_8b909ad815384316aeaf48f96a2f93c5~mv2.png)
The player has 4 envelopes and a treat when they start the game. Each of these envelopes corresponds to a different region in the level, which then can be used as a way for the player to familiarise themselves with the 4 different regions. By starting out with a treat, the player can use it immediately to be able to understand how it works.
Inventory Replenishment
As the player delivers letters, if they deliver a letter that's in one of the first four slots, then that letter gets replaced by a new envelope with a random viable address. This keeps the game going so that the player always has letters to deliver as if it were an arcade game of sorts. If a player delivers a letter that's in slots 5-9, then that letter doesn't get replenished and that slot becomes empty. The same thing goes for if a player uses a treat, that slot will become empty afterward as well.
Random Letter System
At the beginning of the game, the first-person character blueprint generates an array with all the houses in the level.
​
When a new envelope is generated, a random house from all the houses is selected. That house's address is assigned to the new envelope
![](https://static.wixstatic.com/media/85cc2a_fc5ba1964ff24f4e997f0d2ea24fdd9f~mv2.png/v1/fill/w_367,h_106,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_fc5ba1964ff24f4e997f0d2ea24fdd9f~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_4d27bdd41f474c79a6057a58f403cbf6~mv2.png/v1/fill/w_610,h_125,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_4d27bdd41f474c79a6057a58f403cbf6~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_99d6feb67ffa49859866b0183b3f5961~mv2.png/v1/fill/w_540,h_315,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_99d6feb67ffa49859866b0183b3f5961~mv2.png)
Mailboxes of Chance
As the player delivers letters, random mailboxes will become lit up, indicating that there's something inside that mailbox. When the player opens the mailbox, there's about an 80% chance of receiving a treat, and about a 20% chance of receiving a letter. Besides the treat given at the beginning of the game, this is the only way for players to get more treats.
Dynamic Envelope Material
This is an example of one of the instances in which I implemented the address system, specifically when it comes to the envelope.
​
The material for the envelope has a series of various parameters. There's one for the color or section, one for the street name, inputs for the first and second numbers, and inputs for whether or not this is a number with one or two digits.
​
I altered the material using an event in the envelope's blueprint. In this event, a dynamic material instance is created using the envelope's base material.
​
A select node is used to change the color of the envelope based on the section.
​
![](https://static.wixstatic.com/media/85cc2a_1daddf671ea54fe7971f0483315d7c1c~mv2.png/v1/fill/w_428,h_437,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_1daddf671ea54fe7971f0483315d7c1c~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_7c60fbbf882c455aa869dd1c729fbd4b~mv2.png/v1/fill/w_263,h_168,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_7c60fbbf882c455aa869dd1c729fbd4b~mv2.png)
![](https://static.wixstatic.com/media/85cc2a_57d63feaaeee416f9c37ede754ab90b3~mv2.png/v1/fill/w_943,h_411,al_c,q_90,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_57d63feaaeee416f9c37ede754ab90b3~mv2.png)
Another select node is used to change the texture for the street name based on the street name assigned to the envelope. In the material, the texture for the street name is fed into a linear interpolation, also known as a Lerp. This takes the envelope base texture and street name color as inputs for the textures to interpolate and uses the alpha value from the street name texture to have it cleanly appear on top of the envelope's existing texture.
​
The numbers were a bit more complex, given that I wanted to be able to display any number from 0-99. In the material slot, I made two texture inputs, one for the 1's place and one for the 10's place. In the material, I also made scalar inputs for whether the number was visible and the tens position was visible. Each of these scalars would be set to either 0 or 1 and they multiply into the material nodes to toggle the visibility of each of those numbers. The tens visibility also alters the transformation of the 1s material. If the tens parameter is set to 1 indicating that the number is greater than 9, the texture for the 1s position would move over to the right of the envelope. This way the number would always stay centered on the page.
![](https://static.wixstatic.com/media/85cc2a_d19a2496d958426b98e82d2e19d22acd~mv2.png/v1/crop/x_0,y_29,w_1814,h_484/fill/w_944,h_252,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_d19a2496d958426b98e82d2e19d22acd~mv2.png)
In the blueprint, the number input is first evaluated for whether it's over 0. If the number on the address is 0 or less, neither texture will be visible. If it's over 0, the one's spot is active and then the number is evaluated again to see if it's a number from 1-9, or 10+. If the number is from 1-9, the 1s spot is assigned the corresponding texture based on the number on the address, and the tens visibility is turned off.
​
If the number is greater than 10, the tens visibility is turned on. The number on the address is divided by 10 to get the number to assign to the tens position. In order to get the value of the 1s position, the number on the address is turned into a string. The character at the index spot of 1 is grabbed to get the character representing the 1's position. That character is then turned back into an integer value, and that value is used to change the 1s texture on the envelope's material.
![](https://static.wixstatic.com/media/85cc2a_1c3527ad30464d5e866925f07c784c2e~mv2.png/v1/crop/x_0,y_70,w_1562,h_687/fill/w_941,h_414,al_c,q_90,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_1c3527ad30464d5e866925f07c784c2e~mv2.png)
I made this function in the envelope blueprint to return a texture based on an input of 0-9. This function was used repeatedly in the event to alter the envelopes material, and made the code more efficient and less cluttered.
![](https://static.wixstatic.com/media/85cc2a_b755700a307b4df9b1cdd69d728ff0d6~mv2.png/v1/fill/w_442,h_290,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/85cc2a_b755700a307b4df9b1cdd69d728ff0d6~mv2.png)
Similar systems are used throughout the Mailman and Cerberus game to assign dynamic materials onto meshes and blueprints in the level. Other blueprints that use this type of logic can be found on the houses and their numberplates, mailboxes, and the envelope icons on the player HUD. The street signs use a similar system so that I could assign street values to the top and bottom part of the sign in the editor, and they would immediately display the correct street name in that slot.
Review of purpose and Intentions
For this project, I intended to make a game based on the feeling of evading a giant monster. I wished to embody the feeling of an everyday mailman who has gotten stuck running from not just a dog, but a giant Cerberus. Through this project, I have been able to test my Game Design, Programming, and Game Tech abilities. Moving forward I would like to conduct more playtests to determine with more certainty what works well and what doesn't work well in my game for a player.