Client

The client is the Gamehoster code that runs on your machine. Two things live in its source tree. The tools client is the one command you run on a timer: it generates each game to static code and syncs it to the server, and it builds the local browser tools. The browser runtime is the game library baked into each game's page — the same engine the server runs, for prediction — covered in depth on the Frontend page. The source is in layers: client/, this hoster's own modules; common/, the shared toolkit every hoster's client is built from; and the server's generate.js, which the sync drives at build time. This page is the file map — every file, then a section giving its exports, or, for the command you run, its switches.

client/                           this hoster's own modules
  gamehoster-tools.js              the one command you run (tools entry point)
  sync.js                          generate + push game definitions to the server
  browse/
    game.js                        build the Game Logs browser
  gamehoster-client.js             the browser game runtime (baked per game — see Frontend)
  rollback.js                      the browser prediction core (bundled into the library)
common/                           the shared toolkit, common to every hoster
  net.js                           config, TLS and API-version plumbing
  client/
    run.js                         the orchestrator every hoster's client runs
  browse/
    web.js                         build the Web Logs browser
    server.js                      build the Server Logs browser
    pull-logs.js                   mirror the access logs down
    pull-stats.js                  mirror the server stats down
    shell.js                       the page frame: strip, tabs, status, stylesheet
    ui.js                          the UI kit: cards, tables, charts, pagination
    format.js                      shared formatters (esc, bytes, dates)
    io.js                          small render/IO helpers
server/                           the generator the sync drives (see Server)
  generate.js                      compile a definition to static server + client code
  engine.js · schema.js · loader.js the runtime it reuses and bundles for the browser
The client source: this hoster's modules and browser runtime, the shared toolkit, and the generator it drives at sync.

Files

FileWhat it does
client/ — this hoster's modules
client/gamehoster-tools.jsThe single command you run for the server tools. Declares the tool set and the sync hook, then hands off to the shared orchestrator.
client/sync.jsGenerates each game to static code, then diffs the games root against the server by content hash and pushes only the differences.
client/browse/game.jsReads the game definitions and renders the browsable Game Logs map — every game, organised by domain.
client/gamehoster-client.jsThe browser game runtime: opens the socket and drives a local simulation. Baked into each game's library; detailed on Frontend.
client/rollback.jsThe client-side rollback core the runtime is built on: fold server updates, re-simulate for prediction and reconciliation.
common/ — the shared toolkit
common/net.jsReads the config, skips cert verification for a bare-IP endpoint, and discovers the server's API version.
common/client/run.jsThe orchestrator core every hoster's client runs: arg parsing, config, the tool loop, and the tools-site frame.
common/browse/web.jsRenders the static Web Logs browser from the mirrored Caddy access logs.
common/browse/server.jsRenders the static Server Logs browser from the mirrored server statistics, drilling month → minute.
common/browse/pull-logs.jsMirrors the server's access logs down incrementally (rotated files once, the active log by Range).
common/browse/pull-stats.jsMirrors the server's statistics day-files down incrementally, the stats counterpart of pull-logs.
common/browse/shell.jsThe shared page frame: the top strip, tool tabs, per-tool status banner, and stylesheet.
common/browse/ui.jsThe shared UI kit a browser composes: stat cards, tables, chart/table toggles, and pagination.
common/browse/format.jsThe canonical formatters: escaping, numbers, bytes, durations, and month/day labels.
common/browse/io.jsSmall render/IO helpers, chiefly the footer-stripping used by the write-if-changed comparison.
server/ — the generator the sync drives
server/generate.jsCompiles a game definition to a static server module and a front-end library, inlining every body as a real function. Runs on your machine at sync; detailed on Server.

client/gamehoster-tools.js — entry point

The single thing you run for the server tools, and the only file with no exports. It declares Gamehoster's tools — the two universal browsers (Web Logs, Server Logs) from the shared toolkit plus the project's own Game Logs — and its content (sync) hook, then hands off to the shared orchestrator in common/client/run.js. The sync hook shells out to sync.js, so content is generated and pushed before the tools browsers render it. (It is distinct from gamehoster-client.js, the browser game runtime — same folder, different job.)

SwitchWhat it does
--config <path>, -cPath to the client config JSON. Defaults to ./config.json.
--syncGenerate 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.

client/sync.js

The sync client. Each run it first generates every game — regenerating its static gamehoster.server.js and gamehoster.client.js from the definition (via generate.js, reading 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. Importable (the exports below, used by the unified client) and runnable on its own (node client/sync.js --config <path>), including a --watch loop. The full protocol is the Sync page.

ExportWhat it is
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 this client 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.

Standalone switches: --config <path> / -c, --dry-run, --verbose / -v, and --watch / -w with --interval <seconds> (default 30) to loop.

client/browse/game.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.

client/gamehoster-client.js — browser runtime

The browser game client. It connects to the game socket, drives a local simulation that runs the world at the game's tick rate, predicts your own commands the instant you send them, and reconstructs everyone else from the server's per-player delta updates. It is not a Node module: it defines Gamehoster.connect on the page. At sync, generate.js bakes this file — together with the bundled engine — into each game's gamehoster.js library with that game's config and predictors as a preset. The whole prediction model is the Frontend page.

GlobalWhat it is
Gamehoster.connect(game, join, opts)Open a game socket and return a connection: onReady, send(type, params) (predicted at once), frame() (the reconstructed view for rendering), latest(), auth(id), and close().

client/rollback.js

The client-side rollback core, shared by the browser runtime (where the engine is baked in) and Node tests. It keeps a client-mode World, folds in the server's per-player delta updates (a keyframe plus the broadcast command log), and each frame re-simulates from the last authoritative keyframe up to the local leading tick — real commands where known, predicted commands for the ticks not yet received. That single re-simulation is prediction and reconciliation at once. The Instance and Frontend pages are that mechanism in full.

ExportWhat it is
ClientSimThe prediction simulation: onUpdate (fold a server delta), send (predict an own command), advance (step the leading edge), and render (the eased view). Bundled into the library beside the engine.

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 client 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 client 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.

common/client/run.js

The hoster-tools orchestrator core — the shared engine every hoster's client runs. A project calls run({ tools, sync, brand }); this owns arg parsing, config and TLS, the isolated phase loop, and the whole tools-site frame (overview cards, per-tool pages, clash-safe "not run" status, persisted last-run state). The two universal tools come ready-made from webTool()/serverTool(), so Gamehoster's entry is a short declaration plus its Game Logs tool and sync hook.

ExportWhat it is
run(opts)The entry a project calls with { tools, sync, brand }: parse args, run the sync hook and every enabled tool, and write the tools site.
webTool()The ready-made Web Logs tool descriptor (pull the access logs, then build the browser).
serverTool()The ready-made Server Logs tool descriptor (pull the stats, then build the browser).

common/browse/web.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 client passes { logsDir, outDir }; run standalone it reads the log dir beside the script.

common/browse/server.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 client passes { dataDir, outDir, serverIp }; run standalone it reads the data dir beside the script.

common/browse/pull-logs.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.

common/browse/pull-stats.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.

common/browse/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.

common/browse/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.

common/browse/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.

common/browse/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.

server/generate.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 schema helpers, the engine and rollback inlined into one IIFE. 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 runtime bundle plus the client base plus this game's baked preset.
readDefinition(dir)Read a definition directory into raw parts (JSON parsed, body files as source strings) — the shared input both generators build from.