Skip to content

Private parts

Game master notes, the character’s secret, the disguised NPC’s true sheet: some parts of the document must not reach the players. A private part is kept in the room, but the RPG Desk server only hands it to whoever may see it. For the others, it does not exist: not on the screen, not in the data.

Declare the parts in the manifest, on the sheet:

"sheets": [
{
"type": "com.yourname.system.sheet",
"title": "Character",
"private": { "gm": "gm", "secrets": "owner" }
}
]
Value Who receives the part
"gm" game masters only
"owner" the sheet’s owner and the game masters

The name is the part’s path: "gm" covers gm.notes, gm.treasure and everything else inside the gm group. Whoever does not receive the part cannot write to it either.

On the page, show the part only to whoever receives it, with data-role:

<nav data-tabs>
<button data-tab="main">Main</button>
<button data-tab="gm" data-role="gm">GM</button>
</nav>
<section data-tab-panel="gm">
<textarea data-field="gm.notes" placeholder="Only game masters see this"></textarea>
</section>

data-role alone only hides the button; the manifest’s private is what keeps the secret. Test it in test mode, switching the Role to Another player: the tab disappears, and RPGDesk.doc.get('gm') gives undefined.

Room tables have no owner, and the manifest’s private does not apply to them (the verifier warns you). On a table, the game master hides parts from code, on the spot:

await doc.restrict(['npcs', '#' + id], 'gm'); // this NPC becomes game master only
await doc.restrict(['npcs', '#' + id], null); // back to everyone

doc.restrict(path, 'gm' | 'owner' | null) only works for game masters. It is what the examples’ NPC table does with the Hidden from players checkbox: see Room tables.