# Lobby Systems v1.2.2 — Fabric 26.2 Server-side lobby routing untuk Minecraft 26.2/Fabric. Versi 1.2.2 menambahkan portal antar-dimensi berbasis WorldEdit selection, last-position per player/per dimension, minimum playtime sebelum kembali ke lobby, dan konfigurasi terpusat di `config/lobby/`. ### Reload feedback v1.2.2 `/ls reload` menulis banner `RELOAD START` dan `RELOAD COMPLETE` hanya ke console server. Ringkasan reload satu baris dikirim langsung hanya ke player admin/operator yang menjalankan command; ringkasan tersebut tidak dibroadcast ke player lain dan tidak dikirim melalui command feedback ke console. ## Target build - Minecraft: 26.2 - Fabric Loader: 0.19.3 - Fabric API: 0.156.0+26.2 - Fabric Loom: 1.17 - Java: 25+ - Mod ID: `dartokloning` - Java namespace: `id.dartokloning.lobbysystems` - WorldEdit: opsional untuk runtime portal, diperlukan saat membuat portal memakai `//wand` ## Compile di Windows Double-click `compile.bat` atau jalankan: ```powershell .\compile.bat ``` Linux/macOS: ```bash chmod +x compile.sh release.sh ./compile.sh ``` `compile.bat` dan `compile.sh` membaca `mod_version` dan `minecraft_version` langsung dari `gradle.properties`. Setelah `BUILD SUCCESS`, script akan menanyakan apakah source ingin di-commit dan di-push ke Git/Gitea. Header build akan menampilkan versi yang sedang di-compile, misalnya: ```text ============================================ Lobby Systems - Fabric 26.2 Build Version: 1.2.2 Namespace: id.dartokloning.lobbysystems Mod ID: dartokloning ============================================ ``` Output utama: ```text build/libs/lobby-systems-1.2.2.jar ``` `*-sources.jar` hanya source archive dan tidak perlu dipasang ke server. ## Membuat Gitea Release Gunakan `release.bat` di Windows atau `./release.sh` di Linux/macOS. Release script akan: 1. menjalankan build melalui mode `--build-only`; 2. memastikan source sudah di-commit/push; 3. membuat/push tag `v`; 4. membuat Gitea Release melalui API; 5. mengupload `build/libs/lobby-systems-.jar` sebagai release asset. Default repository release: ```text https://git.darto.id/dartokloning/lobby-systems ``` API release membutuhkan Gitea Personal Access Token. Jangan simpan token di repository. Anda dapat memasukkan token ketika script meminta, atau menyediakan environment variable `GITEA_TOKEN`. ## Console state logging State penting Lobby Systems memakai separator agar mudah terlihat di server console, antara lain startup, config load, player-position store ready, portal load, reload, player join/disconnect, portal create/delete, dan teleport. Contoh: ```text ============================================ Lobby Systems - READY Version: 1.2.2 Minecraft: 26.2 Config directory: config/lobby WorldEdit: available ============================================ ``` ## Struktur konfigurasi v1.2.2 ```text config/ └── lobby/ ├── config.json ├── player-positions.json └── portals.json ``` ### `config/lobby/config.json` Contoh: ```json { "lobbyDimension": "minecraft:lobby", "lobbyX": -12.5, "lobbyY": 65.0, "lobbyZ": -3.5, "lobbyYaw": 0.0, "lobbyPitch": 0.0, "minimumPlaySeconds": 300, "portalCheckIntervalTicks": 5, "portalCooldownTicks": 60, "inLobbyMessage": "§eKamu sudah berada di lobby.", "returnedMessage": "§aKamu telah kembali ke lobby.", "waitMessage": "§cKamu belum bisa kembali ke lobby. Tunggu §e{time}§c lagi." } ``` Lobby selalu memakai koordinat statis dari file ini. Lobby **tidak** disimpan sebagai last-position player. ### `config/lobby/player-positions.json` Berisi posisi terakhir masing-masing player pada dimension non-lobby. Data ini dipakai ketika player kembali melalui portal atau `/ls tp`. Dimension yang sedang dikonfigurasi sebagai lobby disaring pada saat capture, read, dan save sehingga tidak disimpan di file ini. ### `config/lobby/portals.json` Portal dibuat lewat command dan tersimpan otomatis. Contoh: ```json { "portals": { "survival": { "sourceDimension": "minecraft:lobby", "min": { "x": 10, "y": 64, "z": -5 }, "max": { "x": 12, "y": 67, "z": -5 }, "targetDimension": "minecraft:overworld" } } } ``` Portal adalah region/cuboid, bukan harus Nether Portal asli. Anda bebas membuat bentuk doorway, arch, lantai, gateway, dan sebagainya di dalam region tersebut. ## Migrasi dari v1.1.x Pada startup pertama v1.2.2: ```text config/lobby-systems.json ``` akan dimigrasikan ke: ```text config/lobby/config.json ``` Dan: ```text config/lobby-systems-positions.json ``` akan dimigrasikan ke: ```text config/lobby/player-positions.json ``` Nama file lama hanya digunakan oleh `LegacyConfigMigrator` untuk proses migrasi. Runtime v1.2.2 membaca dan menulis file baru di `config/lobby/`. Jika file tujuan baru sudah ada, migrator tidak menimpanya. ## Command player ```text /lobby ``` - Jika sudah di lobby: memberi informasi bahwa player sudah berada di lobby. - Jika berada di gameplay dimension: hanya dapat digunakan setelah `minimumPlaySeconds` tercapai. - Jika terlalu cepat: menampilkan countdown. - Jika berhasil: selalu kembali ke fixed lobby spawn dari `config.json`. ## Command admin / OP ```text /ls reload /ls tp /ls portal create /ls portal delete /ls portal list /ls portal info /ls portal tp ``` `/ls tp` tetap command maintenance/admin. Player biasa tidak memerlukannya karena flow normal menggunakan portal. ### `/ls reload` Reload live: - `config/lobby/config.json` - `config/lobby/portals.json` - lobby exclusion pada player-position store Tidak perlu restart untuk perubahan JSON tersebut. ### Membuat portal dengan WorldEdit 1. Pastikan WorldEdit Fabric 26.2 terpasang di server. 2. Masuk ke dimension tempat portal akan berada, biasanya Lobby. 3. Gunakan: ```text //wand ``` 4. Select dua sudut cuboid portal. 5. Buat portal: ```text /ls portal create survival minecraft:overworld ``` Target dimension memiliki autocomplete dari daftar dimension yang sedang loaded. Contoh lain: ```text /ls portal create nether minecraft:the_nether /ls portal create dungeon mypack:dungeon ``` Nama portal hanya menerima huruf kecil `a-z`, angka `0-9`, `_`, dan `-`. WorldEdit hanya dibutuhkan saat membaca selection untuk **membuat** portal. Setelah `portals.json` tersimpan, portal runtime dikelola Lobby Systems sendiri. Jika WorldEdit dilepas kemudian, portal yang sudah ada tetap dapat bekerja. ### Menghapus dan mengecek portal ```text /ls portal list /ls portal info survival /ls portal delete survival ``` Nama portal memiliki autocomplete. ### Teleport admin ke region portal ```text /ls portal tp survival ``` Command ini digunakan untuk maintenance. Lobby Systems memberi suppression sementara agar admin tidak langsung mengaktifkan portal tepat setelah teleport ke region tersebut. ## Perilaku destination Jika target adalah gameplay dimension: - player pernah mengunjungi dimension tersebut → teleport ke last position; - belum pernah → fallback ke spawn dimension. Jika target adalah Lobby: - selalu teleport ke `lobbyX/Y/Z/Yaw/Pitch`; - tidak pernah menggunakan last-position; - jika portal berasal dari gameplay dimension, minimum playtime tetap diberlakukan. ## Portal detection dan performa `portals.json` tidak dibaca setiap tick. Portal dimuat ke RAM saat startup atau `/ls reload` dan di-index berdasarkan source dimension. Default pemeriksaan region: ```json "portalCheckIntervalTicks": 5 ``` Artinya sekitar empat kali per detik. Region check hanya berupa perbandingan koordinat player dengan portal pada dimension yang sama. Setelah portal aktif, `portalCooldownTicks` mencegah portal terpicu berulang saat client menyelesaikan dimension transition. Teleport lintas dimension tetap memakai `TeleportTransition` dan teleport lock dari v1.1.3. ## Flow server ```text JOIN ↓ Lobby fixed spawn ↓ Player berjalan ke portal ↓ Portal region terdeteksi ↓ Gameplay dimension ↓ Last position jika tersedia / spawn jika pertama kali ↓ Minimum gameplay time ↓ /lobby ↓ Lobby fixed spawn ``` ## Catatan pengujian Karena project ini menargetkan Java 25, compile final sebaiknya dilakukan menggunakan `compile.bat`/`compile.ps1` pada mesin dengan JDK 25. Saat menguji portal, perhatikan console untuk log teleport dan error WorldEdit selection jika selection belum lengkap.