
| Role: | Game Designer, Scripter and Level Designer |
| Team Size: | 3 members (with a Level/Tech Artist, Creative Director) |
| Dev Time: | 4 months (PC VR Arcade version) + 6 months (Standalone VR version) |
| Engine: | Unreal Engine 4 |
| Genre: | VR Multiplayer FPS |
| Players: | 1-8 players |
Gameplay Videos
Game Systems
I share the design credit with the Creative Director and scripted / programmed all aspects of the game. Below, I highlight few game systems with their design journey and implementation choices. I also handled the level design of the map in the game.
Capture The Flag Mode
Design Goals
a. Create a standard 2-flag CTF gameplay familiar to gamers
b. Ensure the experience is accessible to non gamers
c. Ensure high replayablity for competitive players
Design to Implementation
a. Ensured all the flag states were handled with visual cues and voice over communication to each player team.
– Team Flag states: Reclaim, Kill Player (enemy holding the team flag), Team Flag stolen (Flag Base).
– Enemy Flag states: Capture, Escort Teammate (with enemy flag), Score Flag (Flag Base).
b. Added accessible flag interaction mechanics where either hand could pick up / drop the flag.
c. Flag runners were given a Handgun in their offhand which introduced interesting playstyle choice either drop the flag at intervals to regain their original loadout or push forward with the flag capture.
d. Reclaiming one’s team flag required players to stay with a flag radius for 5 seconds. One’s team flag needed to be safe at their base to allow scoring an enemy team flag.
Supply Drop Mechanic
Design Goals
As the game is meant to be accessible to all players, the main goals were to
a. End the game on a memorable note, even for a player on the losing side.
b. Give the losing team an opportunity to gain momentum and catch up to the leading team’s score.
c. Add risk/reward gameplay for competitive players.
Taking influence from Density’s multiplayer mode wherein the Heavy Ammo becomes available mid-gameplay to draw players to the same location, we decided to add a Dual Miniguns as a supply drop mid-gameplay.
Design to Implementation
a. A supply drop helicopter was added to fly over 1 of 3 map lanes and drop the supply crate.
b. The supply crate takes 30s to land allowing players to fight to take control of the drop zone.
c. Players have 60s from when the Miniguns land on the ground to the end of each gameplay half.
d. Players holding the Miniguns drop them when they die, allowing other players to pick them up.
e. Async load the Supply Drop related assets (Helicopter, Supply Crate, Miniguns) on all the clients right before being spawned in on the server, to make efficient use of the runtime memory.
Weapon Class Design
Design Goals
a. As this is a bundled game with the product purchase, the weapon classes needed to be easy to pick up and play for non-gamers and gamers alike.
b. Offer diversified playstyles for replayablity.

