TDD-002
Remote Events & Functions
Document Information
Purpose
Dokumen ini mengkatalogkan seluruh titik komunikasi client–server yang dibutuhkan sistem yang sudah Final di roadmap, supaya tidak ada aksi gameplay penting yang diputuskan sepihak oleh client (CDR-007 Server Authority, Anti-Exploit Awareness).
Nama Service/Controller pada kolom "Ditangani Oleh" merujuk ke Module Map di TDD-001.
Convention
- Penamaan — client→server:
Request<Verb><Noun>(mis.RequestSellAnimal). server→client:<Noun><PastVerb>atau<Noun>Updated(mis.CoinBalanceUpdated). - RemoteEvent vs RemoteFunction — MVP memakai RemoteEvent untuk hampir semua kasus (fire-and-forget dari client, respons dikirim balik lewat Event terpisah). RemoteFunction dihindari kecuali query read-only sederhana, karena yield di client bisa dieksploitasi untuk menahan server menunggu.
- Satu Folder per Sistem — Remote diorganisir di
ReplicatedStorage/Remotes/<NamaSistem>/, sesuai baris Module Map di TDD-001. - Server selalu validasi ulang — payload dari client hanya berisi intent (ID target, jumlah), server yang menghitung ulang harga/hasil dari GameData, tidak pernah mempercayai angka dari client.
- Rate limit dasar — setiap Remote client→server punya debounce per-player di server (mis. 0.2 detik) untuk mencegah spam request, terpisah dari validasi logika.
Animal & Beast Signal
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestCaptureAnimal | RemoteEvent | C→S | animalInstanceId | Jarak & line-of-sight ke hewan, hewan masih aktif/belum ditangkap pemain lain, cooldown senjata terpenuhi (AnimalService + EquipmentService). |
| AnimalCaptured | RemoteEvent | S→C (target player) | animalId, coinValue, prestigeValue | — (broadcast hasil, sudah tervalidasi server). |
| BeastSignalTriggered | RemoteEvent | S→C (semua client server) | animalId, worldPosition, windowSeconds | Dipicu server saat Hunter-Minute Pool mencapai threshold (BeastSignalService), untuk Minimap Marker & HUD (DN-004). |
| BeastSignalEnded | RemoteEvent | S→C (semua client server) | animalId, caughtByUserId (opsional) | Dipicu saat First-Hit Wins tercapai atau window 3 menit habis. |
Loadout, Inventory & Ekstraksi
Direvisi (Juli 2026). RequestEquipWeapon dan RequestRentBackpack dicabut — senjata tidak lagi dimiliki, dan yang disewa kini Varian (paket lengkap), bukan tier Backpack. Ekstraksi menjadi Remote tersendiri dengan aturan ketat.
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestDepartToMap | RemoteEvent | C→S | variantId, consumableSelection | Level unlock Varian terpenuhi, Coin cukup untuk sewa, Consumable yang dipilih benar-benar dimiliki di Permanent Storage. Coin dipotong di sini, tanpa refund. Server membuat SessionLoadout di memori — tidak pernah ditulis ke DataStore (GDD-003 Session Boundary). |
| RequestPickupAnimal | RemoteEvent | C→S | animalInstanceId | Kapasitas loot tersisa ≥ Size Value hewan, dihitung dari SessionLoadout di server — tidak pernah dari client (InventoryService, CDR-007). |
| RequestExtract | RemoteEvent | C→S | — | Pemain benar-benar berada di area Village. Server memindahkan hanya Animal Record + sisa Consumable milik pemain ke Permanent Storage memakai allowlist; senjata dan ammo bawaan Varian ditolak dan musnah bersama sesi. |
| RequestUseTeleportStone | RemoteEvent | C→S | — | Pemain benar-benar memiliki Teleport Stone di sesi aktif. Menjalankan rutin ekstraksi yang sama persis dengan RequestExtract, tanpa syarat berada di Village (MDD-003 UTL0005). |
RequestUseConsumable | RemoteEvent | C→S | itemId | (baru Juli 2026) Meminum Wild Honey / Spirit Water. Server memvalidasi stok, mengurangi 1, lalu mengisi segmen Boost Stamina yang sesuai. Client tidak pernah mengirim besar efek maupun durasi — keduanya dibaca server dari ItemData (CDR-007). |
ConditionUpdated | RemoteEvent | S→C | hp, boostHoney, boostWater | (baru Juli 2026) Server mengabarkan kondisi pemain untuk digambar di HUD. Dikirim berkala, bukan tiap frame — bar bergerak dalam skala menit, jadi laju kabar yang jarang sudah memadai (CDR-008). |
| Dicabut (Juli 2026) — Emergency Supplies dihapus dari desain (GDD-003). Pemulihan Stamina kini murni aturan gerak/diam yang dihitung server, tanpa Remote. Nama tidak digunakan ulang. | ||||
| InventoryUpdated | RemoteEvent | S→C (target player) | backpackContents, storageSummary | — (sync state, dipicu tiap perubahan Inventory). |
Aturan keamanan yang mengikat implementasi: rutin ekstraksi wajib memakai allowlist (hanya kategori yang secara eksplisit diizinkan yang lolos), bukan blocklist — supaya kategori item baru yang lupa didaftarkan otomatis tertolak, bukan otomatis lolos ke Permanent Storage.
Economy & Market
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestBuyItem | RemoteEvent | C→S | itemId, quantity | Harga dihitung ulang dari EconomyData di server, Coin cukup, Level unlock terpenuhi. Tidak ada parameter lokasi — seluruh transaksi hanya di Lobby (DN-006 v2.0.0). Berlaku untuk Consumable, fuel Companion, Bonding Potion, dan kosmetik. |
| RequestSellAnimal | RemoteEvent | C→S | animalInstanceId atau "sellAll" | Record ada di Permanent Storage (bukan Backpack sesi — penjualan hanya di Lobby setelah ekstraksi), harga dari formula MDD-001, bukan dari client (EconomyService). |
| CoinBalanceUpdated | RemoteEvent | S→C (target player) | newBalance, delta, reason | — (sync state setelah transaksi apa pun yang mengubah Coin). |
| CrystalBalanceUpdated | RemoteEvent | S→C (target player) | newBalance, delta, reason | — (baru) sync mata uang kedua (GDD-006 Currency). |
Companion
Baru (Juli 2026, DN-010). Sistem berburu offline. Aturan mengikat: hasil patroli tidak boleh pernah dikirim ke client sebelum waktunya matang, dan Remote Collect tidak boleh menerima isi hasil dari client — client hanya mengirim niat.
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestStartPatrol | RemoteEvent | C→S | companionId | Companion dimiliki, jumlah Chum mencukupi kebutuhan Companion tersebut (tabel DN-010; klien tidak mengirim jumlah maupun fuelId — server membacanya sendiri), tidak sedang berpatroli. Server men-generate seluruh hasil sesi seketika (seed = Player ID + waktu Start) dan menyimpannya di server saja, lalu menulis timestamp selesai. |
| RequestStopPatrol | RemoteEvent | C→S | companionId | Sedang berpatroli. Slot yang sudah melewati waktu matang dibuka; slot yang belum matang dihapus permanen. |
| RequestCollectPatrol | RemoteEvent | C→S | companionId | Tanpa payload isi. Server membaca hasil yang ia generate sendiri, memfilter hanya slot yang sudah matang, lalu menulis ke Permanent Storage lewat fungsi yang sama dengan ekstraksi Map. |
| RequestEvolveCompanion | RemoteEvent | C→S | speciesId | Spesies berjenis karnivora (kolom Type MDD-001), Animal Record cukup, Bonding Potion cukup, Crystal cukup (CompanionService). |
| PatrolStateUpdated | RemoteEvent | S→C (target player) | companionId, endsAt, hanya slot yang sudah matang | — Slot yang belum matang tidak pernah ikut dikirim, dalam bentuk apa pun. |
Caravan Trade Market
Baru (Juli 2026, DN-011). Seluruh state per-pemain — tidak ada state lintas server setelah kuota global dibatalkan.
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestFulfillOrderInstant | RemoteEvent | C→S | orderId | Pesanan benar-benar aktif untuk pemain ini, stok Permanent Storage lengkap sesuai paket (lengkap atau tidak sama sekali). Nilai dihitung server dari Base Price × pengali, bukan dari client. |
| RequestSendCaravan | RemoteEvent | C→S | orderId | Sama seperti di atas, plus slot Caravan tersedia. Menulis timestamp selesai, bukan hitung mundur. |
| RequestClaimCaravan | RemoteEvent | C→S | shipmentId | Timestamp selesai sudah terlewat. Menambah Coin, akumulasi nilai transaksi, dan Crystal bila melewati milestone. |
| CaravanStateUpdated | RemoteEvent | S→C (target player) | availableOrders, activeShipments (endsAt), tradeValueAccumulated | — (sync state). |
Mount & Character
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestPurchaseMount / RequestPurchaseCharacter (jalur Coin) | RemoteEvent | C→S | mountId / characterId | Level unlock terpenuhi, Coin cukup, belum dimiliki (MountCharacterService, DN-005/DN-009). Hanya berlaku untuk item yang punya jalur Coin — 3 Character gratis (Valdrik/Nayra/Bonoo) tidak lewat remote ini sama sekali, otomatis dimiliki sejak profil dibuat. |
| RequestEquipMount / RequestEquipCharacter | RemoteEvent | C→S | mountId / characterId | Item sudah dimiliki pemain. |
| RequestEvolveMount | RemoteEvent | C→S | speciesId | Spesies berjenis herbivora (kolom Type MDD-001), Animal Record ≥10, Bonding Potion ≥10, Crystal ≥ Rarity Value spesies (MountCharacterService, DN-005 v4.0.0). Menggantikan RequestBondCompanion, yang namanya menyesatkan sejak Companion berarti sistem lain. |
| MountEvolved | RemoteEvent | S→C (target player) | mountId hasil (MNT0004–0006) | — (hasil evolusi yang sudah divalidasi). |
| ProcessReceipt (MarketplaceService) | Callback bawaan Roblox, bukan RemoteEvent custom | S (dipanggil Roblox setelah pembelian Robux) | productId, userId | Wajib pola resmi Roblox untuk seluruh pembelian Robux — Crystal (stok terbatas), Companion eksklusif, dan jalur Robux Mount/Character (MNT0001–0003/0009, CHR0004–0005) yang tersedia kapan saja tanpa syarat Level/Hunter Rank. Tidak boleh diganti RemoteEvent custom — itu bisa dipalsukan client. |
Trophy Room, Progression & Weekly Mission
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| RequestDisplayTrophy | RemoteEvent | C→S | speciesId, pedestalSlot | Collection Data count > 0 untuk spesies, slot dalam batas Room Capacity Tier (TrophyRoomService). |
| RequestUpgradeRoomCapacity | RemoteEvent | C→S | targetTier | Coin cukup sesuai MDD-007. |
| LevelUp | RemoteEvent | S→C (target player) | newLevel, unlockedThisLevel | Dipicu ProgressionService saat EXP melewati threshold MDD-006. |
| HunterRankUp | RemoteEvent | S→C (target player) | newRankId | Dipicu saat Lifetime Prestige melewati threshold DN-001. |
| WeeklyMissionProgressUpdated | RemoteEvent | S→C (target player) | objectiveProgress, isComplete | Dihitung server dari Animal Record yang diekstraksi, bukan dari client (WeeklyMissionService). |
| RequestClaimMissionReward | RemoteEvent | C→S | — | isComplete true & belum diklaim minggu ini. |
Session & Persistence
| Remote | Tipe | Arah | Payload | Validasi Server |
|---|---|---|---|---|
| PlayerDataLoaded | RemoteEvent | S→C (target player) | full profile snapshot (lihat TDD-003) | Dikirim sekali setelah PersistenceService selesai load & PlayerAdded selesai; UI client tidak boleh render sebelum event ini diterima. |
Scope Note
Katalog ini adalah rangka awal (sesuai catatan roadmap #10 "cukup rangka awal") — mencakup satu jalur utama per sistem yang sudah Final. Remote untuk kasus tepi (mis. batalkan Bonding, refund pembelian) belum dirancang dan akan ditambah saat implementasi nyata dimulai di Roblox Studio.