Server launcher and start-up checks for other machines
- server/run_server.sh: checks Godot is 4.7+, imports a fresh copy once (the class cache in .godot/ isn't in git), then starts the server - The dedicated server refuses to start, with a clear reason, on Godot older than 4.7 or when the game's scripts failed to load, instead of claiming to listen - tests/run_all.sh imports a fresh copy first - Setup doc: 4.7+ (not 4.3+), importing a fresh copy, running a server
This commit is contained in:
@@ -4,14 +4,39 @@ This project is a self-contained git repo. Everything needed to build and run is
|
||||
in it except **Godot itself** (which you install once per machine). No assets to
|
||||
download — the M0 world is generated in code.
|
||||
|
||||
## 1. Install Godot 4.3+
|
||||
## 1. Install Godot 4.7+
|
||||
- **macOS / Windows / Linux:** download the *standard* build (NOT the .NET/C#
|
||||
build — this project is pure GDScript) from https://godotengine.org/download
|
||||
- Use **4.7.x or newer 4.x**. The project was upgraded to `4.7.2.stable` (an
|
||||
older editor will warn that the project is from a newer version).
|
||||
- Use **4.7.x or newer 4.x**. The project is on `4.7.2.stable`. **Older
|
||||
versions (4.3 etc.) can't run it**: they fail with script errors. Check
|
||||
with `godot --version`, or `/Applications/Godot.app/Contents/MacOS/Godot
|
||||
--version` on a Mac.
|
||||
- macOS shortcut: `brew install --cask godot`. If Homebrew can't unpack it,
|
||||
download the zip from the GitHub release page and move `Godot.app` to
|
||||
`/Applications`.
|
||||
`/Applications` (replacing any older one).
|
||||
|
||||
## 2. First run on a fresh copy: import once
|
||||
Godot keeps its list of named classes (e.g. `Inventory`) in `.godot/`, which
|
||||
isn't in git. Opening the project in the editor creates it. If you only run
|
||||
**headless** (a server, or the tests), import once after cloning:
|
||||
```bash
|
||||
godot --headless --path . --import
|
||||
```
|
||||
Without it you get errors like `Could not find type "Inventory"`.
|
||||
`server/run_server.sh` and `tests/run_all.sh` do this for you.
|
||||
|
||||
## 3. Running a dedicated server
|
||||
```bash
|
||||
server/run_server.sh # settings from server.json
|
||||
server/run_server.sh --server-name "Paul's island" --password secret --port 24242
|
||||
```
|
||||
It checks the Godot version, imports a fresh copy, then starts the server on
|
||||
UDP 24242 with no window. Settings live in `server.json` (its path is printed
|
||||
at start-up; on macOS it's under
|
||||
`~/Library/Application Support/Godot/app_userdata/Valheimlike/server/`).
|
||||
Stop it with Ctrl+C. Players join with **Join Game** on the title screen. Over
|
||||
Tailscale, use the server machine's 100.x address or its machine name. See
|
||||
`docs/MULTIPLAYER_PLAN.md` for all the options.
|
||||
|
||||
## Tests
|
||||
Run everything (fails on any failed check or script error):
|
||||
|
||||
@@ -144,7 +144,26 @@ func is_server() -> bool:
|
||||
|
||||
# --- server -------------------------------------------------------------------
|
||||
|
||||
## Why this Godot can't run the server ("" = it can): too old, or the game's
|
||||
## scripts failed to load (usually a fresh copy that's never been imported).
|
||||
func startup_problem() -> String:
|
||||
var v := Engine.get_version_info()
|
||||
if v.major < 4 or (v.major == 4 and v.minor < 7):
|
||||
return "This game needs Godot 4.7 or newer, but this is %s. Download 4.7.2 from https://godotengine.org/download" % v.string
|
||||
var root: Window = (Engine.get_main_loop() as SceneTree).root
|
||||
for n in ["ItemDB", "Actions", "Saves"]:
|
||||
var node := root.get_node_or_null(n)
|
||||
if node == null or node.get_script() == null:
|
||||
return "The game's scripts didn't load (see the errors above). If this is a fresh copy of the project, " + \
|
||||
"import it once first: godot --headless --path . --import (server/run_server.sh does this for you)"
|
||||
return ""
|
||||
|
||||
func _start_dedicated() -> void:
|
||||
var bad := startup_problem()
|
||||
if not bad.is_empty():
|
||||
printerr("[server] Not starting: ", bad)
|
||||
get_tree().quit(1)
|
||||
return
|
||||
var err := start_server(String(_args.get("config", ServerConfig.DEFAULT_PATH)), _args)
|
||||
if not err.is_empty():
|
||||
printerr("[server] ", err)
|
||||
|
||||
44
server/run_server.sh
Executable file
44
server/run_server.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
# Starts a dedicated Valheimlike server (no window, no local player).
|
||||
#
|
||||
# server/run_server.sh defaults from server.json
|
||||
# server/run_server.sh --port 24242 --server-name "Paul's island" --password secret
|
||||
#
|
||||
# Any flags are passed to the server (see docs/MULTIPLAYER_PLAN.md §2).
|
||||
# Set GODOT=/path/to/godot to use a particular Godot. Stop it with Ctrl+C.
|
||||
#
|
||||
# Before starting it checks that Godot is 4.7 or newer, and imports a fresh
|
||||
# copy of the project once (Godot's class cache lives in .godot/, which isn't
|
||||
# in git, so a new clone can't run headless until it has been imported).
|
||||
|
||||
cd "$(dirname "$0")/.." || exit 1
|
||||
|
||||
GODOT="${GODOT:-godot}"
|
||||
if ! command -v "$GODOT" >/dev/null 2>&1; then
|
||||
# macOS: use the app bundle if `godot` isn't on the PATH.
|
||||
if [ -x /Applications/Godot.app/Contents/MacOS/Godot ]; then
|
||||
GODOT=/Applications/Godot.app/Contents/MacOS/Godot
|
||||
else
|
||||
echo "Can't find Godot. Install 4.7.2 from https://godotengine.org/download, or set GODOT=/path/to/godot" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
version=$("$GODOT" --version 2>/dev/null | tail -n 1)
|
||||
major=$(echo "$version" | cut -d. -f1)
|
||||
minor=$(echo "$version" | cut -d. -f2)
|
||||
if [ -z "$major" ] || [ "$major" -lt 4 ] || { [ "$major" -eq 4 ] && [ "$minor" -lt 7 ]; }; then
|
||||
echo "This game needs Godot 4.7 or newer, but $GODOT is ${version:-unknown}." >&2
|
||||
echo "Download 4.7.2 from https://godotengine.org/download (or set GODOT=/path/to/a/newer/godot)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f .godot/global_script_class_cache.cfg ]; then
|
||||
echo "First run on this copy: importing the project (a few seconds)..."
|
||||
if ! "$GODOT" --headless --path . --import >/dev/null 2>&1 || [ ! -f .godot/global_script_class_cache.cfg ]; then
|
||||
echo "Import failed. Try: $GODOT --headless --path . --import" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$GODOT" --headless --path . -- --server "$@"
|
||||
@@ -4,6 +4,11 @@
|
||||
# Usage: tests/run_all.sh (from the repo root; needs `godot` on PATH)
|
||||
cd "$(dirname "$0")/.." || exit 1
|
||||
status=0
|
||||
# A fresh clone has no class cache yet (.godot/ isn't in git): import once.
|
||||
if [ ! -f .godot/global_script_class_cache.cfg ]; then
|
||||
echo "Importing the project first (fresh copy)..."
|
||||
godot --headless --path . --import >/dev/null 2>&1
|
||||
fi
|
||||
for t in test_survival_core test_survival_stats test_save_load test_weather_building test_creatures_combat test_wolves test_fishing_diet test_net_lobby test_net_world test_terrain_edges test_boundary; do
|
||||
extra=""
|
||||
[ "$t" = "test_boundary" ] && extra="--fixed-fps 30"
|
||||
|
||||
Reference in New Issue
Block a user