Initial Design
a. 3 weapon classes: Dual SMGs, Assault Rifle / Grenade and Shotgun / Grenade were chosen to allow for close and long range options with any weapon class.
b. The grenade was given a remote detonation feature to allow for a skill based mechanic but also keep the action fast paced.
c. The initial weapon balance followed the arcade version, balanced to be the best first time experience for players, where weapons felt equally powerful but only gave the perception of offering different playstyles.
d. Weapon attributes were set up as data assets and child weapon classes were assigned the appropriate attribute data asset.
Initial Playtest Feedback
Internal playtests aimed at a home consumer audience with repeated play sessions brought out the following feedback.
Players used the Assault rifle / Grenade class more than 80% of the time.
With this observation in mind, the following feedback from players made sense.
a. Total play session per player was short and players quit feeling frustrated (1-2 games before quitting.
b. Players complained about lack of depth in gameplay i.e. no strategies to try every time they died.
c. Players would run out into the open without using cover / different routes the map offered.
Exploits
e. The grenade’s detonation was exploited by using it as a close range weapon as it wouldn’t damage the player themselves.
f. Players stuck their head / weapons into objects to shoot at players from undesired locations.
Final Design to Implementation
a. The SMG, Assault Rifle and Shotgun classes had their weapon attributes rebalanced aggressively to be the most effective within the designated range of engagement and perceptively weak when used at the unintended range i.e.
increased damage within range, increased magazine size and/or reduced reload time in some cases.
b. The grenade was adjusted to deal damage and a score penalty on self detonation, so players were encouraged to use it more for mid-long range gameplay.
c. Grenade was removed from the Assault rifle class to make the weapon classes more distinct from one another in terms of playstyle.
d. I added custom detection logic to ensure the player camera and weapons were disabled and communicated it to the player visually (weapon material glows holographic red, camera fades to black), when they were inside environmental objects.
The above changes had a chain reaction that led to players using the whole map and cover more effectively. It forced players to use corners / passageways more with the Shotgun, long range vantage points with the Assault Rifle and a balanced gameplay style with the dual SMGs.
Players were killed by other players using different weapons more, which led to the perception that other weapon classes were viable strategies too.
Weapon Attributes
Using Data Assets and Soft References
The child weapon classes had associated Data Assets to help modify individual weapon attributes outside the actual weapon class. The Base Weapon Class retrieves the weapon asset files and attributes via a cast to the base weapon attribute class. The child weapon blueprints set the appropriate soft reference to their attribute data asset, so weapon related assets are only loaded into memory when needed.
Weapon FX Pool Manager
Ensured that the number of Bullet Trail and Impact particle effects could be capped to a certain number to ensure stable performance during 8-player gameplay.
Note: Please use Fullscreen view, Right Mouse click to move around, Ctrl+Mouse Scroll to zoom-out.
Player Spawn Selection
Design Goals
I laid out simple design goals to guide the implementation details.
a. Reduce occurrences of players spawning on / near enemy players.
b. Ensure players spawn in all parts of the map over time.
Design to Implementation
a. Track Empty Spawn zones and Occupied Spawn Zones using zone trigger volumes.
b. If all spawn zones are occupied, prefer ones where enemies are the furthest away from the spawn location.
c. If empty spawn zones are available, track the last time a spawn location was used to prefer the earliest used spawn location.
Although I primarily worked with Blueprint Visual Scripting I got to code in C++ for some features.
//Spawn Selection code sample:
AProjectPlayerStart* AProjectGameMode::GetBestGameplayPlayerStartPerTeam_Implementation(const TArray<APlayerStart*>& Starts)
{
// Check if the input array is empty
if (Starts.Num() == 0)
{
return nullptr;
}
TArray<AProjectPlayerStart*> AllowedStarts;
// Cast to AProjectPlayerStart and add valid entries to AllowedStarts
for (APlayerStart* Start : Starts)
{
if (AProjectPlayerStart* PlayerStart = Cast<AProjectPlayerStart>(Start))
{
AllowedStarts.Add(PlayerStart);
}
}
UProjectGameInstance* GameInstance = Cast<UProjectGameInstance>(GetWorld()->GetGameInstance());
AProjectPlayerStart* BestPlayerStart = nullptr;
TArray<AProjectPlayerStart*> EmptySpawnZones;
// Find all empty spawn zones
for (AProjectPlayerStart* PlayerStart : AllowedStarts)
{
if (!PlayerStart->GetWhetherStartHasBeenSpawnedAt() &&
PlayerStart->GetAllPlayersInSpawnZone().Num() == 0)
{
EmptySpawnZones.AddUnique(PlayerStart);
}
}
UE_LOG(LogTemp, Log, TEXT("Number of empty spawn zones found: %i"), EmptySpawnZones.Num());
// If empty spawn zones are found, select the earliest used one
if (EmptySpawnZones.Num() > 0)
{
// Randomize the first index
int32 RandomIndex = FMath::RandRange(0, EmptySpawnZones.Num() - 1);
EmptySpawnZones.Swap(0, RandomIndex);
float EarliestLastSpawnTime = MAX_FLT;
for (AProjectPlayerStart* PlayerStart : EmptySpawnZones)
{
float LastSpawnTime = PlayerStart->GetGameTimeWhenLastSpawned();
if (LastSpawnTime < EarliestLastSpawnTime)
{
EarliestLastSpawnTime = LastSpawnTime;
BestPlayerStart = PlayerStart;
}
}
}
else
{
// Find the spawn point furthest away from players
float FurthestDistanceToPlayer = 0.0f;
for (AProjectPlayerStart* PlayerStart : AllowedStarts)
{
float DistanceToClosestPlayer = PlayerStart->GetDistanceToClosestPlayerInsideSpawnZone();
if (DistanceToClosestPlayer > FurthestDistanceToPlayer)
{
FurthestDistanceToPlayer = DistanceToClosestPlayer;
BestPlayerStart = PlayerStart;
}
}
}
// If no suitable start found, pick a random start
if (!BestPlayerStart)
{
BestPlayerStart = AllowedStarts[FMath::RandRange(0, AllowedStarts.Num() - 1)];
}
// Mark the selected spawn point as used
if (BestPlayerStart)
{
BestPlayerStart->SetWhetherStartHasBeenSpawnedAt(true);
UE_LOG(LogTemp, Log, TEXT("Best Player Start selected: %s, LastSpawnGameTime: %f, NumPlayersInZone: %i, DistanceToPlayer: %f"),
*BestPlayerStart->GetName(),
BestPlayerStart->GetGameTimeWhenLastSpawned(),
BestPlayerStart->GetAllPlayersInSpawnZone().Num(),
BestPlayerStart->GetDistanceToClosestPlayerInsideSpawnZone());
}
return BestPlayerStart;
}
Dynamic Map Layout
Design Goals
a. Ensure the moment to moment gameplay pacing remains similar irrespective of player count in the game.
b. Allow players to choose the size of map to change the engagement pacing.
Design to Implementation
a. The map was designed and blocked out as an asymmetric 3-lane layout, that offered unique engagement opportunities on the Left (vantage point high vs low gameplay) and Right lane (close quarters interiors).
b. The 3 lanes allowed sectioning the map for different player counts.
– Small Map – 4 players : Center Lane + Right lanes.
– Medium Map – 6 Players : Left + Center lanes.
– Large Map – 8 Players : Left + Center + Right lanes.
I worked with the level artist to place contextual boundary assets that were level streamed in based which lanes were closed off.
c. The Spawn points, Supply drop locations and Flag positions were tagged so ones outside the active lanes of the chosen map size would be deactivated.
c. To allow for players to adjust the engagement pacing,
– Player count of 1-4 could choose between a Small, Medium or Large map size.
– Player count of 5-6 could choose between a Medium or Large map size.
(Max player count of 8 could only choose the Large map size).





















