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:
+26
-17
@@ -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).
|
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).
|
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.
|
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.
|
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:**
|
**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.
|
- 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.
|
- 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.
|
**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.
|
||||||
- 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.
|
Server location: `~/lan-minecraft/server/` on the box. Setup:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd server
|
ssh server
|
||||||
./setup-server.sh
|
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:
|
# then copy your client modpack's mod jars into mcserver/mods/, and:
|
||||||
sudo systemctl restart mc-lazymc
|
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`
|
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`.
|
||||||
- `SERVER_ADDR` / `$ServerAddr` → `<venue-box-lan-ip>:25565` (lazymc's public port)
|
|
||||||
|
|
||||||
Useful commands during the party:
|
Useful commands during the party:
|
||||||
- `sudo systemctl status mc-lazymc` — check if the MC server is asleep/awake
|
- `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:
|
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 |
|
| 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 |
|
| 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).
|
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`
|
`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.
|
||||||
- **Linux / macOS:** `curl -fsSL http://<your-lan-ip>:8000/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, 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.
|
Make sure your Minecraft server itself is running with `online-mode=false` in `server.properties` — offline accounts only work against offline-mode servers.
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -2,16 +2,18 @@
|
|||||||
# Prism fork), seeds a persistent offline account, drops in the pre-built
|
# Prism fork), seeds a persistent offline account, drops in the pre-built
|
||||||
# modpack instance, and launches straight into it on the LAN server.
|
# modpack instance, and launches straight into it on the LAN server.
|
||||||
#
|
#
|
||||||
# Host this file via: python3 -m http.server 8000 (alongside modpack.zip)
|
# Hosted from Gitea (git.mivanchenko.de), not a local http.server — see HOSTING.md.
|
||||||
# Participants run: irm http://<host-ip>:8000/install.ps1 | iex
|
# Participants run: irm https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main/install.ps1 | iex
|
||||||
|
|
||||||
# ---- EDIT ME before hosting ----
|
# ---- EDIT ME before hosting ----
|
||||||
$HostUrl = "http://192.168.1.50:8000"
|
$HostUrl = "https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main"
|
||||||
$ModpackUrl = "$HostUrl/modpack.zip"
|
$ModpackUrl = "$HostUrl/modpack.zip"
|
||||||
$InstanceName = "LANParty"
|
$InstanceName = "LANParty"
|
||||||
$ServerAddr = "192.168.1.50:25565"
|
$ServerAddr = "minecraft.mivanchenko.de:25565" # DNS name, not a raw IP — repoint the A record instead of rebuilding modpack.zip. See HOSTING.md "Moving the server to the venue".
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop" # fail loudly instead of printing an error and silently continuing
|
||||||
|
|
||||||
$InstallDir = Join-Path $env:USERPROFILE "mc-lan-party"
|
$InstallDir = Join-Path $env:USERPROFILE "mc-lan-party"
|
||||||
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
||||||
Set-Location $InstallDir
|
Set-Location $InstallDir
|
||||||
@@ -69,8 +71,15 @@ Write-Host "==> Offline account '$Nick' ready (UUID $Uuid)"
|
|||||||
New-Item -ItemType Directory -Force -Path "instances" | Out-Null
|
New-Item -ItemType Directory -Force -Path "instances" | Out-Null
|
||||||
if (-not (Test-Path (Join-Path "instances" $InstanceName))) {
|
if (-not (Test-Path (Join-Path "instances" $InstanceName))) {
|
||||||
Write-Host "==> Downloading modpack from $ModpackUrl"
|
Write-Host "==> Downloading modpack from $ModpackUrl"
|
||||||
|
try {
|
||||||
Invoke-WebRequest -Uri $ModpackUrl -OutFile "modpack.zip"
|
Invoke-WebRequest -Uri $ModpackUrl -OutFile "modpack.zip"
|
||||||
Expand-Archive -Path "modpack.zip" -DestinationPath "instances" -Force
|
Expand-Archive -Path "modpack.zip" -DestinationPath "instances" -Force
|
||||||
|
} catch {
|
||||||
|
Write-Host "==> FAILED to fetch/extract the modpack from $ModpackUrl" -ForegroundColor Red
|
||||||
|
Write-Host " $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
Write-Host " (Fjord Launcher itself installed fine at $InstallDir\app — this just means modpack.zip isn't being served yet.)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
Write-Host "==> Modpack installed to instances\$InstanceName"
|
Write-Host "==> Modpack installed to instances\$InstanceName"
|
||||||
} else {
|
} else {
|
||||||
Write-Host "==> Instance already present, skipping download"
|
Write-Host "==> Instance already present, skipping download"
|
||||||
|
|||||||
+5
-5
@@ -3,15 +3,15 @@
|
|||||||
# seeds a persistent offline account, drops in the pre-built modpack instance,
|
# seeds a persistent offline account, drops in the pre-built modpack instance,
|
||||||
# and launches straight into it on the LAN server.
|
# and launches straight into it on the LAN server.
|
||||||
#
|
#
|
||||||
# Host this file via: python3 -m http.server 8000
|
# Hosted from Gitea (git.mivanchenko.de), not a local http.server — see HOSTING.md.
|
||||||
# Participants run: curl -fsSL http://<host-ip>:8000/install.sh | bash
|
# Participants run: curl -fsSL https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main/install.sh | bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# ---- EDIT ME before hosting ----
|
# ---- EDIT ME before hosting ----
|
||||||
HOST_URL="http://192.168.1.50:8000" # where THIS script + modpack.zip are served from
|
HOST_URL="https://git.mivanchenko.de/mivanchenko/mc-lan-party/raw/branch/main" # Gitea raw-file base URL
|
||||||
MODPACK_URL="$HOST_URL/modpack.zip" # exported Prism instance folder, zipped (see HOSTING.md)
|
MODPACK_URL="$HOST_URL/modpack.zip" # exported Prism instance folder, zipped, committed to the repo (see HOSTING.md)
|
||||||
INSTANCE_NAME="LANParty" # must match the top-level folder name inside modpack.zip
|
INSTANCE_NAME="LANParty" # must match the top-level folder name inside modpack.zip
|
||||||
SERVER_ADDR="192.168.1.50:25565" # your Minecraft server IP:port
|
SERVER_ADDR="minecraft.mivanchenko.de:25565" # DNS name, not a raw IP — repoint the A record to whichever box is running the server (prep machine now, venue box at party time) instead of rebuilding modpack.zip. See HOSTING.md "Moving the server to the venue".
|
||||||
GH_REPO="unmojang/FjordLauncherUnlocked" # fallback if hero-persson's fork disappears; see note below
|
GH_REPO="unmojang/FjordLauncherUnlocked" # fallback if hero-persson's fork disappears; see note below
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
|
||||||
|
|||||||
+61
@@ -26,6 +26,33 @@ Target: **Minecraft 1.20.1, Forge**. This version/loader combo has the widest, m
|
|||||||
| [Delightful Creators](https://modrinth.com/mod/delightful-creators) | Bridges Create ↔ Farmer's Delight: soups/stews as Create fluids, sequenced-assembly "incomplete foods," cookie/pie recipes usable in Create contraptions. |
|
| [Delightful Creators](https://modrinth.com/mod/delightful-creators) | Bridges Create ↔ Farmer's Delight: soups/stews as Create fluids, sequenced-assembly "incomplete foods," cookie/pie recipes usable in Create contraptions. |
|
||||||
| [FarmersCreate](https://modrinth.com/mod/farmerscreate) | Lets Create's Mixer/Deployer automate Farmer's Delight cooking-pot and cutting-board recipes (auto-cook the feast, don't stand there clicking). |
|
| [FarmersCreate](https://modrinth.com/mod/farmerscreate) | Lets Create's Mixer/Deployer automate Farmer's Delight cooking-pot and cutting-board recipes (auto-cook the feast, don't stand there clicking). |
|
||||||
|
|
||||||
|
## Questing (the actual roadmap/quest-line UI)
|
||||||
|
|
||||||
|
| Mod | Why it's in |
|
||||||
|
|---|---|
|
||||||
|
| [FTB Quests](https://www.curseforge.com/minecraft/mc-mods/ftb-quests-forge) | The quest book itself — this is where the food roadmap actually lives in-game. Build one quest chapter per day (Overworld → Nether → End), one quest per dish from `food.md`, with the required Create/Farmer's Delight item as the completion trigger and a reward chest/item. Players get a checklist UI (default hotkey, or a quest-giver NPC/item) showing exactly what to cook/build next. |
|
||||||
|
| [FTB Library (Forge)](https://www.curseforge.com/minecraft/mc-mods/ftb-library-forge) | Required dependency of FTB Quests. |
|
||||||
|
| [FTB Teams (Forge)](https://www.curseforge.com/minecraft/mc-mods/ftb-teams-forge) | Required dependency of FTB Quests — also lets you decide whether quest progress is per-player or shared per-team, worth deciding before building the quest line (per-player means everyone cooks everything themselves; shared team means the group completes the roadmap together). |
|
||||||
|
| [Architectury API](https://modrinth.com/mod/architectury-api) | Required dependency (cross-loader API FTB's mods are built on). |
|
||||||
|
|
||||||
|
All four go in **both** client and server `mods/` folders — unlike Distant Horizons/Chunky above, quest progress is synced through the server, so it's not optional on either side.
|
||||||
|
|
||||||
|
**Install via Fjord's built-in CurseForge/Modrinth browser, not manual jars** — these four mods have had real version-mismatch bugs between each other on 1.20.1 ([example](https://github.com/FTBTeam/FTB-Mods-Issues/issues/1168)), and the in-launcher browser resolves compatible dependency versions automatically instead of you having to hand-pick a working combination.
|
||||||
|
|
||||||
|
**Building the quest line:** open the quest book in-world (default keybind, configurable), create chapters, and for each dish you picked in `food.md` add a quest with an "item" task pointing at that dish (e.g. the actual `Shepherd's Pie` item) as the completion condition — FTB Quests detects it automatically when a player crafts/holds/turns it in, no extra setup needed. Do this once on your prepped instance before exporting, same as the mods/server-list/DH-cache steps in `HOSTING.md` — the quest progress file lives inside the instance too, so it travels with the modpack zip.
|
||||||
|
|
||||||
|
## VR support (optional, per-player)
|
||||||
|
|
||||||
|
| Mod | Side | Why it's in |
|
||||||
|
|---|---|---|
|
||||||
|
| [Vivecraft](https://modrinth.com/mod/vivecraft) | Client only | Adds VR rendering/motion controls for anyone with a **PC-tethered or PC-streamed headset** (Index, Vive, or a Quest using Air Link/Virtual Desktop into a gaming PC). Pure client-side — connects to the same server as everyone else playing on a flat screen, no server mod required for basic play. |
|
||||||
|
| [ViveCraft Compat](https://www.curseforge.com/minecraft/mc-mods/vivecraft-compat) | Client only | Patches specific interactions between Vivecraft and other mods in this pack — notably **Create** (fixes driving trains, track hitboxes, elevator controls in VR) and HUD overlay support for Jade. Requires Vivecraft. |
|
||||||
|
| Customizable Player Models | Client only (likely also needs server-side for other players to see the model — verify) | Pulled in by Fjord's dependency resolver alongside Vivecraft; lets a player's in-VR avatar/body be customized rather than using the default. |
|
||||||
|
|
||||||
|
**Note on standalone Quest headsets (no PC):** this is for *PC-tethered/streamed* VR only. A standalone Meta Quest with no gaming PC involved would use **QuestCraft** instead — a separate sideloaded Android app that bundles its own Minecraft+Vivecraft runtime directly on the headset. QuestCraft does **not** go through Fjord/`install.sh`/`install.ps1` at all; it's installed on the headset itself via sideloading tools (SideQuest etc.), connects to the same server address, but has its own separate mod manager with less certain compatibility against a heavy pack like this one (Create/Flywheel especially). If anyone at the party wants to join standalone without a PC, treat that as a separate per-person setup, not something this repo's scripts handle.
|
||||||
|
|
||||||
|
Vivecraft auto-detects whether a headset is actually connected and falls back to normal flatscreen play otherwise — so it's safe to leave in the single shared `modpack.zip` for everyone rather than maintaining a separate VR-only instance; people without a headset just won't notice it's there.
|
||||||
|
|
||||||
## Performance utility
|
## Performance utility
|
||||||
|
|
||||||
| Mod | Side | Why it's in |
|
| Mod | Side | Why it's in |
|
||||||
@@ -33,6 +60,8 @@ Target: **Minecraft 1.20.1, Forge**. This version/loader combo has the widest, m
|
|||||||
| [Distant Horizons](https://modrinth.com/mod/distanthorizons) | Client only | Renders a simplified level-of-detail view of terrain beyond the server's `view-distance`, so players see far-off scenery without the server having to actually load/send those chunks. Does the same job you were picturing from "Bobby" — Bobby itself is **Fabric-only** (no Forge build exists), so Distant Horizons is the Forge equivalent. Caches the LOD data locally per-world, same idea as Bobby's chunk cache. |
|
| [Distant Horizons](https://modrinth.com/mod/distanthorizons) | Client only | Renders a simplified level-of-detail view of terrain beyond the server's `view-distance`, so players see far-off scenery without the server having to actually load/send those chunks. Does the same job you were picturing from "Bobby" — Bobby itself is **Fabric-only** (no Forge build exists), so Distant Horizons is the Forge equivalent. Caches the LOD data locally per-world, same idea as Bobby's chunk cache. |
|
||||||
| [Chunky](https://www.curseforge.com/minecraft/mc-mods/chunky-pregenerator-forge) | Server only | Pre-generates a fixed radius of chunks around a chosen center (e.g. spawn/build area) **once, before the party**, via console/RCON commands (`/chunky radius`, `/chunky start`) — eliminates on-the-fly world-gen lag while people explore. **Not** a per-player dynamic follower on Forge — that variant ("Chunky Pregenerator") is Fabric-only, same restriction as Bobby. See `HOSTING.md` for the exact commands. |
|
| [Chunky](https://www.curseforge.com/minecraft/mc-mods/chunky-pregenerator-forge) | Server only | Pre-generates a fixed radius of chunks around a chosen center (e.g. spawn/build area) **once, before the party**, via console/RCON commands (`/chunky radius`, `/chunky start`) — eliminates on-the-fly world-gen lag while people explore. **Not** a per-player dynamic follower on Forge — that variant ("Chunky Pregenerator") is Fabric-only, same restriction as Bobby. See `HOSTING.md` for the exact commands. |
|
||||||
|
|
||||||
|
**Do not install Distant Horizons on the dedicated server, even though DH has an optional server-side mode for pushing accurate LOD data without clients needing to explore.** DH-on-server + Chunky-on-server together crashes the world on first chunk load (`IllegalStateException: Chunky is not loaded`, thrown from DH's Chunky-compat accessor trying to bind to a provider API that's only properly initialized on Bukkit/Paper's Chunky plugin, not the Forge mod port). Keep DH strictly client-only as documented above; get accurate distant terrain by having the host physically explore the pregenerated area once (creative-flight spiral pattern, see `HOSTING.md`) and bundling the resulting `Distant_Horizons_server_data/` cache into `modpack.zip` instead.
|
||||||
|
|
||||||
**Important:** install Distant Horizons in the client instance's `mods/` folder only — do **not** put it in the server's `mods/` folder. It tags itself as client-side in its mod metadata, so Forge won't reject the mismatched mod list between client and server. Keep the server's `server.properties` `view-distance` modest (6–8, see `HOSTING.md` sizing section) and let Distant Horizons fill in the rest visually on each client. Chunky, conversely, only needs to go in the **server's** `mods/` folder — it has no client-side purpose here.
|
**Important:** install Distant Horizons in the client instance's `mods/` folder only — do **not** put it in the server's `mods/` folder. It tags itself as client-side in its mod metadata, so Forge won't reject the mismatched mod list between client and server. Keep the server's `server.properties` `view-distance` modest (6–8, see `HOSTING.md` sizing section) and let Distant Horizons fill in the rest visually on each client. Chunky, conversely, only needs to go in the **server's** `mods/` folder — it has no client-side purpose here.
|
||||||
|
|
||||||
## Optional / stretch (only if the group wants more scope)
|
## Optional / stretch (only if the group wants more scope)
|
||||||
@@ -41,6 +70,38 @@ Target: **Minecraft 1.20.1, Forge**. This version/loader combo has the widest, m
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| [Aether's Delight](https://modrinth.com/mod/the-aethers-delight) | Aether-themed dishes (Holystone/Zanite knives, berry bowls, buffed meals) | Requires installing **The Aether** too — a full extra dimension mod. Only add if someone really wants to make the trip. |
|
| [Aether's Delight](https://modrinth.com/mod/the-aethers-delight) | Aether-themed dishes (Holystone/Zanite knives, berry bowls, buffed meals) | Requires installing **The Aether** too — a full extra dimension mod. Only add if someone really wants to make the trip. |
|
||||||
|
|
||||||
|
## Installed list (as actually downloaded)
|
||||||
|
|
||||||
|
What Fjord's dependency-resolver pulled in when adding the mods above — several of these are auto-added dependencies/QoL mods I hadn't called out individually. Transcribed from the "You're about to download the following mods" confirmation dialog on 2026-10-23; **the dialog was scrolled/cut off in the screenshot, so this list may be incomplete** — if there were more entries below `Nether's Delight`, let me know and I'll fold them in (expecting at least `Flywheel` and possibly `FarmersCreate` to still be in there).
|
||||||
|
|
||||||
|
| Mod | Role |
|
||||||
|
|---|---|
|
||||||
|
| AppleSkin | QoL — HUD overlay showing exact hunger/saturation/exhaustion values instead of guessing from the icon. |
|
||||||
|
| Architectury API | Dependency — cross-loader API FTB's mods are built on. |
|
||||||
|
| Chunky (Forge/NeoForge) | Listed above — server-side pregen. |
|
||||||
|
| Create | Listed above — core. |
|
||||||
|
| Create Slice & Dice | Create addon — automates cutting/dicing-style food prep via Create contraptions; pulled in alongside Delightful Creators for the Create↔food bridge. |
|
||||||
|
| Delightful | Listed above. |
|
||||||
|
| Delightful Creators [Forge] | Listed above. |
|
||||||
|
| Distant Horizons: A Level of Detail mod | Listed above — client-only LOD rendering. |
|
||||||
|
| End's Delight | Listed above. |
|
||||||
|
| Farmer's Delight | Listed above — base. |
|
||||||
|
| Farmer's Respite | Farmer's Delight addon — adds tea/drinks (kettle, brewed teas) as another food category; worth adding a quest or two for this if you want a drinks stage in the roadmap. |
|
||||||
|
| Farmers Structures | Adds farmhouse-style structures that generate in the world — gives the Overworld food chapter something to explore toward, not just build from scratch. |
|
||||||
|
| [FerriteCore](https://modrinth.com/mod/ferritecore) | Performance — reduces RAM usage by deduplicating/compacting in-memory data structures (block states, chunk storage) that Forge normally keeps bloated. Pure upside, no gameplay effect; lowers how much of the `HOSTING.md` sizing-table RAM budget actually gets used. Goes in **both** client and server `mods/` folders. |
|
||||||
|
| FTB Library (NeoForge) | Listed above — FTB Quests dependency. |
|
||||||
|
| FTB Quests (NeoForge) | Listed above — the quest book. |
|
||||||
|
| FTB Teams (NeoForge) | Listed above — FTB Quests dependency. |
|
||||||
|
| Jade | QoL — "look at" overlay showing block/entity info on hover (WAILA-style), handy with this many new mod blocks/crops to identify. |
|
||||||
|
| Just Enough Items (JEI) | Listed above — recipe lookup. |
|
||||||
|
| Kotlin for Forge | Library dependency — several newer mods (Jade and others) are written in Kotlin and need this runtime present. |
|
||||||
|
| MezzConfig | Library dependency — shared in-game config-menu framework used by multiple mods here. |
|
||||||
|
| ModernFix | Performance — reduces startup/load time and fixes various vanilla/Forge memory leaks; pure upside for a 3-day session that stays up a long time. |
|
||||||
|
| Mouse Tweaks | QoL — shift-click/drag item sorting in inventories, genuinely load-bearing once Create/Farmer's Delight items start filling chests. |
|
||||||
|
| Nether's Delight | Listed above. |
|
||||||
|
|
||||||
|
Note the dependency-resolver pulled in `(NeoForge)`-labeled builds for the FTB mods — double-check in Fjord that these are actually resolving against your Forge 1.20.1 instance correctly (Fjord's CurseForge integration sometimes labels the underlying artifact by its primary platform name even when serving the Forge-compatible build); if the instance fails to load with a loader-mismatch error on these three, swap to the explicitly-"Forge"-tagged FTB Library/Quests/Teams listings instead.
|
||||||
|
|
||||||
## Why this shape
|
## Why this shape
|
||||||
|
|
||||||
- Create gives you *progression* (you have to build the farm/kitchen contraption before you "unlock" a dish) — good quest-line material.
|
- Create gives you *progression* (you have to build the farm/kitchen contraption before you "unlock" a dish) — good quest-line material.
|
||||||
|
|||||||
+9
-29
@@ -1,8 +1,10 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# One-time setup for the LAN party's dedicated box: installs a Forge 1.20.1
|
# One-time setup for the LAN party's dedicated box: installs a Forge 1.20.1
|
||||||
# Minecraft server, wraps it in lazymc (auto-sleep when empty / auto-wake on
|
# Minecraft server and wraps it in lazymc (auto-sleep when empty / auto-wake
|
||||||
# connect), and serves the client install scripts + modpack.zip over HTTP —
|
# on connect), as a systemd service so it runs unattended for the 3 days.
|
||||||
# all as systemd services so the box can run unattended for the 3 days.
|
#
|
||||||
|
# File distribution (install.sh/install.ps1/modpack.zip) is NOT handled by
|
||||||
|
# this script — see HOSTING.md, it's served from Gitea instead.
|
||||||
#
|
#
|
||||||
# Target: a Linux machine (Debian/Ubuntu/etc with systemd) at the venue.
|
# Target: a Linux machine (Debian/Ubuntu/etc with systemd) at the venue.
|
||||||
# Run as a normal user with sudo rights: ./setup-server.sh
|
# Run as a normal user with sudo rights: ./setup-server.sh
|
||||||
@@ -13,7 +15,6 @@ FORGE_MC_VERSION="1.20.1"
|
|||||||
FORGE_BUILD="47.4.28" # current recommended build for 1.20.1 — check files.minecraftforge.net if this is stale
|
FORGE_BUILD="47.4.28" # current recommended build for 1.20.1 — check files.minecraftforge.net if this is stale
|
||||||
MC_PUBLIC_PORT=25565 # what players connect to (lazymc listens here)
|
MC_PUBLIC_PORT=25565 # what players connect to (lazymc listens here)
|
||||||
MC_INTERNAL_PORT=25566 # real server listens here, lazymc proxies to it
|
MC_INTERNAL_PORT=25566 # real server listens here, lazymc proxies to it
|
||||||
FILESERVER_PORT=8000 # install.sh / install.ps1 / modpack.zip served from here
|
|
||||||
SLEEP_AFTER="5m" # idle time before lazymc stops the real server
|
SLEEP_AFTER="5m" # idle time before lazymc stops the real server
|
||||||
MIN_RAM="2G"
|
MIN_RAM="2G"
|
||||||
MAX_RAM="6G" # 5-8 players; see ../HOSTING.md sizing table — bump to 8G (9-12p) or 10-12G (13-15p)
|
MAX_RAM="6G" # 5-8 players; see ../HOSTING.md sizing table — bump to 8G (9-12p) or 10-12G (13-15p)
|
||||||
@@ -21,13 +22,10 @@ MAX_RAM="6G" # 5-8 players; see ../HOSTING.md sizing ta
|
|||||||
|
|
||||||
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
SERVER_DIR="$BASE_DIR/mcserver"
|
SERVER_DIR="$BASE_DIR/mcserver"
|
||||||
DIST_DIR="$BASE_DIR/dist"
|
|
||||||
FORGE_VERSION="${FORGE_MC_VERSION}-${FORGE_BUILD}"
|
FORGE_VERSION="${FORGE_MC_VERSION}-${FORGE_BUILD}"
|
||||||
|
|
||||||
command -v java >/dev/null || { echo "Java not found. Install a Java 17+ JDK (e.g. 'sudo apt install -y openjdk-17-jre-headless') then re-run."; exit 1; }
|
command -v java >/dev/null || { echo "Java not found. Install a Java 17+ JDK (e.g. 'sudo apt install -y openjdk-17-jre-headless') then re-run."; exit 1; }
|
||||||
command -v python3 >/dev/null || { echo "python3 not found. Install it (e.g. 'sudo apt install -y python3') then re-run."; exit 1; }
|
mkdir -p "$SERVER_DIR"
|
||||||
|
|
||||||
mkdir -p "$SERVER_DIR" "$DIST_DIR"
|
|
||||||
|
|
||||||
# ---- 1. Install the Forge server ----
|
# ---- 1. Install the Forge server ----
|
||||||
if [[ ! -f "$SERVER_DIR/run.sh" ]]; then
|
if [[ ! -f "$SERVER_DIR/run.sh" ]]; then
|
||||||
@@ -114,32 +112,14 @@ User=${USER}
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo tee /etc/systemd/system/mc-fileserver.service >/dev/null <<EOF
|
|
||||||
[Unit]
|
|
||||||
Description=LAN party modpack/install-script file server
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=${DIST_DIR}
|
|
||||||
ExecStart=/usr/bin/python3 -m http.server ${FILESERVER_PORT}
|
|
||||||
Restart=on-failure
|
|
||||||
User=${USER}
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
sudo systemctl enable --now mc-lazymc.service mc-fileserver.service
|
sudo systemctl enable --now mc-lazymc.service
|
||||||
|
|
||||||
echo "==> Done."
|
echo "==> Done."
|
||||||
echo " - Minecraft server: public port ${MC_PUBLIC_PORT}, sleeps after ${SLEEP_AFTER} idle, wakes on connect."
|
echo " - Minecraft server: public port ${MC_PUBLIC_PORT}, sleeps after ${SLEEP_AFTER} idle, wakes on connect."
|
||||||
echo " - File server: http://<this-box-lan-ip>:${FILESERVER_PORT}/ serving ${DIST_DIR}/"
|
echo " - Install scripts + modpack.zip are served from Gitea, not this box — see ../HOSTING.md."
|
||||||
echo " - Put install.sh, install.ps1 and modpack.zip into ${DIST_DIR}/ (see ../HOSTING.md)."
|
|
||||||
echo " - Copy your client mod jars into ${SERVER_DIR}/mods/ if you haven't yet, then: sudo systemctl restart mc-lazymc"
|
echo " - Copy your client mod jars into ${SERVER_DIR}/mods/ if you haven't yet, then: sudo systemctl restart mc-lazymc"
|
||||||
if command -v ufw >/dev/null && sudo ufw status | grep -q "Status: active"; then
|
if command -v ufw >/dev/null && sudo ufw status | grep -q "Status: active"; then
|
||||||
echo "==> ufw is active — opening ${MC_PUBLIC_PORT}/tcp and ${FILESERVER_PORT}/tcp"
|
echo "==> ufw is active — opening ${MC_PUBLIC_PORT}/tcp"
|
||||||
sudo ufw allow "${MC_PUBLIC_PORT}/tcp"
|
sudo ufw allow "${MC_PUBLIC_PORT}/tcp"
|
||||||
sudo ufw allow "${FILESERVER_PORT}/tcp"
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user