Dashboard Login

Game Server Admin Panel

Server Dashboard

Total Rooms
0
Online Players
0
Waiting
0
Playing
0

Active Rooms

CodeTypeStatusPlayersTimeMapCreatedAction

Players

NameUser IDItemStatus
Select a room

API Documentation

Base URL-
WebSocket-
Room Management 5 endpoints
POST /api/rooms/quickplay Find available room or create new one
Request Body
{
  "userId": "user-123",
  "name": "PlayerName",
  "skin": "character_1"
}
Response 200
{
  "roomId": "ABC123",
  "type": "public"
}
POST /api/rooms/public Create a public room
Request Body
{
  "timeLimit": 90,
  "maxPlayers": 4
}
Response 200
{
  "roomId": "XYZ789",
  "type": "public"
}
POST /api/rooms/private Create a private room
Request Body
{
  "timeLimit": 90,
  "maxPlayers": 4
}
Response 200
{
  "roomId": "ABC123",
  "type": "private"
}
GET /api/rooms/list List all public rooms
Response 200
{
  "count": 2,
  "rooms": [
    {
      "roomId": "ABC123",
      "map": "track_1",
      "playerCount": 3,
      "maxPlayers": 5,
      "status": "waiting",
      "suspended": false,
      "type": "public",
      "timeLimit": 90,
      "createdAt": 1706612345
    }
  ]
}
GET /api/rooms/{roomId} Get room details
Parameters
roomIdstringRoom code (e.g. ABC123)
Response 200
{
  "id": "ABC123",
  "type": "public",
  "status": "waiting",
  "map": "track_1",
  "maxPlayers": 5,
  "timeLimit": 90,
  "timeLeft": 90,
  "players": {},
  "boosters": {},
  "traps": {}
}
History & Stats 3 endpoints
GET /api/history/room/{roomId} Get game history for a room
Parameters
roomIdstringRoom code
Response 200
{
  "roomId": "ABC123",
  "map": "track_1",
  "type": "public",
  "duration": 85,
  "playerCount": 4,
  "winners": [
    {"userId": "u1", "name": "Player1", "position": 1, "time": 45}
  ]
}
GET /api/history/user/{userId} Get user's game history
Parameters
userIdstringUser ID
limitintMax results (default 10)
Response 200
{
  "history": [
    {"roomId": "ABC123", "map": "track_1", "duration": 85, "playerCount": 4}
  ]
}
GET /api/stats Get global game statistics
Response 200
{
  "total_games": 150,
  "avg_duration": 72.5,
  "by_time_limit": {"60": 30, "90": 80, "180": 40}
}
Response Examples Full Data Samples

Room Waiting (with Players)

Room yang sedang menunggu pemain join

{
  "id": "123456",
  "type": "public",
  "status": "waiting",
  "map": "track_1",
  "maxPlayers": 5,
  "timeLimit": 90,
  "isFull": false,
  "players": [
    {
      "id": "player-uuid-1",
      "userId": "user-123",
      "name": "SpeedRacer",
      "skin": "ninja_red",
      "isReady": false,
      "position": {"x": 0, "y": 0, "z": 0}
    },
    {
      "id": "player-uuid-2",
      "userId": "user-456",
      "name": "TurboKing",
      "skin": "robot_blue",
      "isReady": false,
      "position": {"x": 0, "y": 0, "z": 0}
    }
  ]
}

Room Full (Waiting All Ready)

Room penuh, menunggu semua player ready

{
  "id": "123456",
  "type": "public",
  "status": "full",
  "map": "track_1",
  "maxPlayers": 5,
  "timeLimit": 90,
  "isFull": true,
  "players": [
    {"id": "p1", "userId": "u1", "name": "Player1", "skin": "skin1", "isReady": true},
    {"id": "p2", "userId": "u2", "name": "Player2", "skin": "skin2", "isReady": true},
    {"id": "p3", "userId": "u3", "name": "Player3", "skin": "skin3", "isReady": false},
    {"id": "p4", "userId": "u4", "name": "Player4", "skin": "skin4", "isReady": true},
    {"id": "p5", "userId": "u5", "name": "Player5", "skin": "skin5", "isReady": false}
  ]
}

Room Playing (Active Game)

Room yang sedang bermain dengan item boxes, player holding items, dan traps

