top of page
myphoto.jpg

Carl Lindstedt

Game Programmer

  • LinkedIn
  • GitHub

Hyper Blaze

Role: System programmer, UI programmer

Time: 10 weeks

Team: 8 people

Language: C++, Unreal Engine 5

  • GitHub

An online multiplayer first-person shooter sports game. Enter the 2v2 arena and enjoy fast-paced basketball with a twist: GUNS!

My Contribution

During this project I worked on many different systems such as:

  • Online lobby & Steam integration

  • Engagement & Stats system

  • Local & Networked UI Solutions

Online Lobby & Steam Integration

Going into this project our team decided we wanted to develop our game for Steam. I therefore integrated a few plugins to help ease the workflow. The plugins used were mainly Online Subsystem Steam, Advanced Sessions and Advanced Steam Sessions. With the help of these I created the pre-game lobby and set up the logic for connecting, disconnecting and starting a match.

When a new player connects to the lobby, the server registers their Unique Net ID which is then used to store any player-specific information such as team information or which outfit they currently have selected.

Hold Right Click to move around.

Use Ctrl + Mouse Wheel to zoom.

Initially I was getting Player Name instead of their Unique Net ID, from Steam whenever someone joined, but this had to be changed since two players could be using the same display name which would result in their info being overwritten by eachother.

Whenever a player successfully joins a lobby, they are spawned on a platform which then displays all their information to the other members of the lobby. The platforms also show UI elements letting the owner of that platform swap outfit or leave the lobby. If you are server/host you also have additional options for each platform letting you swap a players team or kick them from the lobby.

Client.gif

Lobby as Client.

Server.gif

Lobby as Server/Host.

Finally, whenever a players information is updated, by swapping outfit for example, the new state is stored in the Game Instance. This is later read back and applied to all players after the game starts to have all information persist.

Engagement & Stats System

Our designers had requested a system that would track player stats such as kills, deaths, assists, goals, etc. As well as store information about each specific kill, death, assist, goal, etc. That would then be used to display certain UI elements or effects.

To achieve this, each Player State has two replicated structs that update based on game events. The Match Stats struct keeps track of number of kills, deaths, assists, goals, etc. It does this by holding one other struct for each category inside it (Kill Match Stats, Death Match Stats, etc.). These 'substructs' exists to hold information related to the category. For example the Kill Match Stats struct holds information regarding the amount of kills, double kills, defending kills, etc. The common denominator for all information in the Match Stats struct and its 'substructs' is that it is only ever incremented.

The other replicated struct is the Player Tracker struct. This struct holds references to other players or timers that update based on certain events. For example it stores the last damaged enemy and your number of consecutive deaths. But it also stores timers that for example tell us when the player last got a kill or when they last died. All information inside the Player Tracker struct is meant to be overwritten and not incremented like the Match Stats.

Together these structs are used to fetch information from all players to then be displayed however needed. One example of use is the scoreboard where some of this information is displayed.

scoreboard.gif

Scoreboard showing current player stats.

To further increase engagement and feedback when playing, our team decided that we wanted to display an action feed similar to games like Battlefield or Call of Duty whenever you complete actions such as killing someone, scoring a goal or passing the ball. To do this I implemented a system where whenever one of these events happen, the game registers the current context in a form of snapshot and stores it in a struct. The struct is then passed on to the Game State which broadcasts events with the relevant information to whomever it may concern.

To exemplify this, we can look at whenever a player gets a kill. When this happens the server modifies an instance of a struct that holds the information of the last kill that happened before broadcasting the processed result to all clients.

The clients then respond differently depending on the processed kill result. If you had nothing to do with the kill, meaning you are not the killer nor the one that dies as well as not getting an assist, you simply display the kill info in the kill feed. But if you had something to do with the kill it would show up in your action feed.

Similar events happen for many things in our game and the Game State constantly keeps track and broadcasts information about the most recent kills, deaths, assists, goals, passes, etc.

Action feed after a successful pass.

Local & Networked UI Solutions

During this project I was in charge of implementing most UI functionality. This included the local player HUD as well as networked UI elements such as the kill feed and the screenspace healthbars. To make the player HUD display all needed information, I mostly had to make sure different system had their information public and then binding the variables to the correct part of the HUD.

The kill feed, as previously explained, listens for server kill events and then displays information based on who killed who.

For the screenspace healthbars, there were many different conditions for when and how they should be displayed. If you are looking at a teammate, their healthbar should always be visible as long as they are in line of sight. Enemies however should only show their healthbars if they get hit (also only show for the player that hit them). They then show their healthbar for a few seconds before it disappears or when they break line of sight.

enemyHitNoLOS.gif

Enemy healthbar after hit breaking LOS

Enemy healthbar after hit in LOS

friendlyLOS.gif

Friendly healthbar breaking LOS

Hold Right Click to move around.

Use Ctrl + Mouse Wheel to zoom.

Learnings
  • Learning by iteration. Going into this project I had never done any network programming before. I was not sure what to expect and made many mistakes. However during the course of the project I got more and more comfortable and found learning this new skill was very rewarding!

  • Taking ownership. For a project this big it was important to delegate ownership over different parts of the game to make sure they got the proper attention. As a part of this I also realized how important it is to speak about potential problems and ask for help when you get stuck.

The Team

Designers:

Oliver Smolka

Max Hemberg

Simon Wikström

Artists:

Ida Hansson

Walter Skoglund

Programmers:

Petter Mikaelsson

Udit Shroff

Carl Lindstedt

bottom of page