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:

Rule scope types

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 the Player scope, we can use the EventPlayer payload here because the event is an OnPlayer... 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 the GetPlayers array, one at a time
  • The CurrentArrayElement represents the single player that FilteredArray is currently checking
  • The GetPlayerState block allows us to retrieve the Current Health of the single player that is currently being checked
  • Finally, SetVariable stores the result of the FilteredArray operation into the WeakEnemies variable

We can then use this subroutine and variable like so:

Instantly kill any player that drops below 50 health

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 use DealDamage rather than Kill, because DealDamage allows us to attribute this extra damage to the EventPlayer, which is done through the third parameter

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 is 1

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 in GetPlayers

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.