# Lobby Systems v1.4.0 — Fabric 26.2 Server-side lobby routing untuk Minecraft 26.2/Fabric. v1.4.0 menambahkan **native persistent per-dimension gamerules** milik Lobby Systems, tetap mempertahankan portal antar-dimensi, last-position, minimum playtime, gamerule viewer ber-pagination, serta per-dimension player gamemode. **v1.4.0 feature release:** gamerule tidak lagi bergantung pada WorldGameRules. Lobby Systems membuat instance `GameRules` terpisah untuk setiap `ServerLevel`, menyimpan override ke `config/lobby/dimension-gamerules.json`, lalu menerapkannya kembali saat world load, server start, dan `/ls reload`. WorldGameRules harus dihapus karena kedua mod mengubah mekanisme gamerule per-world. ### Reload feedback `/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.4.0 Namespace: id.dartokloning.lobbysystems Mod ID: dartokloning ============================================ ``` Output utama: ```text build/libs/lobby-systems-1.4.0.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.4.0 Minecraft: 26.2 Config directory: config/lobby WorldEdit: available ============================================ ``` ## Struktur konfigurasi v1.4.0 ```text config/ └── lobby/ ├── config.json ├── player-positions.json ├── portals.json ├── dimension-gamemodes.json └── dimension-gamerules.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. ### `config/lobby/dimension-gamemodes.json` Minecraft menyimpan gamemode pada player, bukan pada dimension. Lobby Systems v1.4.0 menambahkan mapping dimension → gamemode dan menerapkannya ketika player masuk ke dimension tersebut. File ini dibuat otomatis dan dapat dikelola lewat command admin. Contoh: ```json { "minecraft:lobby": "adventure", "minecraft:worldcreative": "creative", "minecraft:overworld": "survival" } ``` Gamemode yang didukung: `survival`, `creative`, `adventure`, dan `spectator`. ## Migrasi dari v1.1.x Pada startup pertama v1.4.0: ```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.4.0 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 gamerule /ls gamerule --page /ls gamerule set /ls gamerule reset /ls gamemode /ls gamemode list /ls gamemode set /ls gamemode remove /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. ### Gamerule per dimension `/ls gamerule ` menampilkan gamerule aktual dari dimension yang sedang ter-load. Hasil ditampilkan 10 rule per halaman dan dipisahkan separator agar lebih mudah dibaca di chat. Untuk perubahan yang harus **persist setelah restart**, gunakan `/ls gamerule set ...`. Perintah vanilla `/gamerule` dapat mengubah nilai runtime yang terlihat pada dimension aktif, tetapi perubahan tersebut tidak ditulis ke `dimension-gamerules.json`, sehingga bukan source of truth Lobby Systems. > **Catatan Minecraft 26.2:** mayoritas gamerule gameplay server-side dapat diisolasi melalui `ServerLevel#getGameRules()`. Rule yang berhubungan dengan clock/weather seperti `minecraft:advance_time` dan `minecraft:advance_weather` memiliki mekanisme sinkronisasi tambahan di 26.x; uji keduanya secara khusus sebelum mengandalkannya untuk world yang membutuhkan waktu/cuaca benar-benar independen. Gunakan command berikut untuk membuat override persistent: ```text /ls gamerule set minecraft:lobby minecraft:spawn_mobs false /ls gamerule set minecraft:lobby minecraft:mob_griefing false /ls gamerule set minecraft:lobby minecraft:keep_inventory true ``` Untuk menghapus override dan mengembalikan rule ke default Minecraft: ```text /ls gamerule reset minecraft:lobby minecraft:spawn_mobs ``` Contoh: ```text /ls gamerule minecraft:lobby /ls gamerule minecraft:lobby --page 2 ``` Header chat menampilkan `halaman/total halaman`, nama dimension, dan jumlah gamerule. Jika masih ada halaman berikutnya, command untuk membuka halaman selanjutnya ikut ditampilkan. ### Gamemode per dimension Gunakan mapping gamemode agar player otomatis mendapat gamemode yang sesuai saat memasuki dimension. Contoh: ```text /ls gamemode set minecraft:lobby adventure /ls gamemode set minecraft:worldcreative creative /ls gamemode set minecraft:overworld survival ``` `/ls gamemode ` melihat mapping satu dimension, `/ls gamemode list` melihat semua mapping, dan `/ls gamemode remove ` menghapus mapping. Mapping disimpan ke `config/lobby/dimension-gamemodes.json` dan ikut direload oleh `/ls reload`. ### `/ls reload` Reload live: - `config/lobby/config.json` - `config/lobby/portals.json` - `config/lobby/dimension-gamemodes.json` - `config/lobby/dimension-gamerules.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` atau `compile.sh` pada mesin dengan JDK 25. Saat menguji portal, perhatikan console untuk log teleport dan error WorldEdit selection jika selection belum lengkap. ## License Lobby Systems is **proprietary software — All Rights Reserved**. Public access to this repository is for viewing, auditing, and reference only. Using, running, compiling, modifying, redistributing, or re-uploading the mod requires prior written permission from DartoKloning. See [`LICENSE`](LICENSE) for the complete terms.