Add portal system to Lobby Systems
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user