{
  "id": "XYZ789",
  "type": "public",
  "status": "playing",
  "map": "track_1",
  "maxPlayers": 5,
  "timeLimit": 90,
  "timeLeft": 45,
  "createdAt": "2026-01-30T15:30:00+07:00",
  "startedAt": "2026-01-30T15:31:00+07:00",
  "players": {
    "player-uuid-1": {
      "id": "player-uuid-1",
      "userId": "user-123",
      "name": "SpeedRacer",
      "skin": "ninja_red",
      "isReady": true,
      "isFinished": false,
      "finishTime": 0,
      "finishPosition": 0,
      "heldItem": {
        "type": "bomb",
        "obtainedAt": "2026-01-30T15:31:30+07:00"
      },
      "position": {"x": 125.5, "y": 2.0, "z": 340.8}
    },
    "player-uuid-2": {
      "id": "player-uuid-2",
      "userId": "user-456",
      "name": "TurboKing",
      "skin": "robot_blue",
      "isReady": true,
      "isFinished": true,
      "finishTime": 42,
      "finishPosition": 1,
      "heldItem": null,
      "position": {"x": 500.0, "y": 0, "z": 1000.0}
    },
    "player-uuid-3": {
      "id": "player-uuid-3",
      "userId": "user-789",
      "name": "NitroBlast",
      "skin": "alien_green",
      "isReady": true,
      "isFinished": false,
      "finishTime": 0,
      "finishPosition": 0,
      "heldItem": {
        "type": "shield",
        "obtainedAt": "2026-01-30T15:32:00+07:00"
      },
      "position": {"x": 89.2, "y": 1.5, "z": 280.3}
    }
  },
  "boosters": {
    "box-uuid-1": {
      "id": "box-uuid-1",
      "type": "speed_boost",
      "position": {"x": 50.0, "y": 0, "z": 100.0},
      "taken": true,
      "takenBy": "player-uuid-1"
    },
    "box-uuid-2": {
      "id": "box-uuid-2",
      "type": "lightning",
      "position": {"x": 150.0, "y": 0, "z": 300.0},
      "taken": false,
      "takenBy": ""
    },
    "box-uuid-3": {
      "id": "box-uuid-3",
      "type": "freeze",
      "position": {"x": 250.0, "y": 0, "z": 500.0},
      "taken": false,
      "takenBy": ""
    }
  },
  "traps": {
    "trap-uuid-1": {
      "id": "trap-uuid-1",
      "type": "bomb",
      "placedBy": "player-uuid-2",
      "position": {"x": 180.5, "y": 0, "z": 420.3},
      "radius": 8.0,
      "active": true,
      "createdAt": "2026-01-30T15:32:15+07:00"
    },
    "trap-uuid-2": {
      "id": "trap-uuid-2",
      "type": "freeze",
      "placedBy": "player-uuid-1",
      "position": {"x": 95.0, "y": 0, "z": 200.0},
      "radius": 5.0,
      "active": false,
      "triggeredBy": "player-uuid-3",
      "createdAt": "2026-01-30T15:31:45+07:00"
    }
  }
}

Room Ended (Game Finished)

Room yang sudah selesai dengan hasil akhir

{
  "id": "DEF456",
  "type": "public",
  "status": "ended",
  "map": "track_1",
  "maxPlayers": 5,
  "timeLimit": 90,
  "timeLeft": 0,
  "createdAt": "2026-01-30T15:00:00+07:00",
  "startedAt": "2026-01-30T15:01:00+07:00",
  "endedAt": "2026-01-30T15:02:30+07:00",
  "players": {
    "player-uuid-1": {
      "id": "player-uuid-1",
      "userId": "user-123",
      "name": "SpeedRacer",
      "isFinished": true,
      "finishTime": 45,
      "finishPosition": 1,
      "heldItem": null
    },
    "player-uuid-2": {
      "id": "player-uuid-2",
      "userId": "user-456",
      "name": "TurboKing",
      "isFinished": true,
      "finishTime": 52,
      "finishPosition": 2,
      "heldItem": null
    },
    "player-uuid-3": {
      "id": "player-uuid-3",
      "userId": "user-789",
      "name": "NitroBlast",
      "isFinished": true,
      "finishTime": 68,
      "finishPosition": 3,
      "heldItem": null
    }
  },
  "boosters": {},
  "traps": {}
}

Game Start Event

Event yang dikirim server saat semua player ready

{
  "type": "game_start",
  "payload": {
    "roomId": "123456",
    "status": "playing",
    "timeLimit": 90,
    "timeLeft": 90,
    "players": [
      {"id": "p1", "userId": "user-123", "name": "SpeedRacer", "skin": "ninja_red", "isReady": true},
      {"id": "p2", "userId": "user-456", "name": "TurboKing", "skin": "robot_blue", "isReady": true}
    ],
    "boosters": [
      {"id": "box-1", "type": "bomb", "position": {"x": 50, "y": 0, "z": 100}, "taken": false},
      {"id": "box-2", "type": "shield", "position": {"x": 150, "y": 0, "z": 300}, "taken": false}
    ],
    "traps": [],
    "finishedIds": []
  }
}

Countdown Event

Countdown 5,4,3,2,1 sebelum timer mulai

{"type":"countdown","payload":{"countdown":5}}
{"type":"countdown","payload":{"countdown":4}}
{"type":"countdown","payload":{"countdown":3}}
{"type":"countdown","payload":{"countdown":2}}
{"type":"countdown","payload":{"countdown":1}}
// After countdown done, timer_update starts
{"type":"timer_update","payload":{"timeLeft":90}}

