Commands & Events
Player Controls
All controls are registered dynamically — they only exist while the relevant game phase is active.
Lobby phase
| Action | Key | Condition |
|---|---|---|
| Open match menu / start player selection | E | Standing near the KTF NPC |
Player selection UI
| Key | Action |
|---|---|
→ Right Arrow | Highlight next player |
← Left Arrow | Highlight previous player |
↓ Down Arrow | Select / deselect highlighted player |
ENTER | Confirm selection and start countdown |
BACKSPACE | Cancel and close selection UI |
In-match
| Action | Key | Condition |
|---|---|---|
| Pick up / capture flag | E | Within 2.5 units of the flag and flag is available |
| Open stash menu | E | Standing on the stash marker |
Flag Capture Flow
- Player walks within 2.5 units of the flag — a "Pick flag" hint appears
- Player presses
E— a circular progress bar runs forMBT.CaptureTimeseconds - If the bar completes without interruption, the flag attaches to the player's back (bone 24816)
- The server locks the flag state so no other player can capture it simultaneously
- Score begins accumulating every second
- On death or when another player captures the dropped flag, the sequence restarts
Score System
Score = total seconds the flag was held during the matchThe leaderboard syncs every MBT.UpdateVip seconds (default 3). The player with the highest cumulative hold time at the end of the match wins.
Developer Reference
Client → Server events
| Event | Payload | Description |
|---|---|---|
mbt_ktf:startChecks | { players } | Sent after player selection is confirmed; initiates the match server-side. |
mbt_ktf:handleFlagState | { state } | Notifies server that the flag availability changed (locked/available). |
mbt_ktf:checkFlagState | — | Client requests the current flag lock state before attempting capture. |
mbt_ktf:capturingFlag | { playerId } | Marks the flag as being captured by playerId. |
mbt_ktf:capturedFlag | { playerId } | Flag successfully picked up; server updates the global state. |
mbt_ktf:calculateScore | { score, playerId } | Submits accumulated score for the player. |
mbt_ktf:flagDrop | { playerId } | Flag dropped (death, boundary kick, or game end). |
mbt_ktf:handleFlag | { netId } | Requests server to delete the flag entity. |
mbt_ktf:endGame | { playerId, name } | Signals game end; triggers reward distribution and cleanup. |
mbt_ktf:setupPickups | { pickups } | Tells server which pickups were created so they can be tracked. |
mbt_ktf:deleteEntity | { netId } | Requests server-side deletion of a networked entity. |
mbt_ktf:enemyAdded | { netId } | Registers a newly spawned enemy NPC on the server. |
mbt_ktf:winnerCameraEnd | — | Camera animation finished; server can proceed with post-match cleanup. |
Server → Client events
| Event | Target | Description |
|---|---|---|
mbt_ktf:startPreMatch | selected players | Opens the player selection UI on the host's screen. |
mbt_ktf:startGame | all participants | Teleports players to the arena and starts the match. |
mbt_ktf:triggerNotify | all | Shows an ox_lib notification. |
mbt_ktf:Notify | all | Shows a sliding in-NUI notification. |
mbt_ktf:updateHighScore | all | Pushes current leaderboard (top score + player name) to the NUI. |
mbt_ktf:updateSelfScore | specific player | Pushes that player's own current score to their NUI. |
mbt_ktf:registerFlag | all | Broadcasts the flag's network ID so clients can interact with it. |
mbt_ktf:tryCaptureFlag | all | Triggers the capture progress sequence on the nearby player. |
mbt_ktf:handleCaptureFlag | all | Confirms capture; attaches flag prop to the carrier. |
mbt_ktf:capturedFlag | all | Updates the NUI flag-holder display. |
mbt_ktf:flagDrop | all | Updates the NUI to clear the flag-holder display. |
mbt_ktf:sendOwnerPosition | all | Broadcasts the flag-holder's coordinates to update the map blip. |
mbt_ktf:handleEnemies | specific player | Sends enemy spawn data to a client to spawn the NPC. |
mbt_ktf:refreshPickups | all | Tells clients to respawn weapon pickups. |
mbt_ktf:handleWinner | all | Starts the winner camera and displays the winner name. |
mbt_ktf:endGame | all participants | Triggers match cleanup: inventory restore, bucket reset, teleport. |
Global State
| Key | Type | Description |
|---|---|---|
GlobalState.ctfGameEnded | boolean | Set to true when the match has ended. |
LocalPlayer.state.isInKtf | boolean | Set per-player; true while participating in a match. |
NUI Messages (Lua → HTML)
| Type | Payload | Description |
|---|---|---|
"ui" | { show: boolean } | Shows or hides the game HUD. |
"flag" | { id, name } | Updates the flag-holder display (name + blip). |
"show" | { text } | Displays a centered message. |
"deathTimer" | — | Starts the 7-second respawn countdown circle. |
"slidingNotify" | { main, sub, type } | Shows a sliding notification panel. |
"updateHighScore" | { score, name } | Updates the leaderboard's top score display. |
"updateSelfScore" | { score } | Updates the player's own score display. |
NUI Callbacks (HTML → Lua)
| Callback (POST) | Description |
|---|---|
https://mbt_ktf/endGame | Fired when the game-over animation finishes; passes { id, name } of the winner. |
Match Lifecycle (Server)
Player presses E near NPC
→ mbt_ktf:startChecks (client → server)
→ Server validates minimum players
→ All participants moved to routing bucket
→ Intro camera starts
→ Flag spawns, pickups spawn, NPCs spawn
→ Game timer starts (EventDuration minutes)
During match:
→ updateVipThread — score sync every UpdateVip seconds
→ sendFlagOwnerCoordsThread — blip sync every UpdateFlagOwnerPosition seconds
→ refreshPickups — weapon respawn every PickupsRefresh seconds
Timer expires:
→ checkWinner() → highest score wins
→ giveReward(winner)
→ handleWinner() → winner camera + notification
→ resetServerVars() → all state cleared
→ All players moved back to main bucket
→ Inventories restored