Move file distribution to Gitea, deploy server on mivanchenko.de

Drops the standalone fileserver systemd unit from setup-server.sh in
favor of Gitea's already-public raw-file serving. Adds VR (Vivecraft)
and quest (FTB Quests) mod docs, the DH/Chunky server-side crash
warning, and documents the real deployment target (always-on homelab
box, not a venue-local machine).
This commit is contained in:
Mykhailo Ivanchenko
2026-10-23 15:01:00 +02:00
parent a243213b47
commit cd694a67b6
5 changed files with 116 additions and 57 deletions
+26 -17
View File
@@ -6,7 +6,12 @@
2. Create a new instance: Minecraft **1.20.1**, **Forge**. Name it exactly `LANParty` (or change `INSTANCE_NAME`/`$InstanceName` in both scripts to match).
3. Add the mods from `modpack.md` (use the launcher's built-in Modrinth/CurseForge browser, or drop jars straight into the instance's `mods/` folder).
4. **Set up the server and pregenerate first** — do the "Set up the dedicated venue box" and "Pre-generate chunks before the party starts (Chunky)" steps below *before* continuing here. Distant Horizons can only cache real terrain that already exists; it can't backfill detail after the fact.
5. Launch the client, go to **Multiplayer → Add Server**, enter the venue box's LAN IP, and join for real. Set your preferred video settings (these land in `options.txt`). Then fly/walk around the pregenerated build area with a decent render distance and Distant Horizons enabled — this is what actually populates `Distant_Horizons_server_data/` in the instance with real LOD data for that area. Quit when you've covered the zone you pregenerated.
5. Launch the client, go to **Multiplayer → Add Server**, enter `minecraft.mivanchenko.de:25565` (not a raw IP — see "Moving the server to the venue" below), and join for real. Set your preferred video settings (these land in `options.txt`). Then do a flying pass to populate the Distant Horizons cache — client-only DH can't backfill terrain it hasn't actually received as real chunks, so this has to be done by hand:
- Switch to **Creative**, double-tap **Space** for creative flight (hold sprint to go faster).
- Temporarily bump your client's **render distance** up (Video Settings) — DH only caches what the server actually sends within that range, so a higher render distance covers more ground per pass.
- Fly a spiral or back-and-forth grid centered on spawn, covering roughly the same radius you pregenerated with Chunky (800 blocks ≈ 50 chunks), spacing passes about 1–1.5× your render distance apart so coverage overlaps slightly.
- Partial coverage is fine — anywhere you don't reach just falls back to the normal fog edge, same as skipping this step, not an error.
- Quit when you've covered the zone. This is what actually populates `Distant_Horizons_server_data/` in the instance with real LOD data — do **not** try to shortcut this by installing Distant Horizons on the dedicated server instead (see the warning in `modpack.md`'s Performance section — DH-on-server crashes when Chunky is also present).
6. Quit the launcher, then export the instance via **right-click the instance → Export Instance** (don't blindly zip the raw folder — the exporter lets you pick what's included). Check: `mods/`, `config/`, `options.txt`, `servers.dat`, `Distant_Horizons_server_data/`. Uncheck: `logs/`, `crash-reports/`, `screenshots/`, and any asset/library caches — those regenerate automatically on first launch and just bloat the zip. Name the result `modpack.zip`, with the instance's folder (`LANParty/...`) as the zip's top-level entry.
**Caveats for this to actually pay off for participants:**
@@ -14,27 +19,28 @@
- Don't regenerate/reset the server world after this point. If the actual party world differs from the one you explored, the cached LOD will show stale terrain that doesn't match reality.
- This cache is for *scenery beyond render distance* only — it doesn't substitute for the server having `online-mode=false` or for Chunky's pregen; all three pieces (pregen, DH cache, offline accounts) are independent and all need to land in the final zip/setup.
## 2. Set up the dedicated venue box (one machine, does both jobs)
## 2. The server: `mivanchenko.de` (always-on, not a box you carry to the venue)
Run `server/setup-server.sh` on the Linux box you're bringing to the party. It:
This setup runs on the existing homelab box at `mivanchenko.de` (SSH: `ssh server`, i.e. port 222, same machine already running Gitea/n8n/the SMB stack/etc) rather than a machine physically present at the party. That means **no DNS repoint, no file-server migration, no "moving to the venue" step** — `minecraft.mivanchenko.de` already resolves here and stays pointed here.
- Installs the Forge 1.20.1 server and wraps it in **lazymc**, which sleeps the real server after 5 idle minutes and transparently wakes it the instant someone connects — no manual start/stop for the whole 3 days.
- Serves `server/dist/` over HTTP via a systemd unit (survives logout, auto-restarts if it dies).
- Opens the relevant ports in `ufw` if it's active.
**Tradeoff to be aware of:** since the server isn't on the venue's local network, players connect over the internet, not LAN — latency depends on the venue's internet connection, not your switch. For a 3-day modded-Minecraft LAN party this is usually fine (Minecraft is forgiving of 20–60ms), but if the venue's internet is bad, this is the thing that bites. Worth testing from the venue ahead of time if you can.
Server location: `~/lan-minecraft/server/` on the box. Setup:
```bash
cd server
./setup-server.sh
ssh server
cd ~/lan-minecraft
# copy server/setup-server.sh here (or git clone the mc-lan-party repo), then:
cd server && ./setup-server.sh
# then copy your client modpack's mod jars into mcserver/mods/, and:
sudo systemctl restart mc-lazymc
```
Put `install.sh`, `install.ps1`, and `modpack.zip` into `server/dist/` (that's what gets served on port 8000).
`setup-server.sh` installs the Forge 1.20.1 server and wraps it in **lazymc**, which sleeps the real server after 5 idle minutes and transparently wakes it the instant someone connects — no manual start/stop for the whole 3 days. It does **not** handle file distribution (see section 3 — that's Gitea now, not this script).
Find the box's LAN IP (`ip a`) and edit the top of **both** `install.sh` and `install.ps1`:
Since port 25565 is reached directly (Minecraft is raw TCP, not HTTP — Caddy on this box only proxies HTTP(S) on 80/443 and has no layer4/TCP module, so it genuinely can't front Minecraft traffic), there's no Caddy entry to add for `minecraft.mivanchenko.de`. lazymc just binds `0.0.0.0:25565` on the host directly, same way `crafty_container` already exposes its own Minecraft ports on this box.
- `HOST_URL` / `$HostUrl` → `http://<venue-box-lan-ip>:8000`
- `SERVER_ADDR` / `$ServerAddr` → `<venue-box-lan-ip>:25565` (lazymc's public port)
Services temporarily stopped on this box to free up resources for the party (`docker stop`, not removed — bring back with `docker start <name>` after): `smb-crm`, `smb-db`, `breathemate-license`, `crafty_container`, `n8n-n8n-1`, `open-webui`, `mcpo`.
Useful commands during the party:
- `sudo systemctl status mc-lazymc` — check if the MC server is asleep/awake
@@ -45,7 +51,7 @@ Useful commands during the party:
Create is the dominant cost here — it's heavier on the server **tick thread (CPU)** than on RAM, because kinetic networks and contraptions get simulated every tick regardless of how many players are nearby. Farmer's Delight/its addons are cheap by comparison. Numbers below assume this modpack (~10 mods) and are *total host box* numbers, not just the JVM heap:
| Concurrent players | JVM heap (`-Xmx`, set in `setup-server.sh`) | Host RAM (total, incl. OS + file server) | CPU | Free disk | Network |
| Concurrent players | JVM heap (`-Xmx`, set in `setup-server.sh`) | Host RAM (total, incl. OS + other running services) | CPU | Free disk | Network |
|---|---|---|---|---|---|
| 5–8 | 6G | 10–12 GB | 4 cores, 3.5 GHz+ single-core perf matters more than core count | ~10 GB (world + mods + Forge libs + logs) | Gigabit LAN recommended, Wi-Fi workable |
| 9–12 | 8G | 12–16 GB | 4–6 cores, 3.5 GHz+ | ~15 GB | Gigabit LAN recommended |
@@ -75,12 +81,15 @@ Chunky (server-side mod, already listed in `modpack.md`) fills in a radius of re
Repeat with `/chunky world the_nether` / `/chunky world the_end` first if you want the Nether/End build areas pregenerated too (useful since the roadmap sends people there for Nether's/End's Delight dishes).
## 3. Give participants the one-liner
## 3. File distribution: Gitea, not a local file server
- **Windows:** `irm http://<your-lan-ip>:8000/install.ps1 | iex`
- **Linux / macOS:** `curl -fsSL http://<your-lan-ip>:8000/install.sh | bash`
`install.sh`, `install.ps1`, and (once built) `modpack.zip` are committed straight to the `mc-lan-party` repo on Gitea (`git.mivanchenko.de`, already proxied by Caddy and public), served via its raw-file URLs. No separate file-server process on the venue/server box — one less moving part, and it's fine for now per your call; worth revisiting (e.g. Gitea releases/LFS, or an object store) if `modpack.zip` turns out large enough that Gitea's raw-file serving gets awkward.
Each script asks for a nickname, derives a stable offline-mode UUID from it (so the same name = same player data across the whole 3-day party, even if they re-run the script), seeds that into a fresh `accounts.json`, downloads Fjord Launcher Unlocked + the modpack, and launches straight into the instance already connected to your server.
Give participants:
- **Windows:** `irm https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main/install.ps1 | iex`
- **Linux / macOS:** `curl -fsSL https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main/install.sh | bash`
Each script asks for a nickname, derives a stable offline-mode UUID from it (so the same name = same player data across the whole 3-day party, even if they re-run the script), seeds that into a fresh `accounts.json`, downloads Fjord Launcher Unlocked + the modpack from Gitea, and launches straight into the instance already connected to `minecraft.mivanchenko.de`.
Make sure your Minecraft server itself is running with `online-mode=false` in `server.properties` — offline accounts only work against offline-mode servers.