Battlefield 2042 Portal - Rules Editor Guide
This guide explains how to use the Battlefield 2042 Portal Rule Editor to create new gamemodes and fun gimmicks.
This is a bit different from my usual posts but as some of you may know, Simon and I are huge Battlefield fans. I've been playing around with the Rules Editor for quite some time and created this guide to help you get started.
Last updated 13/11/2021 8:10pm AEDT
Overview
Types
Each Type icon represents a different kind of value:
There is some ambiguity around the 'Element' type, since some operations accept elements related to the player's inventory and some operations accept elements related to the player's soldier, for example:
To see which types are expected by each action and operation, right click it and click Help
to view documentation:
Event Rules
The Portal supports a few different types of Events - such as 'On Game Mode Start', 'On Player Death' - which we can attach Actions to.
For example, this rule contains:
- A name -
Zombify
- An event -
OnPlayerDied
- An action -
SetTeamId
, which moves the dead player to Team 1
Ongoing Rules
Rules can also be Ongoing, for example this rule will kill a player that's on the ground.
Scope
Ongoing rules have a Scope - either Global, Player or Team
- which affects which event payloads can be used within the rule:
Event Payloads
Event payloads - such as EventPlayer and EventTeam
- can only be used with their respective scope. For example, the EventPlayer
payload cannot be used in the Global scope:
Variables
You can create variables that store:
- Numbers
- Text
- Players
- Vectors
- Arrays
Variables can be stored globally and accessed anywhere, or you can store variables on a specific player.
To start, click the Variables
tab in the bottom-left, and then click Manage Variables
at the top:
From here, click New Variable
and then select the Player scope:
You can now combine this variable with the Add
operation to increase a player's max health by 10 each time they get a kill:
Note that although this Rule doesn't specify thePlayer
scope, we can use the EventPlayer payload here because the event is anOnPlayer...
event
Arrays
Arrays are useful for creating collections of players. As an example, let's create an array that contains all players with less than 50 health.
First, we need to create a global variable that will contain these players:
Then, we'll create a subroutine, so we can re-use this code in many different Rules.
This subroutine will filter through all players and create an array of players who have less than 50 health. This array will then be stored in the WeakEnemies
global variable.
Let's break it down:
GetPlayers
is an array that contains every player in the match- The
FilteredArray
operation checks each player in theGetPlayers
array, one at a time - The
CurrentArrayElement
represents the single player thatFilteredArray
is currently checking - The
GetPlayerState
block allows us to retrieve theCurrent Health
of the single player that is currently being checked - Finally,
SetVariable
stores the result of theFilteredArray
operation into theWeakEnemies
variable
We can then use this subroutine and variable like so:
Examples
Jump Damage
This Rule will deal 10 damage to all enemies when a player jumps
To start, let's create a subroutine that gets all enemies and stores them in a global array called Enemies
:
We can then use the PlayerStateBool
expression to check if the player is currently jumping, and if so deal 10 damage to all enemies:
However, this Rule will deal damage to all enemies while a player is jumping, but we want to deal damage when a player jumps. To do this, we'll need to add a new Player variable called Jumped
, and set it to true after it deals damage to all enemies:
This will permanently set their Jumped
variable to true when they first jump, so we need an extra statement that sets the Jumped
variable back to false when they finish jumping:
Juggernaut Landing
This rule will deal 100 damage to all enemies near a player that lands on the ground
To start, we'll create:
- a new global variable called
NearEnemies
- a new player variable called
OnGround
- a new subroutine called
GetNearbyEnemies
, which gets all players that are within 3 blocks of the player.
Note that the above FilteredArray
operation does not check Team IDs. This is because the expression was too long to get a high-resolution screenshot of, so this rule will damage friendlies as well.
Our rule will then use the new player OnGround
variable to track whether a player has just landed on the ground after jumping:
Bonus Kill
Kill an extra random enemy when getting a kill
To start, we'll create:
- a new global variable called
AliveEnemies
- a new subroutine called
GetAliveEnemies
, which gets all enemy players with greater than zero health
Then when a player lands a kill, we call the GetAliveEnemies
subroutine to update the AliveEnemies
global array, and then kill a random player from AliveEnemies
:
Note that we useDealDamage
rather thanKill
, becauseDealDamage
allows us to attribute this extra damage to theEventPlayer
, which is done through the third parameter
Life Link
All players on one team will share the same health pool
This is a more complex one, as we need to:
- accumulate the total health of all players on a team
- divide the total health by the number of players on that team, so we know how much health each player should have
- damage all players on a team by a specific amount so that their health is the same
To start, we'll create these three global variables. TeamHealth would be a team-scoped variable but I don't think EventTeam
is working yet.
Then we'll create two subroutines, since this task will require a decent amount of code and it's best to split it up:
To start, the GetTotalTeamHealths
subroutine will:
- Reset the
Team1Health
global variable back to 0 - Loop over every player in the game
- Check if their
TeamId
is1
Then, if their TeamId
is 1
, we need to add the health of this player to the Team1Health
global variable:
We do this using the Add
operator, which takes two parameters:
- The
Team1Health
global variable - The
CurrentHealth
of the nth player inGetPlayers
The result is then stored back in the Team1Health
global variable.
To distribute the total team health among all players, we first divide Team1Health
by the number of players in Team 1 to determine how much health each team member should have. This means that Team1Health
now holds the average player health, rather than the total team health.
Then we need to either heal or damage each player in Team 1 to ensure they have the same health value:
This assumes that a negative value sent to DealDamage
will heal the player
The Subtract
operation in the above picture contains these two values, where it will damage the player by the amount PlayerHealth - Team1Health
:
For example if Player X has 80 health, and the value of Team1Health
is 70, we need to deal 10 damage to Player X.
Lastly, to make this work for both teams, we'll duplicate the above code but instead use the Team2Health
global variable with the TeamId 2
:
Issues
Currently the EventTeam
payload cannot be used. The documentation for it has this example:
Although the Rules Editor states that it's invalid:
Community
If you have some cool ideas or extra questions, head over to the Battlefield Discord server and chat with us in the #portal channel.
Special thanks to Dragory for answering everyone's questions regarding the Rules Editor, as well as for providing a great solution to the Jump Damage rule.