BY THINK ARCADE
Role: Lead Programmer
ROLES AND RESPONSIBILITIES
Oversaw two other programmers, as well as helping 10 other developers in the project.
Worked with producers to plan deliverables.
In charge of creating production locks as well as deciding what didn't or did go into the build during locks.
Talked to our Game Designer and Level Designer to try and make what they wanted possible with the time we had.
Made sure that anything we did, did not cause performance drops in the gameplay with art or cool tech.
Made builds (normal .exe, installers, and steam builds).
One of the issues I had to learn to deal with as a Software Lead is to not try and take on work that is on the “critical path.” Since I might have to be pulled away at any time to put out fires, I needed to work on things that would be nice to have but we could live without if the worst were to happen. Thus, I created our Telemetry Tool by using C++ to create Unreal Blueprint nodes. Using a simple Key <String> Value <Vector3> pair I was able to save off events to a file and be able to parse them easily allowing us to recreate what happened during a play session for our Level Designers to use. During a play session: every .3 seconds I was logging the players position (which would show up in game as a green diamond), every restart or death (a red pillar in game), and every tether (blue diamond). This allowed us to have a “heatmap” of all the things a player did in a level and since I was logging in order of them happening, I was able to also create a visualization with a mesh that followed the path the player took so you could “watch” what happened. Fun Fact: This technology later was reused to make our Ghost System which allowed the player to race against their best run of the level!
In addition to saving off the players actions in a level, I also worked with our QA Producer to save off important values such as: Player Deaths per Level, Time Spent in Level, First Completed Time for Level, and Best Completed Time per Level. To do this, I created an Actor in Unreal that was spawned when the level was created, that took “notes” while the player was playing the level, and when they left the level and the actor was destroyed, before destruction they added the values, they had to the global list stored in the game instance. The game instance then stored all this data and once the game was exited it would dump them all to a .csv file that we had so that it was easier for the producer to parse the data! With all the data we gathered, we were able to give that to our Lead Level Designer so that he could smooth out the difficulty curve of our game.
STEAM API INTEGRATION
During development, we realized: “What is the point of a SpeedRunner, if you can’t compare scores with other people?” With that, I started prototyping what became our leaderboard system backend. Unreal has built in steam blueprint nodes that interact with leaderboards, but they didn’t replace scores and instead added new scores with old scores, which was a bust. I then dove into Unreal C++ to try and get more access to the built-in steam capabilities, but they too didn’t work the way we needed. In the end, I had to just include the API in our project. With it included, we had access to everything steam had to offer, however, I needed to expose it in blueprint for our UI/Gameplay programmers to use. I created a wrapper class that called all the steam API functions, and then made a bunch of blueprint nodes that called the functions within the wrapper! With these nodes we were able to upload a score to a leaderboard (and if that leaderboard didn’t exist, we created one!), and get the top 10 scores for a leaderboard. In addition, each leaderboard was tied to the level name. This payed off greatly since we ended up prototyping up to 60 levels, which saved me from having to manually create the leaderboard for each one.