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 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 thePlayerscope, 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:
GetPlayersis an array that contains every player in the match- The 
FilteredArrayoperation checks each player in theGetPlayersarray, one at a time - The 
CurrentArrayElementrepresents the single player thatFilteredArrayis currently checking - The 
GetPlayerStateblock allows us to retrieve theCurrent Healthof the single player that is currently being checked - Finally, 
SetVariablestores the result of theFilteredArrayoperation into theWeakEnemiesvariable 
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 useDealDamagerather thanKill, becauseDealDamageallows 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 
Team1Healthglobal variable back to 0 - Loop over every player in the game
 - Check if their 
TeamIdis1 

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 
Team1Healthglobal variable - The 
CurrentHealthof 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 playerThe 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.