Account entitlements - rebaserHEAD/NexusForever GitHub Wiki

explanation, committed verified 2026-10-14 stable a4e75b18

On stable, every character holds the seven base entitlements the client expects of a full account. Without them, the client treats the player as a trial account: the trade window and the marketplace won't open, and level and currency are capped.

Upstream: #590. On a stock game_rework server, every account looks like a trial account to the client.

The problem

What a trial account means to the client

Missing entitlement What the client does
EconomyParticipation The trade window (trading.lua) and both marketplace windows refuse to open
BaseCharacterProgressionCaps Caps the character at level 20
BaseCurrencyCaps Caps credits at 500,000 and renown at 5,000

The base set also includes GuildsAccess, FullSocialParticipation, CREDDUsage and InGameCSAccess.

Why the server never granted them

Each row of the Entitlement game table carries flags. Bit 0x1 marks a character entitlement, as opposed to an account one. Bit 0x2 means hidden: the client leaves the entitlement out of its UI, but still stores it and counts it.

Upstream's server reads bit 0x2 as disabled. Every one of the seven base entitlements carries it, so the server refused to grant any of them, the GM command included, and zeroed any reward property that reads one.

So every account looked like a trial for two reasons at once: nothing granted the base set by default, and the misread bit blocked the one way to add it by hand.

The fix

The flag

EntitlementFlags.Disabled is renamed Hidden, and both checks that refused it are gone.

The base set

When a character loads, the server adds any of these it doesn't already hold, each with a value of 1, and saves them with the character as new rows:

Entitlement Id
BaseCharacterProgressionCaps 10
BaseCurrencyCaps 14
EconomyParticipation 15
GuildsAccess 16
FullSocialParticipation 17
CREDDUsage 18
InGameCSAccess 19

[!NOTE] Saving them needed one more fix on the way. A new character entitlement used to be saved as an update to a row that didn't exist, which failed the first time anything granted one. New ones are inserted now.

How it was verified

On a local server, with both test accounts' entitlements cleared first:

  • Both characters were given the seven entitlements when they logged in, and the rows saved cleanly.
  • The trade window now gets past the client's check, and the client sends ClientP2PTradingInitiateTrade. The server doesn't handle trading yet, so that's as far as a trade goes for now; Trading design is the work in progress.

Not watched yet: a character levelling past 20 with the cap lifted.

Where the code lives

Piece Path
The base set and the grant on load Source/NexusForever.Game/Entity/CharacterEntitlementManager.cs
The insert fix Source/NexusForever.Game/Entity/CharacterEntitlement.cs
The flag Source/NexusForever.Game.Static/Entity/EntitlementFlags.cs
The two checks that refused it Source/NexusForever.Game/Entitlement/EntitlementManager.cs, Source/NexusForever.Game/Account/Reward/RewardPropertyManager.cs

The branch is base-entitlements.