### Initialize Playroom Session (Vanilla) Source: https://docs.joinplayroom.com/api-reference/js/insertCoin This basic example shows how to use insertCoin() to display the Playroom UI and wait for the host to launch the game. After the host launches, the promise resolves, and you can start your game. ```javascript await insertCoin(); // Start your game! ``` -------------------------------- ### InsertCoin(InitOptions, callback) Source: https://docs.joinplayroom.com/llms-full.txt Initializes Playroom Kit, manages room setup, player joining, and waits for the host to launch the game. The callback is executed once the game is ready to start. ```APIDOC ## `InsertCoin(InitOptions, callback)` ### Description Initializes Playroom Kit, allowing it to manage room creation, player joining, and player customization (names, colors, avatars). The method resolves when the host initiates the game launch, signaling that the game is ready to begin. ### Method Signature `InsertCoin(InitOptions options, Action callback)` ### Parameters #### `options` (InitOptions) An object containing configuration options for Playroom Kit initialization. | Option Property | Type | Default | Description | |---|---|---|---| | `gameId` | string | undefined | The unique identifier for the game obtained from the Playroom Kit developer portal. | | `streamMode` | boolean | `false` | If `true`, enables stream mode for Playroom Kit. See [stream mode documentation](/multiplayer/stream) for details. | | `allowGamepads` | boolean | `false` | If `true` and `streamMode` is also `true`, allows players to use gamepads connected to the stream device as controllers. Phone controllers are also optionally supported. | | `baseUrl` | string | *Current Page URL* | The base URL used to generate the room link that the host shares with other players. | | `skipLobby` | boolean | `false` | If `true`, bypasses the default Playroom Kit lobby screen, allowing for custom lobby implementations. | | `roomCode` | string | undefined | Allows overriding the room to join. If not provided, a random room code is assigned. If the URL contains a `#r=` parameter, that value takes precedence. | | `reconnectGracePeriod` | int | `0` | The duration in milliseconds Playroom Kit will wait for a player to reconnect after a disconnection. If the player reconnects within this period, their state is restored. Otherwise, they are removed from the room. | | `maxPlayersPerRoom` | int | undefined | Sets a maximum limit on the number of players allowed in a room. If the room is full, a default modal is shown, and `insertCoin` will throw a `ROOM_LIMIT_EXCEEDED` error. If `skipLobby` is `true`, the modal is skipped, but the error is still thrown. | | `avatars` | Array<string> | *Default Avatars* | An array of image URLs to be used as player avatars, overriding the default Playroom Kit avatars. | | `defaultStates` | Dictionary<string, object> | *null* | A dictionary defining default states for the room when it is created. | | `defaultPlayerStates` | Dictionary<string, object> | *null* | A dictionary defining default states for all players upon joining the room. | | `matchmaking` | [`MatchmakingOptions`](#matchmakingoptions) or `boolean` | `false` | Configuration for matchmaking, either as an object or `true` to enable with default settings. | | `discord` | boolean | `false` | If `true`, enables Discord mode. Refer to [Discord Mode documentation](/components/games/discord) for more information. | #### `callback` (Action) A callback function that is executed once the Playroom Kit has been successfully initialized and the game is ready to start. ``` -------------------------------- ### Initialize and Start Game Source: https://docs.joinplayroom.com/examples/multiplayer-card-game Sets up the game by distributing cards, initializing player states, and starting the game timer. This function is called on component mount and when a new player joins. ```javascript const startGame = () => { if (isHost()) { console.log("Start game"); setTimer(TIME_PHASE_CARDS, true); const randomPlayer = randInt(0, players.length - 1); setPlayerStart(randomPlayer, true); setPlayerTurn(randomPlayer, true); setRound(1, true); setDeck( [ ...new Array(16).fill(0).map(() => "punch"), ...new Array(24).fill(0).map(() => "grab"), ...new Array(8).fill(0).map(() => "shield"), ], true ); setGems(NB_GEMS, true); players.forEach((player) => { console.log("Setting up player", player.id); player.setState("cards", [], true); player.setState("gems", 0, true); player.setState("shield", false, true); player.setState("winner", false, true); }); distributeCards(CARDS_PER_PLAYER); setPhase("cards", true); } }; useEffect(() => { startGame(); onPlayerJoin(startGame); }, []); ``` -------------------------------- ### Install Playroom Kit with yarn Source: https://docs.joinplayroom.com/frameworks/web/angular Install Playroom Kit using yarn. This command integrates the real-time collaboration SDK into your project. ```bash yarn add playroomkit ``` -------------------------------- ### Install Playroom Kit with bun Source: https://docs.joinplayroom.com/frameworks/web/angular Install Playroom Kit using bun. This command is used to add the real-time collaboration package. ```bash bun add playroomkit ``` -------------------------------- ### Install Electron Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Install Electron as a development dependency for your project. This is the first step in packaging your web game as a desktop application. ```bash npm install --save-dev electron ``` -------------------------------- ### Cards Demo Example Source: https://docs.joinplayroom.com/components/tiktok An example demonstrating the setup for a collaborative cards game that can be integrated with TikTok Live. This includes initialization and event handling. ```javascript import "./styles.css"; import { Playroom } from "playroomkit"; const room = new Playroom(document.getElementById('room'), { // ... other options liveMode: true, }); room.onTikTokLiveEvent((event) => { console.log('Received TikTok Live event:', event); }); // Example: Add a button to deal cards const dealButton = document.createElement('button'); dealButton.textContent = 'Deal Cards'; dealButton.onclick = () => { // Logic to deal cards, potentially triggered by a live event or user action console.log('Dealing cards...'); }; document.body.appendChild(dealButton); ``` -------------------------------- ### 3D Avatars - Ready Player Me Example Source: https://docs.joinplayroom.com/templates An example demonstrating the use of Ready Player Me avatars with Playroom Kit, largely based on Wawa Sensei's tutorial. ```markdown ## 3D Avatars - Ready Player Me **Code** | **Demo** This is an example of how to use the readyplayer.me Avatars with Playroom. This code is almost fully based on Wawa Sensei’s Tutorial. ``` -------------------------------- ### Install Playroom Kit with Bun Source: https://docs.joinplayroom.com/setup Install Playroom Kit and its peer dependencies (React, ReactDOM) using Bun. This is a fast, all-in-one JavaScript runtime. ```bash bun add playroomkit react react-dom ``` -------------------------------- ### Install Unity SDK Dependencies Source: https://docs.joinplayroom.com/frameworks/games/unity Navigate to the Playroom Kit directory in your Unity project and run 'npm install' to install necessary dependencies. ```bash cd Assets/Playroom Kit npm install ``` -------------------------------- ### Start Matchmaking Source: https://docs.joinplayroom.com/api-reference/unity Initiates the matchmaking process. ```csharp StartMatchmaking() ``` -------------------------------- ### Install Electron Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Install Electron and its development dependencies using npm. ```bash npm init -y npm install --save-dev electron ``` -------------------------------- ### Example Prompt for AI Source: https://docs.joinplayroom.com/concepts/ai-features An example prompt demonstrating how to instruct an AI to add live cursors to a React canvas using Playroom Kit, following official guides and without modifying the existing backend. ```plaintext Use Playroom Kit to add live cursors to my existing React canvas. Follow the official step-by-step guide below. Do not modify my backend. Only add presence and cursor logic. ``` -------------------------------- ### Install Electron Builder Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Install electron-builder for creating production-ready builds of your Electron application. ```bash npm install --save-dev electron-builder ``` -------------------------------- ### React App Initialization Source: https://docs.joinplayroom.com/examples/live-canvas Basic React project setup using create-react-app and ReactDOM. ```tsx import { createRoot } from "react-dom/client"; import App from "./App.tsx"; import "./index.css"; createRoot(document.getElementById("root")!).render(); ``` -------------------------------- ### Run Electron App Locally Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Start your packaged Electron application using the npm start script. ```bash npm start ``` -------------------------------- ### Install Playroom Kit with pnpm Source: https://docs.joinplayroom.com/frameworks/web/angular Install Playroom Kit using pnpm. This command adds the necessary package for real-time features. ```bash pnpm add playroomkit ``` -------------------------------- ### Initialize Playroom Kit and Game Loop Source: https://docs.joinplayroom.com/llms-full.txt Initializes Playroom Kit, sets up player joining and leaving events, and starts the game loop for synchronizing game states. This function should be called on game start. ```javascript async function init(event){ // Init Playroom Kit, let players create their profiles. await insertCoin(); // Create the touch joystick. createJoystick(); // Create the scene, lights, sea, sky, etc. createScene(); createLights(); createSea(); createSky(); // Create the plane(s) when the player joins. onPlayerJoin((state) => { const plane = createPlane(state.getProfile().color.hex); players.push({ state, plane }); // Remove the plane when the player leaves. state.onQuit(() => { scene.remove(plane.mesh); players = players.filter((p) => p.state != state); }); }); // Start the game loop. loop(); } ``` -------------------------------- ### PartyKit Broadcast Example Source: https://docs.joinplayroom.com/migration-guides/partykit Example of broadcasting a message in a PartyKit setup. This involves manually sending data to all connected clients. ```javascript room.broadcast({ type: "move", x, y }) ``` -------------------------------- ### Initialize Playroom Kit (Below v1.0.0) Source: https://docs.joinplayroom.com/frameworks/games/unity Initialize Playroom Kit using the static InsertCoin method in your game's Start method. Configure max players and default player states. ```csharp using Playroom; void Start() { Playroom Kit.InsertCoin(new Playroom Kit.InitOptions() { maxPlayersPerRoom = 2, defaultPlayerStates = new() { {"score", -500}, }, }, () => { // Game launch logic here }); } ``` -------------------------------- ### Example Prompt for AI Source: https://docs.joinplayroom.com/llms-full.txt An example prompt demonstrating how to instruct an AI to add live cursors to a React canvas using Playroom Kit, following official guides and respecting existing backend configurations. ```plaintext Use Playroom Kit to add live cursors to my existing React canvas. Follow the official step-by-step guide below. Do not modify my backend. Only add presence and cursor logic. ``` -------------------------------- ### Initialize Playroom Kit and Wait for Launch Source: https://docs.joinplayroom.com/api-reference/unity Use this snippet to show the Playroom Kit UI, manage player joining, and wait for the host to tap 'Launch'. The callback fires when the game is ready to start. ```csharp Playroom Kit.InsertCoin(new Playroom Kit.InitOptions() { maxPlayersPerRoom = 2, defaultPlayerStates = new() { {"score", -500}, }, }, () => { Debug.Log("Insert Coin Callback Fired! Time to play."); }); // Start your game! ``` -------------------------------- ### Electron Main Process Setup Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Create the main Electron process file to load your web game. Replace the placeholder URL with your deployed game's domain. ```javascript const { app, BrowserWindow } = require('electron') function createWindow() { const win = new BrowserWindow({ width: 1280, height: 720, autoHideMenuBar: true, webPreferences: { contextIsolation: true } }) win.loadURL('https://your-game-domain.com') } app.whenReady().then(createWindow) ``` -------------------------------- ### Get State in Godot Source: https://docs.joinplayroom.com/frameworks/games/godot Example of retrieving game state using Playroom Kit in Godot. This is analogous to using `getState` in web applications. ```GDScript var points = Playroom.getState("points") ``` -------------------------------- ### Join a Room on App Start Source: https://docs.joinplayroom.com/llms-full.txt Use `insertCoin()` to join or create a session when your app initializes. This snippet assumes Playroom Kit is installed and configured. ```tsx "use client"; useEffect(() => { insertCoin(); }); const players = usePlayersList(true); const me = myPlayer(); return ( Move your cursor to broadcast its position ); } ``` -------------------------------- ### Initialize Playroom Kit (v1.0.0+) Source: https://docs.joinplayroom.com/frameworks/games/unity Initialize Playroom Kit in your game's Start method using the Singleton pattern. Configure max players and default player states. ```csharp using Playroom; // ... private Playroom Kit _playroomKit = new Playroom Kit(); // ... void Start() { _playroomKit.InsertCoin(new InitOptions() { maxPlayersPerRoom = 2, defaultPlayerStates = new() { {"score", 0}, }, }, () => { // Game launch logic here }); } ``` -------------------------------- ### Basic PWA Setup Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Implement a basic Progressive Web App (PWA) by creating a manifest file and a service worker. This enables offline functionality and installability for your web game. ```javascript // service-worker.js const CACHE_NAME = 'my-game-cache-v1'; const urlsToCache = [ '/', '/index.html', '/styles.css', '/script.js', // Add other assets like images, game files, etc. ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME) .then((cache) => { console.log('Opened cache'); return cache.addAll(urlsToCache); }) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) .then((response) => { if (response) { return response; } return fetch(event.request); }) ); }); ``` ```json { "name": "My Game", "short_name": "Game", "start_url": "/", "display": "standalone", "background_color": "#000000", "theme_color": "#000000", "icons": [ { "src": "icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "icon-512x512.png", "sizes": "512x512", "type": "image/png" } ] } ``` -------------------------------- ### Axie Starter Project with Playroom Source: https://docs.joinplayroom.com/blog/axiegamejam23 This snippet demonstrates how to set up a starter project for building Axie games using Playroom Multiplayer Kit with React/NextJS. It is useful for game developers looking to integrate multiplayer features into Axie-themed games. ```javascript https://codesandbox.io/p/sandbox/axie-starter-playroom-4fkdxd ``` -------------------------------- ### Set Up Main App Component with Providers Source: https://docs.joinplayroom.com/examples/fall-guys-clone Sets up the main App component with React Three Fiber Canvas, physics, keyboard controls, and context providers for game state and audio. Defines keyboard controls for player movement. ```javascript import { Canvas } from "@react-three/fiber"; import { Physics } from "@react-three/rapier"; import { Experience } from "./components/Experience"; import { KeyboardControls } from "@react-three/drei"; import { useMemo } from "react"; import { UI } from "./components/UI"; import { AudioManagerProvider } from "./hooks/useAudioManager"; import { GameStateProvider } from "./hooks/useGameState"; export const Controls = { forward: "forward", back: "back", left: "left", right: "right", jump: "jump", }; function App() { const map = useMemo( () => [ { name: Controls.forward, keys: ["ArrowUp", "KeyW"] }, { name: Controls.back, keys: ["ArrowDown", "KeyS"] }, { name: Controls.left, keys: ["ArrowLeft", "KeyA"] }, { name: Controls.right, keys: ["ArrowRight", "KeyD"] }, { name: Controls.jump, keys: ["Space"] }, ], [] ); return ( ); } export default App; ``` -------------------------------- ### Initialize Playroom Kit Source: https://docs.joinplayroom.com/api-reference/unity Initializes the Playroom Kit with specified options and a callback function. ```csharp InsertCoin(InitOptions, callback) ``` -------------------------------- ### Install Game Dependencies Source: https://docs.joinplayroom.com/examples/multiplayer-shooter-game Installs necessary npm packages for networking, 3D physics, and visual effects, along with Tailwind CSS. ```bash npm install playroomkit @react-three/rapier @react-three/postprocessing three-stdlib npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p ``` -------------------------------- ### Example Architecture Flow Source: https://docs.joinplayroom.com/concepts/adding-playroomkit-to-your-existing-stack Illustrates a typical client-server architecture where Playroom Kit handles real-time collaboration alongside existing services like Supabase or Firebase for authentication and database operations. ```text Client App (React) │ ├── Supabase / Firebase → Auth + Database │ └── Playroom Kit → Presence + Cursors + Realtime UI ``` -------------------------------- ### Initialize Playroom Kit and Set Up Three.js Scene Source: https://docs.joinplayroom.com/examples/cars-on-the-roof-game Sets up the basic Three.js scene with lighting, a WebGL renderer, physics world, and camera using insertCoin. This code forms the foundation for the 3D isometric car game. ```javascript import { onPlayerJoin, insertCoin, isHost, myPlayer, setState, getState, Joystick } from "playroomkit"; import * as THREE from 'three'; import * as CANNON from 'cannon'; import Time from "./utils/Time" import Car from "./car"; import shape2mesh from "./utils/shape2mesh"; import createWorld from "./world"; import loadCar from './carmodel'; import mobileRevTriangle from './images/trianglerev.png' function setupGame() { // Init world const scene = new THREE.Scene() const hemisphereLight = new THREE.HemisphereLight(0xaaaaff, 0xffaa00, .4); const ambientLight = new THREE.AmbientLight(0xdc8874, .4); const shadowLight = new THREE.DirectionalLight(0xffffff, .9); shadowLight.position.set(150, 350, 350); shadowLight.castShadow = true; shadowLight.shadow.camera.left = -400; shadowLight.shadow.camera.right = 400; shadowLight.shadow.camera.top = 400; shadowLight.shadow.camera.bottom = -400; shadowLight.shadow.camera.near = 1; shadowLight.shadow.camera.far = 1000; shadowLight.shadow.mapSize.width = 2048; shadowLight.shadow.mapSize.height = 2048; scene.add(hemisphereLight); scene.add(shadowLight); scene.add(ambientLight); scene.fog = new THREE.Fog(0xf7d9aa, 100, 950); const light = new THREE.DirectionalLight(0xffffff, 0.5); light.position.set(100, 100, 50); light.castShadow = true; const dLight = 200; const sLight = dLight * 0.25; light.shadow.camera.left = - sLight; light.shadow.camera.right = sLight; light.shadow.camera.top = sLight; light.shadow.camera.bottom = - sLight; light.shadow.camera.near = dLight / 30; light.shadow.camera.far = dLight; light.shadow.mapSize.x = 1024 * 2; light.shadow.mapSize.y = 1024 * 2; scene.add(light); // Renderer const renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; renderer.setClearColor(0xb4e0f1, 1) renderer.setPixelRatio(2) renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement); // Camera const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 80); const cameraCoords = new THREE.Vector3(19.36, 9.36, 11.61); camera.position.copy(cameraCoords); camera.lookAt(new THREE.Vector3(0, 0, 0)); camera.rotation.x = -0.7; camera.rotation.y = 1; camera.rotation.z = 2.37; window.camera = camera; // Physics let time = new Time(); const PhysicsWorld = new CANNON.World({ gravity: new CANNON.Vec3(0, -9.83, 0) }); // Floor and walls createWorld(scene, PhysicsWorld); } insertCoin().then(() => { setupGame(); }) ``` -------------------------------- ### Install Playroom Kit with npm Source: https://docs.joinplayroom.com/frameworks/web/angular Install Playroom Kit using npm. This is the first step to add real-time collaboration to your Angular project. ```bash npm install playroomkit ``` -------------------------------- ### Initialize Playroom Kit with Discord Integration Source: https://docs.joinplayroom.com/llms-full.txt Call `insertCoin` with `gameId` and `discord: true` to enable Discord integration and prompt users for permissions. This is the initial setup step for using Discord features within your game. ```javascript await insertCoin({ gameId: "", discord: true }); ``` -------------------------------- ### Install Playroom Kit with npm Source: https://docs.joinplayroom.com/setup Install Playroom Kit and its peer dependencies (React, ReactDOM) using npm. This is the standard method for Node.js projects. ```bash npm i playroomkit react react-dom ``` -------------------------------- ### Set Up Main App with Canvas and Providers Source: https://docs.joinplayroom.com/llms-full.txt Sets up the main App component with React Three Fiber Canvas, physics, keyboard controls, and context providers for game state and audio. Defines control mappings for player movement. ```jsx forward: "forward", back: "back", left: "left", right: "right", jump: "jump", }; function App() { const map = useMemo( () => [ { name: Controls.forward, keys: ["ArrowUp", "KeyW"] }, { name: Controls.back, keys: ["ArrowDown", "KeyS"] }, { name: Controls.left, keys: ["ArrowLeft", "KeyA"] }, { name: Controls.right, keys: ["ArrowRight", "KeyD"] }, { name: Controls.jump, keys: ["Space"] }, ], [] ); return ( ); } ``` -------------------------------- ### Set Up React Project with Vite Source: https://docs.joinplayroom.com/llms-full.txt Initializes the React application using ReactDOM. This snippet is part of the project setup and requires React and ReactDOM. ```jsx import "./index.css"; ReactDOM.createRoot(document.getElementById("root")).render( ); ``` -------------------------------- ### Install Playroom Kit with pnpm Source: https://docs.joinplayroom.com/setup Install Playroom Kit and its peer dependencies (React, ReactDOM) using pnpm. This is an alternative package manager for Node.js projects. ```bash pnpm add playroomkit react react-dom ``` -------------------------------- ### Install Nativefier Source: https://docs.joinplayroom.com/examples/turn-web-game-into-executable Install Nativefier globally using npm. This tool converts web pages into desktop applications. Note: This method is not recommended for production use. ```bash npm install -g nativefier ``` -------------------------------- ### Initialize Playroom Kit and Manage Player Joins Source: https://docs.joinplayroom.com/examples/multiplayer-shooter-game Initializes Playroom Kit using insertCoin and sets up an onPlayerJoin callback to manage new players, their joysticks, and initial states. It also handles player disconnections. ```jsx import { Joystick, insertCoin, isHost, myPlayer, onPlayerJoin, useMultiplayerState, } from "playroomkit"; import { useEffect, useState } from "react"; import { Bullet } from "./Bullet"; import { BulletHit } from "./BulletHit"; import { CharacterController } from "./CharacterController"; import { Map } from "./Map"; export const Experience = ({ downgradedPerformance = false }) => { const [players, setPlayers] = useState([]); const start = async () => { await insertCoin(); onPlayerJoin((state) => { const joystick = new Joystick(state, { type: "angular", buttons: [{ id: "fire", label: "Fire" }], }); const newPlayer = { state, joystick }; state.setState("health", 100); state.setState("deaths", 0); state.setState("kills", 0); setPlayers((players) => [...players, newPlayer]); state.onQuit(() => { setPlayers((players) => players.filter((p) => p.state.id !== state.id)); }); }); }; useEffect(() => { start(); }, []); const [bullets, setBullets] = useState([]); const [hits, setHits] = useState([]); const [networkBullets, setNetworkBullets] = useMultiplayerState( "bullets", [] ); const [networkHits, setNetworkHits] = useMultiplayerState("hits", []); const onFire = (bullet) => { setBullets((bullets) => [...bullets, bullet]); }; const onHit = (bulletId, position) => { setBullets((bullets) => bullets.filter((bullet) => bullet.id !== bulletId)); setHits((hits) => [...hits, { id: bulletId, position }]); }; const onHitEnded = (hitId) => { setHits((hits) => hits.filter((h) => h.id !== hitId)); }; useEffect(() => { setNetworkBullets(bullets); }, [bullets]); useEffect(() => { setNetworkHits(hits); }, [hits]); const onKilled = (_victim, killer) => { const killerState = players.find((p) => p.state.id === killer).state; killerState.setState("kills", killerState.state.kills + 1); }; return ( <> {players.map(({ state, joystick }, index) => ( ))} {(isHost() ? bullets : networkBullets).map((bullet) => ( onHit(bullet.id, position)} /> ))} {(isHost() ? hits : networkHits).map((hit) => ( onHitEnded(hit.id)} /> ))} ); }; ``` -------------------------------- ### Create Main Game Scene Source: https://docs.joinplayroom.com/examples/2d-parkour-game Sets up the main game scene, including loading assets, configuring the tilemap, and initializing player controllers and game loop. ```javascript class PlayGame extends Phaser.Scene { constructor() { super("PlayGame"); } preload() { this.load.image("tile", "/tile.png"); this.load.image("hero", "/hero.png"); this.load.tilemapTiledJSON("level", "/level.json"); } create() { // setting background color this.cameras.main.setBackgroundColor(gameOptions.bgColor); // creatin of "level" tilemap this.map = this.make.tilemap({ key: "level", tileWidth: 64, tileHeight: 64 }); // adding tiles (actually one tile) to tilemap this.tileset = this.map.addTilesetImage("tileset01", "tile"); // which layer should we render? That's right, "layer01" this.layer = this.map.createLayer("layer01", this.tileset, 0, 0); this.layer.setCollisionBetween(0, 1, true); // loading level tilemap this.physics.world.setBounds(0, 0, this.map.widthInPixels, this.map.heightInPixels); // players and their controllers this.players = []; onPlayerJoin(async (player) => { const joystick = new Joystick(player, { type: "dpad", buttons: [ { id: "jump", label: "JUMP" } ] }); const hero = new Player( this, this.layer, this.cameras.main.width / 2 + (this.players.length * 20), 440, player.getProfile().color.hex, joystick); this.players.push({ player, hero, joystick }); player.onQuit(() => { this.players = this.players.filter(({ player: _player }) => _player !== player); hero.destroy(); }); }); } update() { this.players.forEach(({ player, hero }) => { if (isHost()) { hero.update(); player.setState('pos', hero.pos()); } else { const pos = player.getState('pos'); if (pos) { hero.setPos(pos.x, pos.y); } } }); } } var gameOptions = { // width of the game, in pixels gameWidth: 14 * 32, // height of the game, in pixels gameHeight: 23 * 32, // background color bgColor: 0xF7DEB5 } ``` -------------------------------- ### Game Component Setup with PlayroomKit Source: https://docs.joinplayroom.com/examples/multiplayer-game-lobby Sets up the game environment, handles player joining, and renders player cars. Requires PlayroomKit and React Three Drei/Rapier. ```jsx import { Environment, Gltf, Lightformer } from "@react-three/drei"; import { CuboidCollider, Physics, RigidBody } from "@react-three/rapier"; import { Joystick, onPlayerJoin } from "playroomkit"; import { useEffect, useState } from "react"; import { CarController } from "./CarController"; import { GameArea } from "./GameArea"; export const Game = () => { const [players, setPlayers] = useState([]); useEffect(() => { onPlayerJoin((state) => { const controls = new Joystick(state, { type: "angular", buttons: [{ id: "Respawn", label: "Spawn" }], }); const newPlayer = { state, controls }; setPlayers((players) => [...players, newPlayer]); state.onQuit(() => { setPlayers((players) => players.filter((p) => p.state.id !== state.id)); }); }); }, []); return ( {players.map(({ state, controls }) => ( ))} ); }; ``` -------------------------------- ### Playroom Kit setState Example Source: https://docs.joinplayroom.com/migration-guides/partykit Example of updating shared state in Playroom Kit. This automatically synchronizes the state across all participants without manual broadcasting. ```javascript setState("position", { x: 100, y: 200 }) ```