Local

The local package is the Gamehoster code that runs on your own machine. You download gamehoster-local-<version>.zip, unzip it to a local/ directory, and run the one command inside it, gamehoster-local.js. That command parses the command line, loads your config, and hands off to one script per job: sync (compile each game to static code and push it) and the local browser tools. The package is in four parts: localhoster-common/, the shared toolkit every hoster carries; localhoster-tools/, the two universal browser tools; gamehoster-tools/, this hoster's own tools; and gamehoster-sync/, the sync command with the compiler it drives (which bundles the browser runtime, covered on the Frontend page, into each game's library). The directory you see here is exactly the directory in the zip. This page is the file map — every file, then a section giving its exports, or, for the command you run, its switches.

local/                            unzips from gamehoster-local-<version>.zip
  gamehoster-local.js                the one command you run: parse args, load config, dispatch
  config.example.json                the config template (copy to config.json)
  localhoster-common/                 the shared toolkit, identical across every hoster
    index.js                        the single require surface (loadConfig, toolsSite, the UI kit)
    net.js                          config load, bare-IP TLS, API-version
    run.js                          the tools-site frame + per-tool run state
    shell.js                        the page frame: strip, tabs, status, stylesheet
    ui.js                           the UI kit: cards, tables, charts, pagination
    format.js                       formatters: esc, numbers, bytes, dates
    io.js                           small render/IO helpers
  localhoster-tools/                  the universal tools, shared across every hoster
    web-logs/
      index.js                      run(config): pull the access logs, then build the browser
      lib/
        pull.js                    mirror the access logs down
        render.js                  build the Web Logs pages
        chart.client.js            draw the charts + tables in the browser
    server-logs/
      index.js                      run(config): pull the stats, then build the browser
      lib/
        pull.js                    mirror the server stats down
        render.js                  build the Server Logs pages
        chart.client.js            draw the charts + tables in the browser
  gamehoster-tools/                   this hoster's own tools
    game-logs/
      index.js                      run(config): read the game defs, then build the browser
      lib/
        render.js                  render the per-domain Game Logs pages
        chart.client.js            draw the charts + tables in the browser
  gamehoster-sync/                    the sync command and the compiler it drives
    index.js                        run(config): compile, diff vs the server, push changes
    lib/
      compile.js                    compile a game def to static server + client code
      loader.js                     read a definition directory
      schema.js                     field types + defaults
      runtime/
        gamehoster-client.js       the browser client bundled into each game's library
        snapshot.js                the snapshot store bundled into each game's library
The gamehoster-local package: the entry, the shared toolkit, the universal and gamehoster-specific tools, and the sync command with its compiler.

Files

FileWhat it does
the entry
gamehoster-local.jsThe one command you run. Parses the command line, loads the config, and dispatches to each command's own script. Holds no logic itself.
config.example.jsonThe config template: your server address, its token, your games folder, and where the tools pages are built. Copy it to config.json.
localhoster-common/ — the shared toolkit
localhoster-common/index.jsThe single require surface the entry and every tool use: loadConfig, the toolsSite frame builder, recordRun, and the UI kit.
localhoster-common/net.jsReads and validates the config into a frozen object, skips cert verification for a bare-IP endpoint, and discovers the server's API version.
localhoster-common/run.jsThe tools-site frame: toolsSite(config, brand) builds the overview + tabs + clash-safe status; recordRun persists each tool's last run.
localhoster-common/shell.jsThe shared page frame: the top strip, tool tabs, per-tool status banner, and stylesheet.
localhoster-common/ui.jsThe shared UI kit a browser composes: stat cards, tables, chart/table toggles, and pagination.
localhoster-common/format.jsThe canonical formatters: escaping, numbers, bytes, durations, and month/day labels.
localhoster-common/io.jsSmall render/IO helpers, chiefly the footer-stripping used by the write-if-changed comparison.
localhoster-tools/ — the universal tools
localhoster-tools/web-logs/Web Logs: index.js is the tool (run(config)); lib/pull.js mirrors the Caddy access logs down and lib/render.js builds the browser. lib/chart.client.js renders its charts in the browser.
localhoster-tools/server-logs/Server Logs: index.js is the tool; lib/pull.js mirrors the server statistics down and lib/render.js builds the drill-down browser. lib/chart.client.js renders its charts in the browser.
gamehoster-tools/ — this hoster's own tools
gamehoster-tools/game-logs/Game Logs: index.js is the tool; lib/render.js reads the game definitions and renders the browsable per-domain map. Touches no API. lib/chart.client.js renders its charts in the browser.
gamehoster-sync/ — the sync command + compiler
gamehoster-sync/index.jsThe sync command (run(config)): compile every game, diff the games root against the server by content hash, push the differences and prune removals.
gamehoster-sync/lib/compile.jsCompiles a game definition to a static server module and a front-end library, inlining every body as a real function. Detailed on Server.
gamehoster-sync/lib/loader.js · schema.jsRead a definition directory; the field types and defaults it applies. The compiler's own copies (the server carries its own).
gamehoster-sync/lib/runtime/gamehoster-client.jsThe browser client bundled into each game's library: connect, frame, send. Detailed on Frontend.
gamehoster-sync/lib/runtime/snapshot.jsThe browser snapshot store bundled into each library: fold the server's appear/changed/gone deltas, keep a short history, interpolate on a smoothed clock.

