# In-Game Roles

{% hint style="success" %}
verified: 2025-11-19 version: v39
{% endhint %}

The web platform provides an interface to control what "roles" a user has access to, which we can then use in-game to limit or enable particular functionality. For more details on this, see [Setting Role Groups](/creation/worlds/invite-players/role-groups.md)

<figure><img src="/files/5qniSNXnqAtB5Z6UytXY" alt=""><figcaption></figcaption></figure>

`BPMC_M2Example_RolesComponent` is our example usage of this, demonstrating how you can read this information from the web platform and use it to affect gameplay.

<figure><img src="/files/Hd2hyImN6DBCedHNaxom" alt=""><figcaption></figcaption></figure>

## How to set up

### How to inform the web platform

To make sure the web platform knows what the in-game roles are, you need to provide them when you upload content.

* In your level's `World Settings`, there is a `Role List Provider` field, which takes a `M2_WorldRoleListProvider` class.

  <figure><img src="/files/53TBnyGmMXaAHOkvf27G" alt=""><figcaption></figcaption></figure>
* The CDO of the provided class has its `GetWorldRoleNames` function called. This is expected to return a list of names, which will be used as the list of possible in-game roles by the web platform.

  <figure><img src="/files/Mjw67SzIk42gvi8yK8tF" alt=""><figcaption><p>In the M2 example, we use an enum to define the possible roles</p></figcaption></figure>

### How to listen to the web platform

The `M2_WebServicesRoleDataProvider` world service (see [World Services](/creation/unreal-development/features-and-tutorials/helpers-and-extras/world-services.md)) can be used to fetch the roles granted to a given user. If the character does not have access to a given role (e.g. the role was not ticked), it will not show up in the resulting list.

<figure><img src="/files/HZLfe2eHy7T35oLOEbc2" alt=""><figcaption><p>The logic in the <code>BPMC_M2Example_RolesComponent</code> where we look up the roles list for the authoritative client.</p></figcaption></figure>

This can either be done on the client or the server (the client will be able to fetch its own roles, the server will be able to fetch any user's roles). To obtain the UserId on the server, you can use [Morpheus UserID](/creation/unreal-development/features-and-tutorials/helpers-and-extras/the-user-id-replication-component.md).

{% hint style="info" %}
NOTE: There is a trade-off between doing the roles logic on the server or the authoritative client. If roles management is run on the server, it adds extra security against cheating (clients can only request roles, but the server is responsible for validating and approving the requests), but it adds extra load on the server (the server needing to handle all requests, and validate which roles different players can switch to, instead of the client controlling their own state)
{% endhint %}

## How the example works

* In the example plugin, we have a `E_M2Example_Roles` enum, which we use as the list of roles.

  <figure><img src="/files/AepnWQV0EONNMWA0OwfT" alt=""><figcaption></figcaption></figure>
* The `BP_M2Example_RoleListProvider` converts this enum to a list of names, to inform the web platform

  <figure><img src="/files/JxTUslmNDBTxOhTyu20m" alt=""><figcaption></figcaption></figure>
* The `BPMC_M2Example_RolesComponent`, we communicate withthe `M2_WebServicesRoleDataProvider` to determine which roles we have access to. (On the Authoritative Client)
  * In the editor, since we won't have an associated world to grant us roles (and for bots, which don't have web platform profiles), we skip the lookup step and give everyone access to every role.
* The client replicates the role to all other connections using a background replicated integer property.
* If the client has access to no roles, we give them a default role
* We then use this replicated role to drive gameplay effects (by triggering a `OnRoleUpdated` event, and adding handlers). In our example, we have two:
  * The "elevated" role forces the character into the network and rendering foregrounds, so the character is prioritized over other regular participants (this can be used to make a "presenter"/VIP client)
  * The "fancy" role is a simple example of how the role can affect visuals. In this case, it attaches a prop to the character. (For more details on this, see [Attachments](/creation/unreal-development/features-and-tutorials/avatars/avatar-attachments.md))
    * We could also swap out the render target actor completely, using `ApplyPawnSet`

      <figure><img src="/files/Yf5aYQiiQSgRDTeta37q" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**A note on performance:**

Since the role in this example is replicated on the background, it runs on every client. For small scale events this is no problem, but when scaling to 18k+, any such property needs to be handled with care, especially when writing logic in BPs. If thousands of OnReps are triggered on the same frame, there will likely be a small hitch, even if each isn't doing all that much.

We are happy with this consideration for the example roles system; since it is not intended to be used frequently, we are happy that it won't cause performance issues.

TL;DR: Users shouldn't be changing roles frequently. That should just be for high level capabilities gated by the web platform. For pure gameplay features (e.g. which "character" a player is playing as), the roles system shouldn't be needed.
{% endhint %}

## I'm still using the deprecated roles system. How can I migrate across?

Since the old roles system has been deprecated, and is not usable with the example character, we advise any users of said system to migrate over when appropriate. However, the example roles system is much lighter than the original roles table, so doesn't do everything that the old system did. However, equivalents should be possible in your own project:

* Using a data table:
  * If you use a custom `M2_RoleListProvider`, you could make it take a data table's row names to provide to the web platform:

    <figure><img src="/files/a1YnKPoRdV3CAsoq87ot" alt=""><figcaption></figcaption></figure>
  * In your `OnRoleUpdated` handler, you could convert the replicated `RoleIndex` back to a data table row, and then apply the details to your character

    <figure><img src="/files/kwWJ8YtHB3voQPASfmfv" alt=""><figcaption></figcaption></figure>
* LOD level set:
  * This can be modified using the `ApplyPawnSet` helper function

    <figure><img src="/files/GzjzBe0l8bMNzOgsrxET" alt=""><figcaption></figcaption></figure>
* Capabilities:
  * Capabilities aren't currently used by the example character, but the capabilities component could be added, and then the capabilities can be granted or removed as a result of the role change, same as before. For more details see [Capabilities](/creation/unreal-development/features-and-tutorials/capabilities.md).

    <figure><img src="/files/G8SR6cEkQqzYtG8TWc9v" alt=""><figcaption></figcaption></figure>
* Gait speeds:
  * Similar story: this could be overridden in your project as a result of the role change.
  * However, in v39, we no longer use the `J_CharacterMovementComponent` in our example character, instead using Unreal's `CharacterMovementComponent` directly. We advise doing the same.
    * This means that "gait speeds" are no longer an in-built concept in the movement component. An equivalent could easily be achieved in a downstream project though by setting the `MaxWalkSpeed` directly. We have an example of doing this in our example base class: `BP_M2_PlayerCharacter`

      <figure><img src="/files/ASNwR3jw284J59j7bzri" alt=""><figcaption></figcaption></figure>
* Resizing:
  * Switch to using the example component described in [Resizing](/creation/unreal-development/features-and-tutorials/the-m2-example-plugin/resizing.md) (`BPMC_M2Example_ResizingComponent`), or use it as a reference point for your own implementation
  * (Character resizing in the deprecated character is tied to the `JM_ResizeableActorComponent`, which is not compatible with the simplified base character.)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.msquared.io/creation/unreal-development/features-and-tutorials/the-m2-example-plugin/in-game-roles.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
