Add portal system to Lobby Systems

This commit is contained in:
Darto KLoning
2026-09-06 14:03:54 +07:00
parent 8ae4e6982d
commit 7c747f9036
14 changed files with 846 additions and 142 deletions
+237 -64
View File
@@ -1,107 +1,280 @@
# Lobby Systems - Fabric 26.2
# Lobby Systems v1.2.0 — Fabric 26.2
Server-side lobby router untuk Minecraft Java 26.2 / Fabric.
Server-side lobby routing untuk Minecraft 26.2/Fabric. Versi 1.2.0 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/`.
## Identity
## 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 package: `id.dartokloning.lobbysystems`
- Maven group: `id.dartokloning`
- Mod name: `Lobby Systems`
## Requirements
- JDK / Java 25 atau lebih baru
- Minecraft 26.2
- Fabric Loader 0.19.3+
- Fabric API 0.156.0+26.2
- Internet pada build pertama untuk mengunduh Gradle dan dependency Fabric/Minecraft
- Optional: World Manager 1.4.4+26.2 hanya untuk membuat/mengelola world; Lobby Systems tidak memiliki hard dependency ke World Manager
- Java namespace: `id.dartokloning.lobbysystems`
- WorldEdit: opsional untuk runtime portal, diperlukan saat membuat portal memakai `//wand`
## Compile di Windows
Cara termudah: double-click `compile.bat`.
Script tersebut memanggil `compile.ps1`, mengecek Java 25+, mengunduh Gradle 9.5.1 secara lokal ke `.gradle-local` bila diperlukan, lalu menjalankan:
```text
clean build
```
Alternatif PowerShell:
Double-click `compile.bat` atau jalankan:
```powershell
powershell -ExecutionPolicy Bypass -File .\compile.ps1
.\compile.bat
```
JAR hasil build berada di:
Atau langsung:
```powershell
.\compile.ps1
```
Kedua script membaca `mod_version` dan `minecraft_version` langsung dari `gradle.properties`. Header build akan menampilkan versi yang sedang di-compile, misalnya:
```text
build\libs\
============================================
Lobby Systems - Fabric 26.2 Build
Version: 1.2.0
Namespace: id.dartokloning.lobbysystems
Mod ID: dartokloning
============================================
```
Folder `.gradle-local` hanya cache Gradle lokal project dan boleh dihapus kapan saja.
Output utama:
## Compile manual
Jika Gradle sudah terpasang:
```bash
gradle clean build
```text
build/libs/lobby-systems-1.2.0.jar
```
## Configuration
Jalankan server sekali. Edit:
`*-sources.jar` hanya source archive dan tidak perlu dipasang ke server.
`config/lobby-systems.json`
## Struktur konfigurasi v1.2.0
```text
config/
└── lobby/
├── config.json
├── player-positions.json
└── portals.json
```
### `config/lobby/config.json`
Contoh:
```json
{
"lobbyDimension": "minecraft:overworld",
"lobbyX": 0.5,
"lobbyY": 100.0,
"lobbyZ": 0.5,
"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."
}
```
Set `lobbyDimension` ke identifier dimensi/world yang dibuat oleh World Manager.
Lobby selalu memakai koordinat statis dari file ini. Lobby **tidak** disimpan sebagai last-position player.
## Behavior
1. Setiap login diarahkan ke dimensi dan koordinat lobby yang dikonfigurasi.
2. Saat player keluar lobby dan masuk dimensi lain, timer sesi game baru dimulai.
3. `/lobby` saat sudah berada di lobby hanya memberi informasi bahwa player sedang di lobby.
4. `/lobby` di luar lobby diblokir sampai `minimumPlaySeconds` berlalu dan menampilkan countdown.
5. Setelah timer selesai, `/lobby` mengembalikan player ke lobby.
6. Pindah dari satu dimensi non-lobby ke dimensi game lain memulai timer baru untuk dimensi tersebut.
7. Reconnect selalu mengembalikan player ke lobby dan membersihkan timer sesi sebelumnya.
### `config/lobby/player-positions.json`
## World Manager integration
Lobby Systems tidak menggunakan internal API World Manager. World Manager cukup membuat/load custom world, kemudian ID dimensinya dimasukkan ke `lobby-systems.json`. Dengan desain ini, portal mod/command lain juga tetap bisa digunakan.
Berisi posisi terakhir masing-masing player pada dimension non-lobby. Data ini dipakai ketika player kembali melalui portal atau `/ls tp`.
## Admin command (v1.1.3)
Dimension yang sedang dikonfigurasi sebagai lobby disaring pada saat capture, read, dan save sehingga tidak disimpan di file ini.
Requires Minecraft admin/OP command permission.
### `config/lobby/portals.json`
- `/ls reload` — reloads `config/lobby-systems.json` live without restarting the server.
- `/ls tp <dimension>` — teleports the executing player to a loaded dimension. The `<dimension>` argument autocompletes from the server's currently loaded dimension keys.
Portal dibuat lewat command dan tersimpan otomatis. Contoh:
### Last-position behavior
```json
{
"portals": {
"survival": {
"sourceDimension": "minecraft:lobby",
"min": {
"x": 10,
"y": 64,
"z": -5
},
"max": {
"x": 12,
"y": 67,
"z": -5
},
"targetDimension": "minecraft:overworld"
}
}
}
```
Lobby Systems stores each player's last coordinates and rotation per dimension in:
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-systems-positions.json`
## Migrasi dari v1.1.x
When `/ls tp <dimension>` is used, the player returns to their last recorded position in that dimension. If the player has never visited that dimension before, the command falls back to the dimension's configured respawn/spawn position.
Pada startup pertama v1.2.0:
Positions are captured for non-lobby dimensions when players change dimensions, use `/ls tp`, use `/lobby`, disconnect, and are periodically flushed to disk. The configured lobby dimension is deliberately excluded: every teleport/login to the lobby always uses `lobbyX/Y/Z/Yaw/Pitch` from `lobby-systems.json`. Existing saved lobby-position entries are removed automatically on startup/reload.
```text
config/lobby-systems.json
```
## v1.1.3 stability changes
- Cross-dimension teleports now use Minecraft's `TeleportTransition` path instead of calling `teleportTo(...)` directly.
- Destination chunk is loaded before the transition is sent.
- Login-to-lobby is delayed 20 server ticks so the client has time to finish entering play state.
- A 40-tick per-player teleport lock prevents overlapping dimension transitions.
- Lobby position persistence is enforced inside `PositionManager`, not only at call sites. The configured lobby dimension is purged on startup/reload and filtered again before every save, so it cannot be written to `lobby-systems-positions.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.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 <dimension>
/ls portal create <name> <target_dimension>
/ls portal delete <name>
/ls portal list
/ls portal info <name>
/ls portal tp <name>
```
`/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.