# Roleplay Characters

Roleplay Core 0.9.0 gebruikt de transactionele characterdatabase die in 0.3.0 is geïntroduceerd
offline-first, transactioneel characterdomein.

## Identiteit en privacy

Bij de eerste characteractie leest de server de beschikbare FiveM-identifiers
via de artifact-3258-compatibele primitive natives. Alleen SHA-256-hashes en het
identifiertype worden lokaal opgeslagen. Als meerdere identifiers al naar
verschillende lokale spelers wijzen, stopt de transactie met een conflict.

De cloudprojectie ontvangt uitsluitend de primaire identifierhash. Daarmee kan
het control-plane een character aan een reeds bekende `Player` koppelen zonder
een ruwe identifier in character-events te plaatsen.

## Character lifecycle

De lokale tabellen bewaren:

- meerdere characters per speler, begrensd door `platform_max_characters`;
- naam, geboortedatum, appearance en extensible metadata;
- gekozen spawn, laatste geldige positie en totale speeltijd;
- server-side character permissions;
- monotone lokale versie, selectie- en archieftijd.

`/characters` opent de characterselector. Spelers kunnen een character maken,
een allowlisted spawn kiezen, spelen en hun eigen character archiveren. De
client rapporteert alleen begrensde positie- en appearancegegevens voor het
actieve character; eigenaarschap wordt altijd opnieuw op de server bepaald.

Elke create-, select-, update-, appearance-, runtime- en archive-mutatie schrijft
in dezelfde InnoDB-transactie naar de lokale state en, waar cloudsynchronisatie
nodig is, naar `gc_rp_cloud_outbox`.

## Exports

JavaScript/TypeScript:

```ts
await exports['platform-characters'].listCharacters(source);
await exports['platform-characters'].createCharacter(source, input);
await exports['platform-characters'].selectCharacter(source, characterId, spawnKey);
await exports['platform-characters'].archiveCharacter(source, characterId);
exports['platform-characters'].hasCharacterPermission(characterId, 'jobs.police');
```

Lua gebruikt `ListCharacters`, `CreateCharacter`, `SelectCharacter`,
`ArchiveCharacter`, `GetActiveCharacter`, `GetCharacterById` en
`HasCharacterPermission`.

## Paneelbeheer

Het Operations-paneel bevat een afzonderlijk Characters-scherm met:

- actieve en gearchiveerde characters per server;
- gekoppelde cloudspeler, geboortedatum, speeltijd en laatste positie;
- appearance- en metadata-JSON;
- character permissions;
- geaudite wijzig- en archiveeracties.

Lezen vereist `servers.characters.read`; wijzigen en archiveren vereist
`servers.characters.manage`. Mutaties worden als allowlisted
`CHARACTER_MANAGE`-command naar bridge 0.13.0 gestuurd. De cloudweergave wordt
pas door de volgende ondertekende, idempotente characterprojectie bijgewerkt.
