JOSEPH SIEREJKO

GAME DEVELOPER : PROGRAMMER : DESIGNER

First Class Trouble
roles UI and Backend Programmer • UI/UX Designer • Account Services Management
software Unreal Engine 4 • Adobe Photoshop • Visual Studio 2019 • Perforce • JIRA
languages C++ • WPF • C# • JSON • XML • UE4 Blueprints
team size 18
platforms PlayStation™ 5 • PlayStation™ 4 • Steam • Epic Games Store
developer Invisible Walls™
First Class Trouble is an Asymmetrical 6 Player Multiplayer Game rooted in both Cooperation and Deception. Taking place on a Luxury Space Cruiser, 4 Residents, must survive an A.I. uprising, where 2 Players are secretly playing the role of Personoids. While the goal of the Residents is to Survive, Discover the Imposters, and Shut Down the Ship's A.I., the Personoids use a set of skills to sabotage ship systems, and Covertly Kill Residents.
Outside of Customization, my primary and ongoing responsibility is maintaining and optimizing our Account Services. This includes all Social Features and Platform-Specific utility functions with different Plugins. As we worked on Steam Early Access release, I started with the Steamworks SDK, and soon migrated over to the platform-agnostic plugin, OnlineSubsystem. Currently we are now using AccelByte, due to it's cross-platform functionality.
I still setup OnlineSubSystem to login the user, and get an auth token, which would then be passed into the AccelByte Login request to authenticate with the services. I have had success making all of the Account related features through their Endpoints.
  • Cloud Records for Individual users and global files for the game
    • With Cloud Records, I was able to store the Player Profile, Platform Info, and Customization Info
  • Lobby and Social Features
    • Cross-platform Friendslists
    • Party Lobbies
  • Matchmaking
  • Analytics, by creating events and sending metadata
In addition to our provider, I also wrote several HTTP requests to communicate with our internal moderation platform. One crucial purpose was that it allowed us to dynamically display ban messages when a player attempts to find a match. During early access, we had some real issues with feedback, and properly informing users that they have been banned. I developed the UI and added variables we would use to the request.
Design and Implementation
Customization, above anything else, is one of the most complex constructs in the game. I was first tasked with creating customization when starting at Invisible Walls, and it has undergone a few refactors over the last year. I am proud of the final product, having complete ownership over the entire feature, and independently developed and programmed it, top-to-bottom.
  • Designed UI elements in Photoshop to import into game
  • Developed blueprints for UI functionality, with a shared base class for Gamepad highlight states
  • Created a polymorphic set of classes for Male, Female and Vruumba Customization options
  • Monitoring Profiler to ensure optimized performance, and only cache asseets when they are needed
  • Assigned assets to Character Blueprints, in Main Menu and in Game
  • Data Table driven functionality, designed to be used by non-technical consumers, like our Designers
  • Utilizes Cloud Saves to record Player loadouts
Utilizing Data Tables
One of the major components I developed for Customization was an easy-to-use set of Data Tables in C++ and Blueprint. This allowed for anyone to easily add new items to the Customization Menu. Each item includes variables like Mesh, Materials, Entitlement Code, Achievement Code, level requirement, and Quality.
  • Mesh and Materials are assigned to a Skeletal Mesh on the Preview Character, and In-Game Character
  • Various types of Codes and level requirement determines whether the item is usable
    • Achievement Codes are unlocked when a specific Achievement or Trophy has been Unlocked
    • Entitlement Codes are used for DLC redemption, twitch drops, and events. In this case, content won't be visible unless user owns Item
  • I am also categorizing the items, to set up identifying traits like Quality, under a unique header
Replicating Customization In-Game
  • Using the Cloud Save, along with the Data-Tables setup in the game, users send their data to each other's Clients via Replication
  • Characters remain hidden until all features are setup
  • The same result occurs when players become VRuumbas after dying, replicating the settings to other dead players
A bigger contribution I made was when we rebuilt the main menu into a more gamepad-friendly Tab menu. Over the course of a week, I reworked all of the UI from our simple Vertical menu, to the user-friendly tab menu, which also gave me flexibility with features such as starting the matchmaker, and customizing your Avatar in the Cabin tab while searching for a game, which wasn't possible in the previous iteration.
  • We developed some automated binding functionality for Gamepad
    • For Example, unbinding the Right Face Button in Play Now and Rebind it to Stop Preview in the Cabin
  • I setup tracking selected items in a list to update cosmetic states (Such as the Customization Grid or FriendsList)
  • Submenus with Tab Menus that borrow functionality from the main Tab Menu
  • Base C++ functionality that is inherited in several UserWidgets that make up the tab menu, limiting specific logic for each menu
I wrote a C++ class that updats a button's UI, regardless of mouse or gamepad interaction. This class is inherited by most Button-Based UserWidgets, and allows for clean and flexible implementations
  • Gamepad feedback events utilized On Focus Added and On Focus Lost events
  • Mouse events were bound to the UButton in the Constructor
  • Added BlueprintImplementable events in base class, for custom functionality that needed to be implemented in Blueprints.
  • EditDefaultOnly FSlateBrush variables to set color, image, and transparency to modify button states in various Blueprints
