terainia/run.sh
Maximus Gorog 3a4ae970b2 pre-alpha 0.0.1 — initial multiplayer voxel sandbox
Web/wasm Rust voxel game with:
- wgpu 23 client (WebGPU when available, WebGL2 fallback)
- Chunked terrain (17x17 chunks, deterministic value-noise generator)
- Greedy meshing with frustum + distance culling
- Sky shader, leaf wind shader, distance fog
- Player physics: substepped AABB collision, gravity, fall damage,
  natural-surface respawn
- Touch UI (MCPE-style joystick + jump/break/place/sprint),
  gamepad polling with axis calibration, mouse+keyboard
- HP / death-screen / respawn flow
- 10-slot hotbar with mouse-wheel + hotkey + tap cycling
- Settings menu (mouse sens, FOV, render distance, input mode toggle)
- Axum multiplayer server: WebSocket protocol, edit log,
  10Hz player broadcasts
- 31 unit tests covering spawn invariants, collision sweeps,
  raycast hit/miss, greedy mesh winding, fall damage, oriented
  box rotation, hotbar block roundtrip, and the input-merge
  regression that latched movement after touch release

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:33:47 -06:00

96 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# Build the wasm bundle, build + run the multiplayer server, and open a public
# tunnel via localhost.run (free, ssh-based, no signup).
#
# Usage:
# ./run.sh # build everything then run server + tunnel
# ./run.sh --no-tunnel # local only (http://localhost:8080)
# ./run.sh --no-build # skip rebuild; just run
set -euo pipefail
cd "$(dirname "$0")"
DO_BUILD=1
DO_TUNNEL=1
for arg in "$@"; do
case "$arg" in
--no-build) DO_BUILD=0 ;;
--no-tunnel) DO_TUNNEL=0 ;;
*) echo "unknown arg: $arg" >&2; exit 1 ;;
esac
done
if [[ $DO_BUILD -eq 1 ]]; then
echo "==> running unit tests (proves spawn / collision / mesh invariants)"
cargo test --lib
echo "==> building wasm client (release)"
cargo build --target wasm32-unknown-unknown --release --lib
~/.cargo/bin/wasm-bindgen --target web --out-dir web --no-typescript \
target/wasm32-unknown-unknown/release/voxel_game.wasm
echo "==> building server (release)"
(cd server && cargo build --release)
# Catch JS no-undef / parse errors before they hit the browser. eslint
# is optional: warns if absent so this step never blocks an emergency
# deploy, but normally you should `npm i -g eslint` to get it.
if command -v npx >/dev/null 2>&1; then
if [[ -f web/.eslintrc.json ]]; then
echo "==> linting web/main.js"
(cd web && npx --no-install eslint main.js) \
|| echo " (eslint reported issues; not fatal)"
fi
else
echo " (skipping JS lint: npx not installed)"
fi
fi
SERVER_BIN="./target/release/voxel-server"
if [[ ! -x "$SERVER_BIN" ]]; then
# workspace fallback: server has its own target
SERVER_BIN="./server/target/release/voxel-server"
fi
# Kill any previous instance.
pkill -f 'voxel-server' 2>/dev/null || true
pkill -f 'http.server --directory web' 2>/dev/null || true
sleep 0.3
echo "==> starting server on :8080"
STATIC_DIR="$(pwd)/web" "$SERVER_BIN" &
SERVER_PID=$!
trap 'echo; echo "stopping..."; kill $SERVER_PID 2>/dev/null || true; kill $TUNNEL_PID 2>/dev/null || true; exit' INT TERM
# Wait for server to come up.
for i in {1..20}; do
if curl -sf -o /dev/null http://localhost:8080/; then break; fi
sleep 0.2
done
if [[ $DO_TUNNEL -eq 0 ]]; then
echo "==> server running at http://localhost:8080 (no tunnel)"
wait $SERVER_PID
exit
fi
echo "==> opening Cloudflare quick tunnel (free, no signup)"
echo " look for the trycloudflare.com URL below; share that link."
echo
CLOUDFLARED="${CLOUDFLARED:-$HOME/.local/bin/cloudflared}"
if [[ ! -x "$CLOUDFLARED" ]] && command -v cloudflared >/dev/null 2>&1; then
CLOUDFLARED="$(command -v cloudflared)"
fi
if [[ ! -x "$CLOUDFLARED" ]]; then
echo "cloudflared not found. Install it with:"
echo " mkdir -p ~/.local/bin && curl -sL -o ~/.local/bin/cloudflared \\"
echo " https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 \\"
echo " && chmod +x ~/.local/bin/cloudflared"
kill $SERVER_PID 2>/dev/null || true
exit 1
fi
"$CLOUDFLARED" tunnel --url http://localhost:8080 --no-autoupdate &
TUNNEL_PID=$!
wait $SERVER_PID
kill $TUNNEL_PID 2>/dev/null || true