Shrineflow Minimap

Prototype

Towards the earlier part of the initial Shrineflow prototype, one problem we continually ran into as people tried our game out, was the opportunities they had to get lost in the map. As the ninja, you have to run from the kitsune, but this requires a sense of your location and where you need to go. Many playtesters who would play our prototype felt lost and had to expend their energy and effort into finding where they need to go next rather than running and hiding from the kitsune.

I was fully aware of this problem, and I took it upon myself to incorporate a minimap for both characters to aid the players in a higher sense of location. At first, it was a simple scene capture 2D camera placed above the map with paper sprites tacked onto the player models. This quickly made the prototype laggier, as the cameras had to update every tick on both players screens and I needed to change the minimap logic to something much more simple, yet even more effective in aiding players.

In Adobe Illustrator, I took an aerial screenshot of our map at the time and created a simple, blocked out image of the landscape, including some landmarks to help orient the players. This image was then added into the minimap widget I had created in our Unreal project, as well as a simple arrow and sight icons to show the player where they are on the map. These can be seen in the image above.

After creating the image assets, I had to figure out how to update the players’ locations in real-time to have it be perfectly reflected to the minimap. This took a lot of hours of trial and error, but I finally figured out the math needed to translate the world space locations to the screen space of the widget I have created. 

The linear algebra I used is shown in the blueprint screenshot below. The widget takes in the player’s world location, adds the respective axis’s offset of the world map. It then multiplies the ratio of the map size to the minimap size to correctly have the 1:1 ratio for any location changes. The updated numbers are then passed into the opposite axis’s image translation to finally show the correct location of the players on the minimap.

As seen in the first image, the math requires the arrow and all other elements that need to be moved along the minimap to be initially located in the top right corner of the minimap image. This is due to the linear algebra treating the minimap as its own screen space, with the origin located in the top right corner. Instead of changing the images location in the widget canvas, the arrows are moved using the render transform’s translation values instead. This maintains the correct world to screen space ratio to correctly display the real-time location of the players onto the minimap. Below is a short video of the minimap in action.

After logic was finally figured out, iteration of the map and minimap through the process of internal and external playtesting was applied. To make sure each player could intake and understand the information given through them quickly, improvements were made over time. A ping system was also created by me to help tell players certain points of interest as they needed them. The iterative process is shown here, with 4 different minimaps, each with their own layouts, levels of detail and particular minimap features to improve on my own UI design decisions over time to help better our player experience.

Stable Build

As we began our stable build and restarted the project from scratch, the minimap had to be redone. We had ran into a problem due to the introduction of networking, since our game would be played over a server. Variables needed to be replicated, and each client needed separately constructed minimaps. This required an entirely new system to allow both characters to know where they were located within our play-space as well as landmarks to help them navigate towards the win condition.

To accomplish this, we wrote a minimap subsystem within C++. This subsystem would set up an initial minimap using UE5’s location systems, and applied the needed minimap markers from each object in the playing field that required markers on the minimap. This was done through each object individually, so that when these objects were replicated within each player’s client, each minimap can create and maintain its own markers. When a specified minimap marker subclass was given to an object, that object would send the class to the minimap to have a marker of said class be made and updated in real-time (based off of transformation and possible deletion). The blueprint macro for adding markers is shown here:

This style of minimap implementation allows for effective communication regardless of the complicated networking that our game was doing during the course of each match. It allowed me to be fully unrestricted to making a minimap that clearly expressed whatever information each player needed through the use of color, shape and movement within the minimap itself. This video shows the completed design in a close-up ninja shot, as well as a zoomed out kitsune shot that shows the final minimap as a piece in the entire UI for the game. I am very proud of what I was able to accomplish for the minimap within the timeframe and restrictions of our collegiate project.