The Oval button is the most used button widget in the game. I developed tools to modify it's size, font, color, interaction type (gamepad button or navigation), and various other options. The purpose was to make it easy-to-use for the designers.
Here is an example of our Find Game Button. It also is utilizing the BlueprintImplementableEvent trigger to start the countdown timer and replicate it to the other users in the party.
Late in development, I added a navigation method to allow buttons to be navigable with Gamepad D-Pad and Joystick.
The Settings menu was the largest project in terms of adding the focused/hovered state. This was due to encapsulating the functionality that previously existed into a new set of widgets.
Like Customization, the Friendslist has had multiple iterations, UI overhauls, and a few different SDK updates requiring changes to the functionality.
  • It uses a tab-menu I wrote for our submenus, and has a few tabs for both friend and party related lists
  • Each user is setup with a #XXXX code to allow users on various platforms to retain their original Platform name, while making a unique identifier.
  • Uses Presence to get online/offline status, and a URL-encoded method to store Platform Info
    • If No Presence data is available, Cloud Saves are used to get Plaform Info
The Party system is a companion to Friendslist, and as you recieve friend requests through an in-game popup, you are teleported to their lobby, and using notifiers on the invitee, and an accept response on all members in the party, the UI is updated, and the party members are now linked when searching for a game. There is a bunch of Characters in the Main Menu that are enabled, and assigned Customization loadout via Cloud Saves. The Party List is also updated. Aside from the Playstation Specific logic for system-level parties, I had complete ownership over the design and implementation.
Server-Driven UI, Without a Patch
One of my favorite Features that I got to implement was using Cloud Files to instantly Update UI. This allowed us to add/remove leaderboards, prep DLC for release, and have dynamic service Messages, all without disrupting users and requiring them to update the game.
  • Structures are put in a JSon format and reformatted into structs that will control how UI is displayed
  • A Language object is in the JSon to provide a way to localize text.
Downloadable Content Implementation
The DLC UI is my favorite use-case for Server-Driven UI. It is also the most useful. It allows us to prepare for a newly released Pack, and just enable as needed.
Global JSon Schema
  • bDoubleSpan allows us to determine width in grid
  • discount is straightforward, input the percent off the item is, and a UI will popup with discount value
  • enabled is to hide item until ready for release
  • lang is for localization, and is used in a very server-driven UI schemas.
    • lang has a unique FExternalLocalizationData struct that takes Unreal's CurrentLanguage, compares to the 2 character Culture Code, and finds which language to use in-game
  • loadOrder sorts elements on the client by this value
  • The Id variables are just store AppId's for each platform, determined and assigned by the client
  • The Thumbnail Urls are stored on our storage server, and I wrote a conversion function to make an HTTP request using the URL, and convert it from raw image data and into a usable UTexture2D
{
    "packs": [
        {
            "bDoubleSpan": boolean,
            "description": string,
            "discount": float,
            "enabled": boolean,
            "lang": {
                "ar": string,
                "de": string,
                "en": string,
                "es": string,
                "fr": string,
                "ja": string,
                "ko": string,
                "pt": string,
                "ru": string,
                "th": string,
                "yi": string,
                "zh": string
            },
            "loadOrder": integer,
            "ps4Id": string,
            "ps5Id": string,
            "steamId": string,
            "thumbnailUrlDoubleSpan": string,
            "thumbnailUrlSingleSpan": string
        }
    ]
}
Server-Driven UI, Without a Patch
One of my favorite Features that I got to implement was using Cloud Files to instantly Update UI. This allowed us to add/remove leaderboards, prep DLC for release, and have dynamic service Messages, all without disrupting users and requiring them to update the game.
  • Structures are put in a JSon format and reformatted into structs that will control how UI is displayed
  • A Language object is in the JSon to provide a way to localize text.
Downloadable Content Implementation
The DLC UI is my favorite use-case for Server-Driven UI. It is also the most useful. It allows us to prepare for a newly released Pack, and just enable as needed.
Global JSon Schema
  • bDoubleSpan allows us to determine width in grid
  • discount is straightforward, input the percent off the item is, and a UI will popup with discount value
  • enabled is to hide item until ready for release
  • lang is for localization, and is used in a very server-driven UI schemas.
    • lang has a unique FExternalLocalizationData struct that takes Unreal's CurrentLanguage, compares to the 2 character Culture Code, and finds which language to use in-game
  • loadOrder sorts elements on the client by this value
  • The Id variables are just store AppId's for each platform, determined and assigned by the client
  • The Thumbnail Urls are stored on our storage server, and I wrote a conversion function to make an HTTP request using the URL, and convert it from raw image data and into a usable UTexture2D
{
    "packs": [
        {
            "bDoubleSpan": boolean,
            "description": string,
            "discount": float,
            "enabled": boolean,
            "lang": {
                "ar": string,
                "de": string,
                "en": string,
                "es": string,
                "fr": string,
                "ja": string,
                "ko": string,
                "pt": string,
                "ru": string,
                "th": string,
                "yi": string,
                "zh": string
            },
            "loadOrder": integer,
            "ps4Id": string,
            "ps5Id": string,
            "steamId": string,
            "thumbnailUrlDoubleSpan": string,
            "thumbnailUrlSingleSpan": string
        }
    ]
}