LegacyShell WikiLegacyShell Wiki
Back to LegacyShell
Home
Wiki
Plugins
Docs
Back to LegacyShell
Home
Wiki
Plugins
Docs
  • Documentation

    • Getting Started

      • What is LegacyShell?
      • Speed Setup
      • Requirements
      • Installation
      • First Run
      • Config Files
      • Making an Account
      • Troubleshooting (Getting Started)
    • Running a Server

      • Architecture Overview
      • The Database
      • Users and Ranks
      • Adding Game Servers
      • Client Mirrors
      • Perpetual
      • Backups
      • Rate Limiting
      • Moderation
      • Closed Mode
      • Deployment
      • Troubleshooting (Running a Server)
      • Hosting for Someone Else's Instance
    • Content Creation

      • Maps
      • Dealing with Babylon Models
      • Map Blocks
      • Items and Skins
      • Hats and Stamps
      • Sounds
      • Gamemodes
      • Seasonal Events
    • Plugin Development

      • Quickstart
      • I Want To...
      • Anatomy of a Plugin
      • Lifecycle
      • Dependencies
      • Events (Concept)
      • Event Reference

        • services: events
        • game: events — shared logic (src/shell/)
        • game: events — main-thread server process
        • game: events — per-connection client object
        • game: events — room lifecycle & tick loop
        • game: events — in-browser gameplay
        • client: events — client server & build pipeline
      • Commands
      • Client-Side Code
      • Static Assets
      • Content Packs
      • Networking
      • Workers and State
      • Prediction and Authority
      • Recipes

        • Recipe: Killstreaks
        • Recipe: New Pickup Item
        • Recipe: New Gamemode
        • Recipe: Custom Weapon
        • Recipe: UI Modification
        • Recipe: Discord Integration
        • Recipe: Replacing Core Behaviour
        • Recipe: Persistent Plugin Storage
        • Recipe: Rewarding Players with Currency
        • Recipe: Custom Per-Player Data
        • Recipe: Custom Theme
      • Publishing
      • Pitfalls
      • Modifiers
      • Sound and Apollo
    • Codebase Reference

      • Repo Layout
      • Shared Shell Layer
      • Server-Only Markers
      • The ss Object
      • Build Pipeline
      • Stamps and Babylons
      • Game Loop
      • Rooms and Workers
      • Wire Protocol
      • Generated

        • Wire Protocol Opcodes
        • Enums & Lookup Tables
        • Database Schema
        • Config Reference
        • Slash Command Reference
      • Services Internals
      • Catalog and Items
      • Permissions Internals
      • Physics and Collision
      • Known Quirks
      • Codebase Anecdotes
      • Development Timeline
    • Contributing

      • Documentation Style Guide
      • Generators
      • For AI Agents

game: events — room lifecycle & tick loop

Audience: Plugin authors and AI agents · Prereqs: Events (concept)

Every plugins.emit(...) call site found in the files below, extracted directly from source - not hand-maintained. Unprefixed at the call site; PluginManager.emit adds game: before checking for listeners, so e.g. the first row below actually fires as game:roomLoading.