Game End Event

Game selesai saat 1 player finish atau time up; posisi sisanya diisi by distance

{
  "type": "game_end",
  "payload": {
    "roomId": "ABC123",
    "finishedPlayers": ["player-uuid-1"],
    "winners": [
      {"userId": "user-123", "name": "SpeedRacer", "position": 1, "time": 45},
      {"userId": "user-456", "name": "TurboKing", "position": 2, "time": 180},
      {"userId": "user-789", "name": "NitroBlast", "position": 3, "time": 180}
    ]
  }
}
WebSocket Events Client & Server

Connect to: wss://gameapi.copod.my.id/ws/{roomId}

Game Flow

1. POST /api/rooms/quickplay (userId, name, skin) → get roomId
2. Connect WebSocket → send player_joined (userId; optional name/skin)
3. Server broadcasts room_update (status: waiting)
4. Public room full → status changes to "full"
5. Client moves to game layout
6. Each client sends set_ready (userId)
7. Public: full + all ready, Private: all joined ready (min 2) → game_start
8. Server sends countdown (5,4,3,2,1)
9. Countdown done → timer_update starts

Room Status

waiting Room menunggu player join full Room penuh, menunggu semua ready playing Game sedang berjalan ended Game selesai
Private room bisa start dari status waiting jika semua player yang sudah join ready (min 2).

Client → Server

player_joined
{"type":"player_joined","payload":{"userId":"user-123","name":"PlayerName","skin":"skin_1"}}
Untuk private join bisa kirim name/skin di sini
set_ready
{"type":"set_ready","payload":{"userId":"user-123"}}
position_update
{"type":"position_update","payload":{"userId":"x","x":943,"y":861,"animName":"Diam","isMirror":0,"isCrouch":0,"timestamp":1700000000000}}
falldown
{"type":"falldown","payload":{"userId":"user-123"}}
doublejump
{"type":"doublejump","payload":{"userId":"user-123"}}
item_taken
{"type":"item_taken","payload":{"userId":"x","itemType":"BOMB","itemId":1}}
item_used
{"type":"item_used","payload":{"userId":"x","itemType":"HURRICANE","itemId":1,"x":100,"y":200,"direction":"LEFT"}}
tornadoHit
{"type":"tornadoHit","payload":{"userId":"user-123"}}
player_finish
{"type":"player_finish","payload":{"userId":"user-123"}}
kick_player
{"type":"kick_player","payload":{"userId":"user-456","reason":"afk"}}
Direct custom event: langsung direlay ke semua player/spectator
custom_broadcast
{"type":"custom_broadcast","payload":{"eventType":"kick_player","payload":{"userId":"user-456","reason":"afk"},"excludeSelf":false,"mySelf":false}}
Wrapper custom relay, support excludeSelf & mySelf (self-only)
custom_broadcast (ping self-only)
{"type":"custom_broadcast","payload":{"eventType":"ping","payload":{"clientTimestamp":1700000000000},"mySelf":true}}
Response event: ping dengan serverTimestamp + latencyMs

Server → Client

room_updateBroadcast on join/leave/ready
game_startAuto-start (public: full+ready, private: joined+ready min 2)
countdown
{"type":"countdown","payload":{"timeLeft":5}}
timer_update
{"type":"timer_update","payload":{"timeLeft":85}}
game_suspended
{"type":"game_suspended","payload":{"roomId":"ABC123","timeLeft":80}}
game_resumed
{"type":"game_resumed","payload":{"roomId":"ABC123","timeLeft":80}}
onplayerChange
{"type":"onplayerChange","payload":{"players":[{"userId":"x","x":943,"y":861,"animName":"Diam","isMirror":0,"isCrouch":0,"timestamp":1700000000000}]}}
getFallDown
{"type":"getFallDown","payload":{"userId":"user-123"}}
getPlayerDoubleJump
{"type":"getPlayerDoubleJump","payload":{"userId":"user-123"}}
getItem
{"type":"getItem","payload":{"userId":"x","itemType":"BOMB","itemId":1}}
trap_placed
{"type":"trap_placed","payload":{"userId":"x","itemType":"BOMB","itemId":1,"x":100,"y":200,"direction":"LEFT"}}
trap_hit
{"type":"trap_hit","payload":{"userId":"x","itemType":"TRAP","itemId":1}}
getTornadoHit
{"type":"getTornadoHit","payload":{"userId":"user-123"}}
playerFinish
{"type":"playerFinish","payload":{"userId":"x","position":1,"time":45}}
game_endGame ended with winners list

Item Types

TRAPBOMBLIGHTINGHURRICANE
Response

            

Game History

Game List

Loading game history...
RoomMapDurationPlayersWinnersDate
Loading game history...

Map Pool

Add New Map

Room baru akan random map dari daftar ini.
Map NameCreatedAction
No maps found

Admin Management

UserUsernameCreatedLast LoginAction

Settings

Change Password