Battlefield 2042 Portal - Creating a Zombies Game Mode
This guide explains how to create a Zombies game mode using the Battlefield 2042 Portal Rules Editor.
This guide that explains how use the Battlefield 2042 Portal Rules Editor to:
- Infect random players 45 seconds after the match starts
- Change player teams on death
- Spawn zombies near humans
- Spawn resupply crates near humans
- End the match when all humans are dead
- Buff zombies over time
Part 1 - Team Management
When the match first starts, we want every player to be a human so they can run around and pick a position they want to defend. Then after 45 seconds elapses we'll infect random players in a loop until there's 8 humans left.
Note that TeamId 1 represents humans, and TeamId 2 represents zombies
When setting up the gamemode, we can't specify a team size of zero for the zombies team, so we need to manually move everyone over to the human team when they first deploy:
This has two conditions:
- The initial infection hasn't happened yet (i.e. there are no zombies)
- The player was placed on the zombies team (this will happen because the gamemode settings say 32v32)
Part 2 - Infecting Random Players
We can use the Wait
action to delay this rule from occuring, so that players can run around for 45 seconds at the start of the match before they get infected.
The GetAliveHumans
subroutine populates the AliveHumans
and AliveHumanCount
global variables and will be re-used throughout many of our rules.
In the rule below, we call GetAliveHumans
and infect random players until GetAliveHumans
is no longer greater than 8. We call GetAliveHumans
at the end of the loop as we need to update our global variables after infecting a player.
Once this rule has executed we set InitialInfectionOccured
to true so that our other rules can be aware of the fact that we're now in zombieland.
Part 3 - Zombification
This one is pretty simple - when a zombie kills a human, that human should be moved over to the other team.
Note there's a loophole here - if a human kills themself, they will remain a human. We counter that in Part 5
Part 4 - Input Restrictions
If zombies could shoot, the humans would have a tough time surviving. We need to stop zombies from being able to switch weapons, and also ensure they have no ammo just in case there's a glitch that allows them to switch to a gun.
Part 5 - Zombie Spawning
Criteria
This is a more complicated rule. When a zombie spawns we need to ensure:
- They aren't on top of an alive human
- They aren't super far away from all humans
In this rule we'll aim to spawn a zombie at a position where the minimum distance to an alive human is 50 meters, which we can achieve using this process:
- Get a random alive player's position
- Pick a random horizontal direction (random yaw, zero pitch)
- Multiply that direction by 50 meters
- Add that direction to the alive player's position
- Check if this final position is within 49.5 meters of an enemy. If so, we need to pick a new random position. If not, this is a valid spawn position
For example, in the diagram below there are 4 alive humans. The circles around the humans are the area that we should not spawn a zombie, as that's too close.
Player Variables
To start, we'll have this rule structure:
The Condition
is present as this should only apply to players who spawn after the initial infection occurs. This rule uses two new player variables:
Spawned
- keep track of whether or not we have successfully spawned this zombieSpawnPosition
- this will store the random spawn position we will generate
The Maths (or 'Math' for the Americans)
To get the position of a random player, we will use GetPlayerState
and PlayerStateVector
:
To get a random horizontal vector with length 50, we'll use RandomReal
to generate a random number between -π and π (a full circle), then we convert this to a vector using DirectionFromAngles
and Multiply
it by 50:
Then we'll Add
it to the random player's position and store it in the SpawnPosition
player variable:
Now that we've generated this position, we need to ensure it's not within 50 meters of any other players:
We do this by looping over all alive humans, checking the distance between SpawnPosition
and the human's position, and failing if the distance is less than 49.5:
Note that at the start this setsSpawned
to true, then setsSpawned
to false if the position is too close to an alive human.
This loop uses a Break
operation because there's no point comparing SpawnPosition
to humans #2, #3 and #4 if we already know this position is too close to human #1.
The super-long LessThan
operator compares the DistanceBetween
the alive human's position and the SpawnPosition
player variable:
Note that this uses a new player variable called SpawnIndex
to loop over the alive humans
The full rule is as follows:
Note that we set the TeamId
of the player to 2
, so that players who join the match after the initial infection occurs will become zombies, and so that humans who kill themselves will respawn as a zombie.
Part 6 - Resupply
The humans will be using up a lot of ammo defending themselves from these zombies, so every 2 minutes we'll resupply each human's ammo.
We use a while
loop here so that the players will receive loadout crates until the match ends.
Part 7 - Winning
The humans win by lasting till the timer runs out, but the zombies can win by killing all alive humans:
To ensure this condition fires, we need to run the GetAliveHumans
subroutine to update the global AliveHumanCount
variable after every human dies:
We also need to run the subroutine if a human leaves the match:
Part 8 - Optional Buffs
To help balance your game mode you might want to buff zombies when they get a kill, or buff alive humans if a human dies. For example when a zombie kills a human, you can give the zombie +50 max health like so:
Note that we useMax(..., 150)
because the default value forZombieMaxHealth
is 0
Another option is to increase zombie max health steadily over 20 minutes. We can do this using the TrackVariableOverTime
and WaitUntil
actions:
This sets the ZombieMaxHealth
to the default value 100, then gradually increases it up to 300 over the next 1200 seconds (20 minutes).
Then in a While
loop we:
- set the player's max health
- wait until
ZombieMaxHealth - PlayerStateNumber.MaxHealth >= 1
The reason for the WaitUntil
action is to avoid spam, as I'm guessing TrackVariableOverTime
increases the ZombieMaxHealth
value as a decimal value, rather than an integer.
Conclusion
That's all for this guide, if you have any further questions you can ask them in the #portal-builder channel on the Official Battlefield Discord server.