Build and test a multiplayer game
Configure private 2-8 player rooms, assign vehicle slots, share state, and test a published multiplayer release.
What multiplayer supports
Airogel multiplayer provides private rooms for 2 to 8 signed-in players. One player creates a room and shares an eight-character invite code or link. Everyone marks ready, the host starts the room, and each browser enters the same immutable published release.
The current runtime is intended for casual cooperative and racing games, not cheat-resistant competition. Each player simulates the vehicle assigned to their slot. The host relays vehicle state and shared race variables to the other browsers.
Current replication scope
Multiplayer currently replicates slotted wheeled and tracked vehicles plus selected primitive scene variables. It does not provide general character, rigid-body, runtime-created-object, or scene-transition replication. There is no multiplayer Lua global or runtime controller-transfer API yet.
Configure the project
Open the project's Multiplayer section and configure:
- Enable multiplayer: includes multiplayer in the next runtime bundle.
- Minimum players: the number required before the host can start, from 2 through 8.
- Maximum players: the room capacity, from the minimum through 8.
- Allow late joining: lets a new player enter an active room. It is off by default.
These settings are copied into an immutable release. Changing them after publishing does not change the live game or an existing room; republish to create a new release. Every room remains pinned to the release, protocol version, capacity, and late-join policy with which it was created.
Assign player vehicles
Add a numeric object variable named multiplayerPlayerSlot to each player-controlled vehicle. Use slot numbers beginning at 1. A project with a maximum of eight players normally provides one suitable vehicle for each slot from 1 through 8.
During multiplayer, a browser dynamically simulates its own slotted vehicle. The other slotted vehicles become kinematic remote bodies and interpolate their received chassis and wheel transforms. Leave shared track, scenery, and host-controlled gameplay objects unslotted.
Check slots yourself before publishing
Publication validates the multiplayer settings, but it does not yet reject a missing, duplicate, or out-of-range multiplayerPlayerSlot. Run every supported room size and confirm that each player controls exactly one intended vehicle.
Understand script authority
- Scene scripts run on the host.
- Unslotted non-GUI object scripts run on the host.
- A slotted object's script runs on the browser that owns that slot.
- GUI scripts run on every browser.
Only the owning slotted script receives that player's local input. Other slotted objects receive zeroed input on that browser. Keep authoritative race rules and shared gameplay in a scene script or an unslotted host object. Keep each vehicle's input and driving logic on that slotted vehicle. Keep player-facing presentation in GUI scripts.
Replicate scene variables
The host snapshot copies number, string, and boolean scene variables whose names begin with one of these patterns:
race_p<number>_, such asp3_lapplayer_<number>_, such asplayer_3_scoremultiplayer_shared_
Write these variables from a host-authoritative script with scene.setVar(name, value). GUI scripts can read them with scene.getVar(name). A value written only by a non-host slotted script remains local and is not promoted into the host snapshot.
Three read-only local facts are also exposed as scene variables: multiplayer_local_player_slot, multiplayer_local_is_host, and multiplayer_local_host_epoch.
gameStorage, Lua locals, timers, object references, nested tables, unreplicated physics, and runtime-created objects remain local to one browser. Do not use them for state that every player must see or that must survive host migration.
Publish and invite players
- Configure multiplayer and vehicle slots, then test each slot in Preview's lobby simulator.
- Publish or republish the project. A previously published release does not gain new multiplayer settings automatically.
- Open the public game and choose Multiplayer. Every participant needs an Airogel account.
- Create a player profile if prompted. Handles are unique, moderated, 3 to 20 ASCII letters, numbers, or underscores, and players must be at least 13.
- One player creates the room and shares its code or invite link. The others join, and everyone marks ready.
- The host starts when the minimum is present and every connected player is ready. Each browser follows the prompt to enter the game.
Waiting-room codes expire after 15 minutes. Active rooms end after four hours. Late joining, when enabled, admits a player directly to an active room without repeating the ready check.
Reconnect and host migration
A reconnecting player normally keeps the same room membership and stable slot. The client renews its short-lived connection credentials automatically and stores a rotating reconnect ticket in that browser session.
If the host disconnects unexpectedly, the room waits through a reconnect grace period before selecting another connected player. Clients pause during connection loss or an authority change. Host migration increments the host epoch and rotates the snapshot-signing key; peers resume after receiving verified state from the new host.
Migration is best effort. Shared primitive variables and the state already present in each browser can continue, but Lua locals, timers, gameStorage, runtime-created objects, and unreplicated physics are not restored from the old host.
Safety and privacy boundaries
Rooms are private and code-based. There is no public matchmaking, open text chat, voice chat, friend graph, direct messaging, or location sharing. Players can block and report other profiles. Teen profiles can be subject to guardian multiplayer, schedule, play-time, and approved-game controls.
A room code is an invitation, not a secret access-control system. Share it only with intended players. Blocking either direction prevents two profiles from joining the same room.
Runtime limits
- 2 to 8 participants per room.
- Client input and controlled state are sent at up to 20 updates per second.
- The host sends snapshots at up to 10 updates per second.
- Input packets are limited to 4 KiB and snapshots to 8 KiB.
- An input can carry at most 32 controlled objects, 16 named actions, and 16 wheels per object.
- A snapshot can carry at most 128 objects and 128 replicated-state keys.
Design for small snapshots rather than the hard maximum. Large, rapidly changing shared values waste bandwidth and can cause a connection or stream to be rejected.
Test the published release
Preview is useful for slot and script checks, but it does not exercise real rooms, authentication, WebSockets, reconnect, signing, or host migration. Test the published URL with separate signed-in browser profiles.
- Fill the room to every player count you intend to support, including the configured maximum.
- Confirm lobby membership, slot numbers, readiness, start, and late-join behavior.
- Drive every vehicle and confirm that only its owner controls it while every peer sees chassis and wheel movement.
- Confirm shared race variables and every player's HUD update.
- Reload one non-host browser and confirm it reconnects into the same slot.
- Have the host leave and confirm the remaining clients pause, migrate, and resume.
- Check desktop and mobile devices you intend to support and review browser-console errors.
See Publish and test a game for release readiness, republishing, public URLs, and analytics.