Panduan Pembuatan Pemain Bot
Pemain bot digunakan untuk mengisi ketika tidak ada cukup orang untuk memulai dunia multiplayer, atau ketika seorang pemain meninggalkan dunia selama permainan.
Bagaimana perilaku pemain bot perlu diimplementasikan untuk setiap konten.
Panduan ini menjelaskan metode umum untuk membuat pemain Bot.
📘 Panduan pembuatan Pemain Bot didasarkan pada panduan multiplayer. [Tutorial Bermain Ganda]
LANGKAH 1: Buat Pemain Bot
1-1. Tambahkan nilai boolean yang disebut IsBot ke skema multiplayer.

1-2. Definisikan fungsi di bawah ini untuk membuat pemain Bot dalam skrip server index.ts dan panggil di titik yang diinginkan.
// Metode `CreateBot()` digunakan untuk membuat pemain bot dengan `userId` yang diberikan.
CreateBot(userId: string) {
// Menghasilkan ID sesi untuk pemain bot menggunakan `userId` yang diberikan.
const sessionId = "Bot_" + userId;
// Periksa apakah pemain bot dengan ID sesi yang sama sudah ada. Jika ya, kembalikan tanpa membuat duplikat.
if (this.state.players.has(sessionId)) {
return;
}
// Buat objek `Player` baru untuk pemain bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Tambahkan pemain bot ke peta pemain di state menggunakan ID sesi sebagai kunci.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
}
👍 Tips
- UserId dari pengguna tertentu disimpan sebelumnya untuk karakter pemain Bot yang akan dibuat.
- Anda dapat memeriksa UserId dari pengguna tertentu dengan memeriksa userId dari klien yang terhubung ke OnJoin di server. Setelah menulis skrip di bawah ini dalam skrip server, sambungkan dari dunia yang relevan.
onJoin(client: SandboxPlayer) {
console.log(client.userId);
}
LANGKAH 2: Buat pemain Bot di klien
2-1. Jika Anda memiliki server yang membuat pemain Bot pada suatu titik, klien akan mengenalinya sebagai pemain baru di OnJoinPlayer().
- Buat Proyek > Buat > ZEPETO > TypeScript dan ganti namanya menjadi BotPlayerManager.
- Tambahkan logika di OnAddedPlayer() untuk membuat setiap pemain, dan tambahkan logika untuk membedakan pemain bot dan membuat karakter ZEPETO mereka.
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room } from 'ZEPETO.Multiplay';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
export default class BotPlayerManager extends ZepetoScriptBehaviour {
public zepetoWorldMultiplay: ZepetoWorldMultiplay;
// Variabel privat untuk menyimpan ruangan saat ini dan data pemain bot.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// Dengarkan acara `RoomJoined` dari komponen `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
}
// Dengarkan acara `OnAddedPlayer` dari `ZepetoPlayers.instance` untuk menangani pemain yang baru ditambahkan.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// Dapatkan data pemain saat ini dari status ruangan menggunakan `userId`.
const currentPlayer = this._room.State.players.get_Item(userId);
// Periksa apakah pemain adalah bot, dan jika ya, tetapkan mereka sebagai pemain bot.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
}
}
2-2. Tulis fungsi SetBotPlayer untuk menambahkan tag dan komponen sinkronisasi ke pemain bot dan buat skrip untuk mengendalikannya.
- Set _botMapData untuk menyimpan data pemain bot dalam format Peta untuk mengelola pemain bot.
// Metode `SetBotPlayer()` digunakan untuk mengatur pemain sebagai bot.
SetBotPlayer(userId: string) {
// Dapatkan karakter ZEPETO yang terkait dengan pemain bot menggunakan `userId` mereka.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// Atur nama karakter ke `userId` untuk identifikasi.
bot.gameObject.name = userId;
// Simpan data pemain bot dalam peta `_botMapData` menggunakan `userId` mereka sebagai kunci.
this._botMapData.set(userId, bot);
}
👍 Tips Anda dapat menambahkan skrip atau pengaturan tambahan ke SetBotPlayer() untuk mengendalikan perilaku pemain bot.
LANGKAH 3: Buat tombol pemain Bot di klien
Untuk dunia yang memerlukan sejumlah pemain tertentu untuk memulai, terkadang tidak ada cukup pemain dan Anda harus menunggu lama untuk dunia dimulai.
Dalam hal ini, Anda dapat memulai dunia dengan menambahkan pemain Bot.
3-1. Daftarkan fungsi untuk mengeksekusi CreateBot() ketika server menerima pesan dari klien di index.ts.
async OnCreate() {
// Tangani pesan "CreateBot", yang membuat pemain bot dengan userId yang diberikan.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
}
3-2. Dalam skrip klien BotPlayerManager.ts, tulis fungsi untuk mengirim pesan "CreateBot" ke server.
- Cara untuk mengeksekusi fungsi adalah dengan mengirim pesan dengan menekan tombol.
- Kirim ID pengguna dari pemain Bot yang akan dibuat sebagai string melalui pesan.
public buttonCreateBot: Button;
public botPlayerId: string;
Start() {
// Tambahkan pendengar klik ke tombol "Buat Bot" untuk mengirim pesan untuk membuat pemain bot.
this.buttonCreateBot.onClick.AddListener(() => {
this._room.Send("CreateBot", this.botPlayerId);
});
}
3-3. Sekarang, ketika Anda menjalankan server dan runtime, Anda dapat melihat bahwa pemain bot dibuat ketika Anda menekan tombol.

