Skip to content

FOS Tablet System — Standard

Version 2.1.0 · requires FOS Essentials Core 1.1.0 or later · also requires FOS Localization 1.0.0, FOS Teleport 1.0.0

A tablet players summon in front of them: teleport menu, local toggles, world rules, and a full moderation panel with roles, freeze, isolation, mute and a synchronised log.

Requires FOS Essentials Core 1.1.0, FOS Localization 1.0.0 and FOS Teleport 1.0.0.

Upgrading from an earlier version? Read CHANGELOG.md first — a prefab you have modified does not carry over on its own.


This pack ships in editions, each in its own folder:

Assets/FOS/TabletSystem/
└── Standard/ ← you are here

A future Pro edition sits next to this one as Pro/, with its own assembly and its own components. It adds components beside the Standard ones and talks to them through their public API — it never replaces a component on the prefab. Upgrading therefore never costs you the wiring you already did.


  1. Drop FOS Essentials > FOS Tablet System > Standard > FOSTabletSystem into your scene.
  2. Assign the isolation zone: an empty Transform somewhere out of the way. Without it, isolating a player does nothing.
  3. Assign the player registry (FOSPlayerRegistry, from the Core) on the staff manager. It is optional, but without it the player list allocates an array on every join and leave.
  4. Fill the restored values on the staff manager to match your world’s movement and voice settings. They are what a player gets back when unfrozen or unmuted, and they overwrite whatever they had.
  5. Fill your teleport destinations, your toggle groups and your rules.

Component Role Networking
FOSTabletManager Summons, places and closes the tablet none
FOSTabletCaller Recalls the tablet to a fixed stand none
FOSTabletSettings Personal sliders, community settings, rules manual
FOSTabletToggleGroup Objects switched on and off together none
FOSTabletToggleButton Button driving one group none
FOSTabletStaffManager Roles, freeze, isolation, mute, authority manual
FOSTabletStaffRow One player’s row in the staff panel none
FOSTabletPermissions Per-role object visibility none
FOSTabletPermissionRow One player’s row in the role panel none
FOSTabletLogManager Synchronised moderation log manual
FOSTabletLogRow One log line none

This is the part worth reading before shipping a world with it.

The owner of the staff manager is the only authority. Every moderation action is a request sent to that owner through Network Calling. The owner checks the real calling player with NetworkCalling.CallingPlayer, which cannot be spoofed, and only then writes. A modified client can send the request; it will be refused.

Synced variables carry state, never commands. That is what makes late joiners safe: a player who arrives applies the current state instead of replaying stale actions. A SendCustomNetworkEvent is never replayed for them, which is exactly why the state does not live in events.

Ownership is restricted to staff. If the owner leaves and VRChat drops the object on a visitor, the staff member with the lowest player id reclaims it — a deterministic rule, so one client acts, not all of them at once.

The first admin is the first player of the instance, locked by display name. Trusting the master would be a hole: the master changes every time someone leaves, and the admin would eventually land on a stranger. The instance creator is recognised as admin too, and the founder can never be demoted — not by a moderator, not by another admin.

Checks in the row components are interface checks only. They avoid sending a request that is going to be refused and stop a visitor clicking dead buttons. They are not a security barrier and do not pretend to be one.

Isolation is a temporary confinement inside the current instance. A VRChat world cannot — and must not — enforce a persistent ban. Rejoining clears it, by design.

An isolated player is teleported to the isolation zone and sent back every two seconds if they walk out of its radius. Respawning does not release them either.


Role Value Can
Visitor 0 nothing
VIP 1 nothing more; the role exists for the visibility rules
Moderator 2 freeze, isolate, mute, set roles up to moderator
Admin 3 all of it, plus promoting admins and the community settings

Equal ranks can act on each other — two moderators can neutralise one another. That is a deliberate choice for the moment one of them goes wrong.

If the last admin leaves, the first moderator is promoted automatically. Without that succession, an instance loses moderation entirely until it is restarted.

Moderator and admin roles are remembered for the current instance only, by display name. A staff member who crashes and comes back to the same instance gets their role again.

Nothing is stored between sessions or across instances. Different groups open instances of the same world, and permissions from one have no business leaking into another. VIP is not remembered, and isolation is deliberately not remembered either.


FOSTabletPermissions shows and hides objects according to the local player’s role.

Roles are cumulative: a role gets everything shown to the roles below it. An admin sees the visitor, VIP and moderator objects without you copying them into four lists — that copying was the most common configuration mistake and the most tedious to undo.

The “hidden from” lists are exceptions for one role, applied last. An object that only appears in hidden from moderator is visible to everyone except moderators.

This is presentation, not protection. Hiding an object does not stop anyone reaching it another way.


A FOSTabletToggleGroup holds a list of objects and one state, applied to all of them. A FOSTabletToggleButton points at a group — directly, not through a string key.

Toggles are local on purpose. A comfort switch has no reason to be imposed on the rest of the instance, and synchronising it would spend bandwidth on something nobody asked for.

Several buttons can drive the same group: they register with it and their indicators stay in agreement.


In-game text goes through FOS Localization. Assign the locale manager and give the translation keys:

Where Keys
FOSTabletStaffManager four role names, in order: visitor, VIP, moderator, admin
FOSTabletSettings standard rules, adult rules

Without a locale manager, the fallback strings written next to those fields are used, and the tablet works in one language.

Any label of your own is a FOSLocalizedText like anywhere else in your world.


Teleport buttons in the tablet are FOS Teleport components: one FOSTeleportButton per destination, with its target Transform. This pack does not ship its own teleporter.

The one exception is teleport to a player in the staff panel: FOS Teleport aims at a fixed Transform in the scene, whereas that destination is a player who moves and may leave between the click and the arrival. It stays native here, and fails silently if the target is gone.


Every entry point below takes no parameter, so any script can reach it with SendCustomEvent.

Call On Effect
SummonTablet() / CloseTablet() FOSTabletManager Opens or closes the tablet
RecallTablet() FOSTabletCaller Brings the tablet back to its stand
FOSToggle() FOSTabletToggleGroup / FOSTabletToggleButton Flips a group
FOSRoleOf(id) / FOSIsStaff(id) / FOSIsAdmin(id) FOSTabletStaffManager Reads a role
FOSRequestFreeze/Isolation/Mute(id) FOSTabletStaffManager Requests an action
FOSRequestRole(id, role) FOSTabletStaffManager Requests a role change
FOSAdultContentIsOn() FOSTabletSettings Reads the adult content state

Three components publish state changes the same way. Call FOSRegister(this) on one, and expose a public parameterless method of the matching name:

Publisher Event to expose
FOSTabletStaffManager FOSApplyStaffState()
FOSTabletToggleGroup FOSApplyToggleState()
FOSLocaleManager FOSApplyLanguage()

A listener should also apply itself once in its own Start: it can register after the publisher has already set its initial state.

This is how the Pro edition plugs in, and how anything this pack does not cover plugs in too.


  • One staff manager per scene. Several would fight over the same players.
  • Nothing persists between sessions. Roles live in the current instance only.
  • Log size costs bandwidth. Every entry is synchronised; 30 is a sensible default.
  • Restored values overwrite the player’s settings. Match them to your world.
  • Quest and PC behave identically: there is no platform-specific code, and there could not be — Udon is compiled once for both.