EventLocationPayloadFires when
roomLoadingserver-game/src/rooms.js:27{}Module load, once, inside the room worker thread.
roomInitserver-game/src/rooms.js:35{this: this}A room is being constructed.
roomSetSSserver-game/src/rooms.js:39{ss}The room worker's local ss is being seeded with {maps, items, permissions, config} from the main thread.
roomInitGameOptionsserver-game/src/rooms.js:61{this: this}gameOptions is being initialized for the room.
roomBeforeMapBuildserver-game/src/rooms.js:94{this: this, info: info}Before the map is built — a listener can rewrite this.minMap to substitute a custom map.
roomInitEndserver-game/src/rooms.js:168{ this: this }Room construction finished; the room is ready to accept players.
roomWsMessageserver-game/src/rooms.js:185{this: this, client, type, content}A raw, not-yet-decoded websocket message arrived for a client in this room (relayed from the main thread) — a plugin can decode it itself with new Comm.In(data.content) to react to a custom opcode.
packRoundEndserver-game/src/rooms.js:255{this: this, output}Building the "round end" network packet — fires before the packet body is assembled.
packRoundEndEndserver-game/src/rooms.js:258{this: this, output}Building the "round end" network packet — fires after the packet body is assembled.
packRoundUpdateserver-game/src/rooms.js:262{this: this, output}Building the "round update" (timer) network packet — fires before the packet body is assembled.
packRoundUpdateEndserver-game/src/rooms.js:267{this: this, output}Building the "round update" (timer) network packet — fires after the packet body is assembled.
resetGamePlayerserver-game/src/rooms.js:284{this: this, player}A player's round-scoped state (score, etc.) is being reset.
roomDetailsUpdatedserver-game/src/rooms.js:294{this: this, details: this.details}Room metadata (name, options, etc.) is changing — fires before the change is applied.
roomDetailsUpdatedEndserver-game/src/rooms.js:322{this: this, details: this.details}Room metadata (name, options, etc.) has changed — fires after the change is applied.
packUpdateRoomParamsserver-game/src/rooms.js:332{this: this, output}Building the room-params sync packet sent to clients — fires before the packet body is assembled.
packUpdateRoomParamsEndserver-game/src/rooms.js:342{this: this, output}Building the room-params sync packet sent to clients — fires after the packet body is assembled.
roomUpdateserver-game/src/rooms.js:353{this: this, delta, currentTimeStamp}Top of the 60Hz simulation tick, before per-player updates run.
playerUpdateserver-game/src/rooms.js:362{this: this, player, delta, currentTimeStamp}Per-player, per-tick update within the main tick loop.
playerStateUpdateserver-game/src/rooms.js:368{this: this, player, delta, currentTimeStamp}Per-player state-buffer replay/prediction step within the main tick loop.
roomStateUpdateserver-game/src/rooms.js:378{this: this, delta, currentTimeStamp}End of the per-tick player loop.
roomSyncserver-game/src/rooms.js:385{this: this}The ~10Hz full-state sync is about to run (every FramesBetweenSyncs ticks).
dataSyncLoopserver-game/src/rooms.js:394{this: this, delta, output}The ~1000ms "data sync" loop (less time-critical per-client data) is running.
clientDataSyncserver-game/src/rooms.js:397{this: this, client, delta, output}Per-client step within the data-sync loop.
roomDataSyncserver-game/src/rooms.js:401{this: this, delta, output}End of the data-sync loop.
metaLoopserver-game/src/rooms.js:407{this: this, fromDisconnect}The ~2000ms "meta" loop (idle-kick, weather triggers, empty-room destroy) is running.
metaLoopClientsserver-game/src/rooms.js:413{this: this, client, fromDisconnect}Per-client step within the meta loop.
roomDestroyserver-game/src/rooms.js:437{this: this}The room is being torn down.
clientSyncserver-game/src/rooms.js:462{this: this, output}Building the full-state sync packet — fires once, before the per-client loop below.
clientSyncLoopserver-game/src/rooms.js:465{ this: this, client, output }Building the full-state sync packet — fires once per client; a plugin can set plugins.cancel here to replace the default position data with its own (e.g. occlusion-based visibility filtering).
clientSyncEndserver-game/src/rooms.js:471{this: this, output}Building the full-state sync packet — fires once at the end, after every client has been packed.
joinPlayerserver-game/src/rooms.js:477{this: this, info}A player is joining this room.
registerPlayerClientserver-game/src/rooms.js:492{this: this, client}The new ClientConstructor is registered into the room's player list.
disconnectClientserver-game/src/rooms.js:498{this: this, client}A player is leaving/disconnecting — the closest real equivalent to a "leave" hook (there is no separate leavePlayer event, despite the naming symmetry you might expect with joinPlayer).
getPlayerCountLoopserver-game/src/rooms.js:531{this: this, count, uuids, usernames, sessions, player, extraDetails}Computing the room's live player count/roster — fires once per player being counted.
getPlayerCountserver-game/src/rooms.js:535{this: this, count, uuids, usernames, sessions, extraDetails}Computing the room's live player count/roster — fires once with the final tally.
getOldestClientLoopserver-game/src/rooms.js:546{this: this, client, oldestClient, oldestTime}Finding the longest-connected client (used for game-owner fallback) — fires once per client being checked.
getOldestClientserver-game/src/rooms.js:553{this: this, oldestClient}Finding the longest-connected client (used for game-owner fallback) — fires once with the result.
packSetGameOwnerserver-game/src/rooms.js:558{this: this, output}Building the "game owner" packet — fires before the packet body is assembled.
packSetGameOwnerFoundserver-game/src/rooms.js:560{this: this, output}Building the "game owner" packet — fires once an owner has actually been found.
setGameOwnerserver-game/src/rooms.js:568{this: this}Game-owner assignment/reassignment is starting (private rooms only have an owner).
setGameOwnerPrivateserver-game/src/rooms.js:570{this: this}Game-owner assignment is proceeding, specifically for a private room.
setGameOwnerNewserver-game/src/rooms.js:576{this: this, newOwner}A new game owner has been chosen.
getRandomSpawnserver-game/src/rooms.js:594{this: this, player, list, pos}A random spawn point is being picked for a player.
getBestSpawnserver-game/src/rooms.js:607{this: this, player}The "furthest from enemies" best-spawn algorithm is starting for a player.
getBestSpawnLoopserver-game/src/rooms.js:617{this: this, player, spwn, spawnPos, smallestDistance}The "furthest from enemies" best-spawn algorithm — fires once per candidate spawn point being scored.
getBestSpawnEndserver-game/src/rooms.js:635{this: this, player, best, bestDistance}The "furthest from enemies" best-spawn algorithm — fires once with the chosen spawn point.
getValidItemSpawnsserver-game/src/rooms.js:651{this: this, data}Scanning the map for valid item-spawn cells — fires before the scan starts.
getValidItemSpawnsLoopserver-game/src/rooms.js:659{this: this, x, y, z}Scanning the map for valid item-spawn cells — fires once per cell being checked.
getValidItemSpawnsEndserver-game/src/rooms.js:670{this: this}Scanning the map for valid item-spawn cells — fires once the scan is complete.
notifyserver-game/src/rooms.js:678{this: this, client, text, timeoutTime}A toast/notification is being sent to one client, as part of a room-wide room.notify(text, timeoutTime) broadcast.
packChatserver-game/src/rooms.js:685{this: this, output, text, id, chatType}Building a chat-message packet — fires before the packet body is assembled (runs after censor.js filtering has already happened).
packChatEndserver-game/src/rooms.js:690{this: this, output, text, id, chatType}Building a chat-message packet — fires after the packet body is assembled.
packSpawnItemPacketserver-game/src/rooms.js:694{this: this, output, id, kind, x, y, z}Building an item-spawn packet — fires before the packet body is assembled.
packSpawnItemPacketEndserver-game/src/rooms.js:701{this: this, output, id, kind, x, y, z}Building an item-spawn packet — fires after the packet body is assembled.
packCollectItemPacketserver-game/src/rooms.js:705{this: this, output, playerId, kind, index, id}Building an item-collected packet — fires before the packet body is assembled.
packCollectItemPacketEndserver-game/src/rooms.js:711{this: this, output, playerId, kind, index, id}Building an item-collected packet — fires after the packet body is assembled.
packAllItemsserver-game/src/rooms.js:716{this: this, output, pools}Building the full item-state packet sent on join — fires before the per-pool loop below.
packAllItemsLoopserver-game/src/rooms.js:721{this: this, output, item, i}Building the full item-state packet sent on join — fires once per item being packed.
spawnItemsserver-game/src/rooms.js:731{this: this, pools, output}The periodic item-spawning algorithm is starting for this pass.
spawnItemsLoopserver-game/src/rooms.js:743{this: this, pool, i, maximum, output}The item-spawning algorithm — fires once per item pool being processed.
spawnItemsLoopSpawnserver-game/src/rooms.js:752{this: this, pool, i, maximum, output, x, y, z}The item-spawning algorithm — fires immediately before an individual item is actually spawned.
spawnItemsLoopSpawnEndserver-game/src/rooms.js:759{this: this, pool, i, maximum, output, x, y, z, item}The item-spawning algorithm — fires immediately after an individual item has been spawned.
spawnItemsEndserver-game/src/rooms.js:765{this: this, pools, output}The periodic item-spawning algorithm has finished this pass.
getItemSpawnFromQueueserver-game/src/rooms.js:773{this: this, pos}Pulling the next queued spawn position — fires before the position is resolved.
getItemSpawnFromQueueEndserver-game/src/rooms.js:777{this: this, pos}Pulling the next queued spawn position — fires with the resolved position.
getUnusedPlayerIdserver-game/src/rooms.js:783{this: this}Allocating a free numeric player-id slot — fires before the scan starts.
getUnusedPlayerIdLoopserver-game/src/rooms.js:793{this: this, i, client, player}Allocating a free numeric player-id slot — fires once per candidate id being checked.
getPreferredTeamserver-game/src/rooms.js:805{this: this}Team-balancing logic for a joining player — fires before team counts are tallied.
getPreferredTeamEndserver-game/src/rooms.js:813{this: this, team1Count, team2Count}Team-balancing logic for a joining player — fires with the chosen team.
getPlayerClientserver-game/src/rooms.js:822{this: this, client, player}Resolving a Player back to its owning ClientConstructor.
packAllPlayersserver-game/src/rooms.js:828{this: this, output}Building the full player-roster packet sent on join — fires before the per-client loop below.
packAllPlayersLoopserver-game/src/rooms.js:832{this: this, output, client}Building the full player-roster packet sent on join — fires once per player being packed.
sendToOneserver-game/src/rooms.js:841{this: this, output, fromId, toId, debug}Unicast send to one client — fires before the target is resolved.
sendToOneFoundserver-game/src/rooms.js:843{this: this, output, fromId, toId, debug}Unicast send to one client — fires once the target client has been found.
sendToOthersserver-game/src/rooms.js:854{this: this, output, fromId, debug}Broadcast to all clients but one — fires before the per-client loop below.
sendToOthersLoopserver-game/src/rooms.js:856{this: this, client, output, fromId, debug}Broadcast to all clients but one — fires once per client being considered.
sendToOthersLoopFoundserver-game/src/rooms.js:858{this: this, client, output, fromId, debug}Broadcast to all clients but one — fires once for each client that actually receives the packet.
sendToAllserver-game/src/rooms.js:865{this: this, output, fromId, debug}Broadcast to every client — fires before the per-client loop below; a plugin can set plugins.cancel here to replace default fan-out with custom per-client visibility filtering.
sendToAllLoopserver-game/src/rooms.js:867{this: this, client, output, fromId, debug}Broadcast to every client — fires once per client being considered.
sendToAllLoopFoundserver-game/src/rooms.js:869{this: this, client, output, fromId, debug}Broadcast to every client — fires once for each client that actually receives the packet.
roomLoadedserver-game/src/rooms.js:876{RoomConstructor}Module load, once — hands out the room class itself.
adminCommandserver-game/src/worker.js:51{ payload: message }Main thread relayed an admin action into THIS specific room worker (e.g. a kick - see roomManager.js's admin dispatch and legacyadmin's game/moderationWorker.js/game/roomBridge.js). Only meaningful once ss.room exists.

This page was drafted with AI assistance and reviewed for accuracy. If something looks wrong, please open a PR or flag it.

Edit this page on GitHub
Prev
game: events — per-connection client object
Next
game: events — in-browser gameplay