gamehoster-local.js — entry point

The one command you run for the server tools, and the only file with no exports. It parses the command line, loads your config into a frozen object with loadConfig, and dispatches to one script per job: sync first (so content is published before the browsers render it), then each requested browser tool. When they have run it reassembles the shared tools site with toolsSite (the overview, the tab strip, and each tool's status). It holds no logic itself: one explicit line per command, and the config it hands each script is read-only.

SwitchWhat it does
--config <path>Required. The full absolute path to a .json config file. A missing path, another flag, a relative path, or a non-.json file is rejected.
--syncCompile every game to static code and push the changes to the server.
--game-logsBuild the Game Logs browser from your game definitions.
--web-logsMirror the access logs down and build the Web Logs browser.
--server-logsMirror the server stats down and build the Server Logs browser.
--allEverything in one process: sync and all three browser tools.

gamehoster-sync/index.js

The sync command. Its run(config) takes one pass with the frozen config from the entry. It first compiles every game, regenerating its static gamehoster.server.js and gamehoster.client.js from the definition (via lib/compile.js, reading lib/runtime/gamehoster-client.js as the library base), then compares the games root to the server by content hash and pushes only the differences, pruning files removed locally. What syncs is decided by structure, not a blocklist: only <domain>/<game>/** under a dotted domain folder, skipping reserved _/. names. Nothing stays resident. The full protocol is the Sync page.

ExportWhat it is
run(config)One sync pass: compile every game, diff the games root against the server, push the changes and prune removals. Returns { generated, pushed, pruned }.
localTree(root)Walk the games root into { relpath: { hash, abs } }, taking each <domain>/<game>/ subtree and hashing every file by its SHA-256 content.
managed(rel)Whether a server path is one the local package owns, and may therefore prune: at least <domain>/<game>/ deep. Reserved dirs and loose files on the server are left untouched.
isDomain(name), isGame(name)The structural rules that decide what syncs: a domain is a dotted, non-reserved directory; a game is any non-reserved directory holding a gamehoster-game.json.

gamehoster-tools/game-logs/index.js

The Game Logs browser generator, and this hoster's own domain tool (the analog of sitehoster's Automation Logs and datahoster's Data Logs). Where the log browsers read the access logs, this one reads the game definitions — the same tree the server loads — and renders a complete, browsable, static map of every game on the server, organised by domain: each game's config (tick/send rates, capacity), its player and instance state schemas, its entity types, and its commands (the parameters each takes and the state each writes). It composes the shared shell, UI kit and formatters, so it feels like one tool with the log browsers, and it touches no API — everything is built from the local files with write-if-changed and orphan pruning.

ExportWhat it is
build(options)Scan the game definitions under contentRoot and render the per-domain Game Logs browser. Takes { contentRoot, outDir, ip }; returns the summary the Game Logs card shows.

gamehoster-sync/lib/runtime/gamehoster-client.js — browser runtime

The browser game client. It opens the game socket and folds the server's per-player state deltas into a snapshot store; each display frame it hands the front end an interpolated view of the public state, drawn a fixed buffer behind the server's leading edge so motion stays smooth under jitter. Beyond one bit of local responsiveness — your own object's prediction, run for you by the store from the game's predict body and the live input you push with conn.input — it runs no game logic: the server is authoritative, and a command takes effect on the server's next tick. It is not a Node module: it defines Gamehoster.connect on the page. At sync, generate.js bundles this file, together with the snapshot store and the game's baked client-only bodies (the predict body, and any per-object -enter.js / -smooth.js), into each game's gamehoster.client.js library with that game's config. The whole model is the Frontend page.

MemberWhat it is
Gamehoster.connect(game, join, opts)Open a game socket and return the connection object below.
onReady(cb)Run cb once the welcome has arrived and updates are flowing; it fires at once if the connection is already ready.
send(type, params, predict)Send a command; the server applies it on its next tick. The optional predict patch is laid over every frame until the server's ack catches up to this command, when the authoritative state stands. Returns the command's sequence number.
input(name, value)Feed the live local input the game's predict body reads (e.g. thrust held, aim angle), so your own object is simulated forward the instant you act.
frame()Advance the render clock and return the interpolated view for this display frame: { self, tick, instance, players[], entities[] }.
latest(id)The newest authoritative (un-interpolated) state: one object by id, or the whole freshest view when called with no id.
now(), lead()The leading-edge server-tick estimate, and how far it leads the newest data the client holds.
tickRate, close()The game's tick rate, baked into the generated client, and closing the socket.

gamehoster-sync/lib/runtime/snapshot.js

The browser snapshot store, and the whole of what the client keeps. It runs no game logic and simulates none of the world; the schema tables and binary codec are baked into the generated client, so it decodes each update against this game's schema. The game bodies it runs are all client-only rendering helpers: the baked predict body, once per tick for the local player's own object only — simulating it from live input and reconciling it toward authority — and, per object, the optional -enter.js (once, when the object first appears, to seed its front-end persistent bag) and -smooth.js (each frame, to override the default per-field interpolation). Every other object is only interpolated. It folds in the server's per-player deltas (appear / changed / gone, each stamped with the server tick), keeps a short history of each object's public state, and drives a render clock locked to the server's tick rate. The clock is advanced by the local timer, so its pace stays constant under jitter, and only gently slewed toward the tick the newest packet implies; the render position sits a fixed buffer behind that leading edge, so a later sample is normally in hand to interpolate toward. It also holds the per-object front-end persistent bags and the optimistic command overlays, each overlay retired when the server's ack catches up to it. The Frontend page is this mechanism in full.

ExportWhat it is
SnapshotThe store bundled into the library: onUpdate (fold a server delta, and _runEnter the per-object -enter.js body for anything newly appeared), addPending (record an optimistic overlay), setInput (feed live input to the predict body), advance (step the render clock and run the own-object predict body from the local timer), frame (the interpolated view — with the predicted own object overlaid and each object's smoothState -smooth.js override applied), latest / newest (the un-interpolated authoritative state), and a per-object front-end persistent bag the enter and smooth bodies share.

localhoster-common/net.js

The shared API-client plumbing every hoster's downloaders sit on: read the config, skip cert verification for a bare-IP (self-signed) endpoint, and discover the server's API version so request paths follow it. Meant to be copied across the hosters unchanged. (The sync tool reads its own gamehoster-config-* config directly; this file backs the log/stat pulls the tools orchestrator runs.)

ExportWhat it is
loadConfig(path)Read and validate the local tool's config JSON into the shape the tools expect.
isIpHttps(apiBase)Whether the endpoint is HTTPS to a bare IP literal (or [ipv6]) — hence self-signed.
disableTlsVerification()Quiet the one-time Node warning and disable TLS verification process-wide (only for an IP endpoint).
resolvePrefix(...)Discover the server's API version and build the /api/vN path prefix the requests use.

localhoster-common/run.js

The shared tools-site frame. Each tool renders its own pages during its own run(config) and records its result; this assembles the surrounding site — the overview (one card per tool), the tab strip, and a "not run yet" status page for any tool that has never produced pages. It reads each tool's own state file, so running one tool never clobbers another tool's card. There is no shared mutable state: each tool owns <toolsRoot>/<key>/.state.json.

ExportWhat it is
toolsSite(config, brand)A builder: register each tool's tab with .add(tool), one line per tool, then .render() writes the overview, tabs and status around whatever ran.
recordRun(outDir, summary)A tool records its last-run time and summary into its own output dir, read back to draw its overview card.

localhoster-tools/web-logs/lib/render.js

The Web Logs browser generator. It reads the Caddy JSON access logs mirrored down by pull-logs.js and renders a set of static, self-contained HTML pages so the traffic can be browsed offline. Composes the shared shell, UI kit and formatters; also runnable standalone.

ExportWhat it is
build(options)Render the Web Logs browser. The local tool passes { logsDir, outDir }; run standalone it reads the log dir beside the script.

localhoster-tools/server-logs/lib/render.js

The Server Logs browser generator — the reader half of the shared stats facility. It reads the per-type dated day-files mirrored down by pull-stats.js and writes a drill-down site (all time → month → day → hour → minute), each page charting every metric with a chart/table toggle.

ExportWhat it is
build(options)Render the Server Logs browser. The local tool passes { dataDir, outDir, serverIp }; run standalone it reads the data dir beside the script.

localhoster-tools/web-logs/lib/pull.js

Mirror the server's Caddy access logs into a data dir — the log counterpart of pull-stats.js. Rotated files are immutable (fetched once, whole); the active log grows, so only its new tail is appended via a Range request; a newly-appeared rotated file means the active log restarted, so it resets and re-fetches. TLS is expected to be already configured by the caller.

ExportWhat it is
pull(opts)Mirror the access logs down incrementally. Takes { logsDir, apiBase, apiToken } and reports how many lines were mirrored.

localhoster-tools/server-logs/lib/pull.js

Mirror the server's statistics day-files into a data dir — the stats counterpart of pull-logs.js. The server samples CPU, memory, disk and IO into per-type dated files; a frozen past day is fetched once and today's growing file has only its tail appended by Range. TLS is expected to be already configured by the caller.

ExportWhat it is
pull(opts)Mirror the stats day-files down incrementally. Takes { dataDir, apiBase, apiToken } and reports what was fetched and appended.

localhoster-common/shell.js

The shared shell that owns the page frame for the tools site: the fixed top strip (brand + Overview + a tab per tool + the IP), the per-tool status banner, the stylesheet, and small formatters. The same strip goes on every page; the tab set and brand are configured per project by run.js at startup, so this file carries no project identity and copies across the hosters unchanged.

ExportWhat it is
layout(opts)Render a full framed page (top strip + body) for the Overview and any not-run tool's status page.
toolStrip(...)The fixed top strip a tool browser injects at the top of its own pages, so the tabs are identical everywhere.
statusBanner(tool)The per-tool banner shown when a tool has not been run.
overviewCard(tool, state)One tool's card on the Overview, reflecting its last-run state.
setTools(tools), setBrand(brand)Configure the tab set and brand for this project (called by run.js); TOOLS, brandName() expose them.
esc, fmtNum, fmtBytes, stripFooterThe formatters and footer-stripper re-exported for convenience, plus STYLESHEET and TOOLSTRIP_CSS.

localhoster-common/ui.js

The shared UI kit for the tools browsers — the reusable builders a domain tool composes instead of hand-rolling markup. The page frame lives in shell.js and the formatters in format.js; specialised chart bodies stay per-browser, bound to each tool's data.

ExportWhat it is
panel(...), table(...)A titled panel, and a table with a built-in Show-all toggle.
statCards(items)A row of stat blocks (name + value, or a custom cell).
navButtons(prev, next, up)Prev / Next (with an optional Up) pagination, used on every dated page.
viewToggle(...)A chart ⇄ table switch for a metric.
SCRIPT, CSSThe shared client JS (table toggle + chart switch) and the common visual furniture.

localhoster-common/format.js

The canonical formatters shared by the tools browsers — pure functions with no state, meant to be copied across the hoster projects unchanged.

ExportWhat it is
esc(s)HTML-escape a value for safe interpolation.
fmtNum(n)A grouped decimal number (thousands separators).
fmtBytes(b)A human byte size (B, KB, MB, …).
fmtDuration(ms)A compact duration (ms, s, or m s).
monthLabel, monthLabelShort, dayLabel, MONTH_NAMESMonth/day label helpers and the month-name table used by the dated pages.

localhoster-common/io.js

Small shared render/IO helpers for the tools browsers. The footer carries the page's generation time, which changes every run; stripFooter removes the whole footer before the write-if-changed comparison so a new timestamp alone never forces a rewrite.

ExportWhat it is
stripFooter(html)Remove the footer block before comparing a freshly rendered page to the one on disk.
rmrf(p)Recursively remove a path (for a clean full rebuild).
GEN_DURATION_TOKENThe placeholder a browser writes for the generation time and patches with the real value last.

gamehoster-sync/lib/compile.js — run at sync

The code generator the sync drives on your machine. It reads a game definition directory and emits two plain, static JS files — a server module and a front-end library — with every raw body inlined as a real function (Gamehoster) { … } literal, so nothing is compiled with new Function at request time. For the library it also bundles the runtime for the browser: the snapshot store and this game's binary codec inlined into one IIFE, with no game logic. It reuses the server's schema.js and loader.js, so the generated code and the running server can never disagree. Full detail lives on the Server and Sync pages.

ExportWhat it is
generateServer(dir)Compile a definition directory to the static gamehoster.server.js module the server requires.
generateClient(dir, clientBaseSrc)Compile a definition to the gamehoster.client.js library: the snapshot runtime, the client base, this game's config, and the game's baked client-only bodies — gamehoster-player-predict.js for your own object, and any per-object -enter.js / -smooth.js the runtime runs while rendering.
readDefinition(dir)Read a definition directory into raw parts (JSON parsed, body files as source strings) — the shared input both generators build from.