LANGKAH 4: Mulai dunia dengan menambahkan pemain bot
Ketika tidak ada cukup pemain untuk memulai dunia, Anda dapat menambahkan pemain bot untuk memulai dunia.
4-1. Dalam skrip server, tambahkan kode berikut selama OnJoin untuk memeriksa jumlah pemain dan memulai dunia ketika ada setidaknya empat pemain.
- Tambahkan fungsi untuk memeriksa jumlah pemain di CreateBot().
- Tambahkan penghitung untuk jumlah permainan di fungsi StartWorld().
async onJoin(client: SandboxPlayer) {
// Periksa jumlah pemain di ruangan setelah seorang pemain bergabung.
this.CheckPlayerNumber();
}
// Metode `CheckPlayerNumber()` memeriksa jumlah pemain di ruangan dan memulai dunia jika ada setidaknya empat pemain.
CheckPlayerNumber() {
// Cetak jumlah pemain saat ini di ruangan ke konsol.
console.log(`jumlah pemain, ${this.state.players.size}`);
// Jika ada setidaknya empat pemain di ruangan, mulai dunia.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// Metode `CreateBot()` digunakan untuk membuat pemain bot dengan `userId` yang diberikan.
CreateBot(userId: string) {
// Hasilkan ID sesi untuk pemain bot menggunakan `userId` yang diberikan.
const sessionId = "Bot_" + userId;
// Periksa apakah pemain bot dengan ID sesi yang sama sudah ada. Jika ya, kembali tanpa membuat duplikat.
if (this.state.players.has(sessionId)) {
return;
}
// Buat objek `Player` baru untuk pemain bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Tambahkan pemain bot ke peta pemain negara menggunakan ID sesi sebagai kunci.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// Periksa jumlah pemain di ruangan setelah menambahkan pemain bot.
this.CheckPlayerNumber();
}
private playTime: number = 0;
// Metode `StartWorld()` meningkatkan waktu bermain dan menyiarkan pesan "StartWorld" ke semua klien.
StartWorld() {
this.playTime += 1;
// Cetak pesan yang menunjukkan dimulainya dunia dan waktu bermain saat ini.
console.log("Mulai Dunia!");
this.broadcast("StartWorld", this.playTime);
}
- Di server, OnJoin dieksekusi ketika pemain nyata bergabung ke ruangan. Jadi, ketika pemain Bot dibuat melalui CreateBot dan ketika seorang pemain masuk melalui OnJoin, checkPlayerNumber() menambahkan jumlah orang.
4-2. Dalam skrip klien, BotPlayerManager.ts, tulis StartWorld(), yang dieksekusi ketika pesan StartWorld diterima dari server.
Start() {
// Dengarkan untuk event `RoomJoined` dari komponen `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
// Tambahkan handler pesan untuk tipe pesan "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// Metode `StartWorld()` dipanggil ketika dunia dimulai dengan `playTime` yang diberikan.
StartWorld(playTime: number) {
// Cetak pesan mulai dunia bersama dengan `playTime`.
console.log(`Mulai Dunia : ${playTime}`);
}
4-3. Saat runtime, ketika ada lebih dari 4 pemain, termasuk pemain Bot, Anda dapat melihat log yang disebut World Start muncul di konsol server dan di konsol klien.

LANGKAH 5: Sinkronkan Posisi Pemain Bot
Di bawah ini adalah contoh kode yang memindahkan pemain Bot yang ditambahkan ke posisi pemain lokal dan menyinkronkan posisi gerakan.
5-1. Pertama, tulis kode untuk memindahkan pemain Bot ketika pesan MoveBot diterima dari klien di index.ts dari server.
async OnCreate() {
// Tangani pesan "MoveBot", yang memindahkan pemain bot ke posisi yang ditentukan.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// Metode `MoveBot()` memindahkan pemain bot ke posisi yang ditentukan berdasarkan pesan yang diterima.
MoveBot(client: SandboxPlayer, message: string) {
// Parse pesan JSON yang diterima dari klien untuk mengekstrak informasi posisi.
const position = JSON.parse(message);
// Buat objek pesan baru dengan ID sesi pengguna dan data posisi yang diparse.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// Siarkan pesan "MoveBotToPosition" ke semua klien dengan data pesan baru sebagai string JSON.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
5-2. Dalam skrip klien, BotPlayerManager.ts, tulis SendBotPosition() yang mengirim posisi pemain lokal ke server ketika buttonCallBot ditekan.
- Kemudian tulis kode untuk memindahkan semua pemain Bot ke lokasi informasi yang disertakan dalam pesan ketika pesan MoveBotToPosition diterima dari server.
public buttonCallBot: Button;
Start(){
// Dengarkan untuk acara `RoomJoined` dari komponen `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// Tambahkan pengendali pesan untuk jenis pesan "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
// Tambahkan pendengar klik ke tombol "Call Bot" untuk mengirim pesan untuk mengirim posisi pemain bot.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// Metode ini mengirim posisi karakter pemain lokal ke server untuk sinkronisasi gerakan bot.
SendBotPosition() {
// Dapatkan posisi karakter pemain lokal.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// Buat objek posisi yang berisi koordinat x, y, dan z dari karakter pemain lokal.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// Ubah objek posisi menjadi string JSON dan kirim ke server dengan jenis pesan "MoveBot".
this._room.Send("MoveBot", JSON.stringify(position));
}
MoveBotToPosition(message) {
// Parse pesan JSON yang diterima dari klien untuk mengekstrak informasi posisi.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// Pindahkan setiap karakter bot dalam peta `_botMapData` ke posisi yang ditentukan dengan sedikit offset acak pada sumbu x dan z.
this._botMapData.forEach((character: ZepetoCharacter) => {
// Metode `MoveToPosition()` digunakan untuk memindahkan karakter ke posisi yang ditentukan.
// Di sini, sedikit offset acak ditambahkan ke posisi target untuk menciptakan gerakan yang terlihat alami untuk bot.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
5-3. Sekarang jika Anda membuat pemain Bot saat runtime dan menekan tombol buttonCallBot, Anda harus melihat pemain Bot yang dibuat bergerak ke posisi karakter pemain lokal.

Kode lengkap BotPlayerManager.ts
import { Random, Vector3 } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room } from 'ZEPETO.Multiplay';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
export default class BotPlayerManager extends ZepetoScriptBehaviour {
// Properti publik untuk merujuk komponen dan pengaturan yang diperlukan dari Inspector.
public zepetoWorldMultiplay: ZepetoWorldMultiplay;
public buttonCreateBot: Button;
public buttonCallBot: Button;
public botPlayerId: string;
// Variabel privat untuk menyimpan data ruangan dan pemain bot saat ini.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// Mendengarkan event `RoomJoined` dari komponen `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// Menambahkan handler pesan untuk tipe pesan "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// Mendengarkan event `OnAddedPlayer` dari `ZepetoPlayers.instance` untuk menangani pemain yang baru ditambahkan.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// Mendapatkan data pemain saat ini dari status ruangan menggunakan `userId`.
const currentPlayer = this._room.State.players.get_Item(userId);
// Memeriksa apakah pemain adalah bot, dan jika ya, menetapkannya sebagai pemain bot.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
// Menambahkan listener klik pada tombol "Buat Bot" untuk mengirim pesan untuk membuat pemain bot.
this.buttonCreateBot.onClick.AddListener(() => {
this._room.Send("CreateBot", this.botPlayerId);
});
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
this._room.AddMessageHandler("MoveBotToPosition", (message: string) => {
this.MoveBotToPosition(message);
});
}
// Menambahkan listener klik pada tombol "Panggil Bot" untuk mengirim pesan untuk mengirim posisi pemain bot.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// Metode `SetBotPlayer()` digunakan untuk menetapkan pemain sebagai bot.
SetBotPlayer(userId: string) {
// Mendapatkan karakter ZEPETO yang terkait dengan pemain bot menggunakan `userId` mereka.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// Menetapkan nama karakter ke `userId` untuk identifikasi.
bot.gameObject.name = userId;
// Menyimpan data pemain bot dalam peta `_botMapData` menggunakan `userId` mereka sebagai kunci.
this._botMapData.set(userId, bot);
}
// Metode `StartWorld()` dipanggil saat dunia dimulai dengan `playTime` yang diberikan.
StartWorld(playTime: number) {
// Mencetak pesan mulai dunia bersama dengan `playTime`.
console.log(`Mulai Dunia : ${playTime}`);
}
// Metode ini mengirim posisi karakter pemain lokal ke server untuk sinkronisasi gerakan bot.
SendBotPosition() {
// Mendapatkan posisi karakter pemain lokal.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// Membuat objek posisi yang berisi koordinat x, y, dan z dari karakter pemain lokal.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// Mengonversi objek posisi menjadi string JSON dan mengirimkannya ke server dengan tipe pesan "MoveBot".
this._room.Send("MoveBot", JSON.stringify(position));
}
// Metode ini dipanggil saat server menerima pesan "MoveBot" dari klien dan memindahkan karakter bot ke posisi yang ditentukan.
MoveBotToPosition(message) {
// Mengurai pesan JSON yang diterima dari klien untuk mengekstrak informasi posisi.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// Memindahkan setiap karakter bot dalam peta `_botMapData` ke posisi yang ditentukan dengan sedikit offset acak pada sumbu x dan z.
this._botMapData.forEach((character: ZepetoCharacter) => {
// Metode `MoveToPosition()` digunakan untuk memindahkan karakter ke posisi yang ditentukan.
// Di sini, sedikit offset acak ditambahkan ke posisi target untuk menciptakan gerakan yang terlihat alami untuk bot.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
}
kode lengkap server index.ts
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { DataStorage } from "ZEPETO.Multiplay.DataStorage";
import { Player, Transform, Vector3 } from "ZEPETO.Multiplay.Schema";
export default class extends Sandbox {
storageMap: Map<string, DataStorage> = new Map<string, DataStorage>();
// Simpan data peta pemain bot sebagai _botMap
private _botMap: Map<string, Player> = new Map<string, Player>();
private playTime: number = 0;
constructor() {
super();
}
onCreate(options: SandboxOptions) {
// Dipanggil saat objek Ruang dibuat.
// Tangani status atau inisialisasi data objek Ruang.
this.onMessage("onChangedTransform", (client, message) => {
this.state.players.get(client.sessionId);
const player = this.state.players.get(client.sessionId);
const transform = new Transform();
transform.position = new Vector3();
transform.position.x = message.position.x;
transform.position.y = message.position.y;
transform.position.z = message.position.z;
transform.rotation = new Vector3();
transform.rotation.x = message.rotation.x;
transform.rotation.y = message.rotation.y;
transform.rotation.z = message.rotation.z;
if (player) {
player.transform = transform;
}
});
this.onMessage("onChangedState", (client, message) => {
const player = this.state.players.get(client.sessionId);
if (player) {
player.state = message.state;
player.subState = message.subState;
}
});
// Tangani pesan "CreateBot", yang membuat pemain bot dengan userId yang diberikan.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
// Tangani pesan "MoveBot", yang memindahkan pemain bot ke posisi yang ditentukan.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// Metode `CreateBot()` digunakan untuk membuat pemain bot dengan `userId` yang diberikan.
CreateBot(userId: string) {
// Hasilkan ID sesi untuk pemain bot menggunakan `userId` yang diberikan.
const sessionId = "Bot_" + userId;
// Periksa apakah pemain bot dengan ID sesi yang sama sudah ada. Jika ada, kembali tanpa membuat duplikat.
if (this.state.players.has(sessionId)) {
return;
}
// Buat objek `Player` baru untuk pemain bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Tambahkan pemain bot ke peta pemain state menggunakan ID sesi sebagai kunci.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// Periksa jumlah pemain di ruangan setelah menambahkan pemain bot.
this.CheckPlayerNumber();
}
// Metode `CheckPlayerNumber()` memeriksa jumlah pemain di ruangan dan memulai dunia jika ada setidaknya empat pemain.
CheckPlayerNumber() {
// Cetak jumlah pemain saat ini di ruangan ke konsol.
console.log(`jumlah pemain, ${this.state.players.size}`);
// Jika ada setidaknya empat pemain di ruangan, mulai dunia.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// Metode `StartWorld()` meningkatkan waktu bermain dan menyiarkan pesan "StartWorld" ke semua klien.
StartWorld() {
this.playTime += 1;
// Cetak pesan yang menunjukkan dimulainya dunia dan waktu bermain saat ini.
console.log("Mulai Dunia!");
this.broadcast("StartWorld", this.playTime);
}
// Metode `MoveBot()` memindahkan pemain bot ke posisi yang ditentukan berdasarkan pesan yang diterima.
MoveBot(client: SandboxPlayer, message: string) {
// Parse pesan JSON yang diterima dari klien untuk mengekstrak informasi posisi.
const position = JSON.parse(message);
// Buat objek pesan baru dengan ID sesi pengguna dan data posisi yang diparsing.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// Siarkan pesan "MoveBotToPosition" ke semua klien dengan data pesan baru sebagai string JSON.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
async onJoin(client: SandboxPlayer) {
// Buat objek pemain yang didefinisikan dalam schemas.json dan atur nilai awal.
console.log(`[OnJoin] sessionId : ${client.sessionId}, HashCode : ${client.hashCode}, userId : ${client.userId}`)
const player = new Player();
player.sessionId = client.sessionId;
if (client.hashCode) {
player.zepetoHash = client.hashCode;
}
if (client.userId) {
player.zepetoUserId = client.userId;
}
// [DataStorage] Memuat DataStorage dari Pemain yang masuk
const storage: DataStorage = client.loadDataStorage();
this.storageMap.set(client.sessionId, storage);
let visit_cnt = await storage.get("VisitCount") as number;
if (visit_cnt == null) visit_cnt = 0;
console.log(`[OnJoin] jumlah kunjungan ${client.sessionId} : ${visit_cnt}`)
// [DataStorage] Perbarui jumlah kunjungan Pemain dan kemudian Simpan Storage
await storage.set("VisitCount", ++visit_cnt);
// Kelola objek Pemain menggunakan sessionId, nilai kunci unik dari objek klien.
// Klien dapat memeriksa informasi tentang objek pemain yang ditambahkan dengan set dengan menambahkan acara add_OnAdd ke objek pemain.
this.state.players.set(client.sessionId, player);
// Periksa jumlah pemain di ruangan setelah seorang pemain bergabung.
this.CheckPlayerNumber();
}
onTick(deltaTime: number): void {
// Ini dipanggil berulang kali pada setiap waktu yang ditetapkan di server, dan acara interval tertentu dapat dikelola menggunakan deltaTime.
}
async onLeave(client: SandboxPlayer, consented?: boolean) {
// Dengan mengatur allowReconnection, dimungkinkan untuk mempertahankan koneksi untuk sirkuit, tetapi bersihkan segera dalam panduan dasar.
// Klien dapat memeriksa informasi tentang objek pemain yang dihapus dengan menambahkan acara add_OnRemove ke objek pemain.
this.state.players.delete(client.sessionId);
}
}