`gbrgames draft -name <game> -image <image> [-steam-app ID] [-first-boot report.json]` has a model write games/<id>/game.yaml and test.yaml, then checks them like any template and sends problems back for up to three fix rounds. Ollama (default qwen3.8:27b, OLLAMA_URL) or Gemini (GEMINI_API_KEY). The model gets AUTHORING.md (new: the house rules, from how nodes really run servers and today's bugs: x-generate passwords, no published RCON ports, containerUser, heap below the limit, env var naming, ready lines), the inspect-image facts, the first-boot report and the two smallest templates as examples. With Ollama the answer is forced into the template schema, tightened for drafts so ports, install config, settings and their descriptions can't be left out or null. On top of validation and the image checks, drafts must: - be complete: player ports, >=3 settings each described, real memory, a readyPattern or settleSec - name settings so they reach the container as variables the image reads (ServerPassword -> SERVER_PASSWORD when the image reads SERVER_PASS) - not leave files first boot saw outside /server (lost on every start) A first boot showing the image dies within seconds on permission errors (it needs root) stops the draft before any model call. A missing readyPattern is filled from first boot's verified suggestion. Valheim, which we have no template for: lloesche/valheim-server was rejected as root-only; via SteamCMD (app 896660) qwen3.8:27b on a local 3090 Ti wrote a passing template in two rounds (~1 min). It is about 70% there: it chose "--save-dir /server", which Valheim doesn't have (-savedir), and missed -crossplay and 2457/udp. The save check is a text check; booting the draft itself is the next step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.8 KiB
Go
50 lines
1.8 KiB
Go
// Command gbrgames validates the game templates in this repo and imports them from a panel export.
|
|
//
|
|
// go run ./cmd/gbrgames validate # check every games/<id>/game.yaml (+ test.yaml)
|
|
// go run ./cmd/gbrgames import export.json # write games/<id>/ from GET /api/v1/admin/games
|
|
// go run ./cmd/gbrgames export -out p.json # build the games_published payload CI sends to the panel
|
|
// go run ./cmd/gbrgames boottest-payload ID # build the deploy message the node-agent's BootTest runs
|
|
// go run ./cmd/gbrgames inspect-image -game ID # read the image's facts and check the template against them
|
|
// go run ./cmd/gbrgames first-boot -game ID # start the server once, untouched; record its log and files
|
|
// go run ./cmd/gbrgames draft -name N -image I # have an AI model write a new game's template from those facts
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
usage()
|
|
}
|
|
var err error
|
|
switch os.Args[1] {
|
|
case "validate":
|
|
err = runValidate(os.Args[2:])
|
|
case "import":
|
|
err = runImport(os.Args[2:])
|
|
case "export":
|
|
err = runExport(os.Args[2:])
|
|
case "boottest-payload":
|
|
err = runBootTestPayload(os.Args[2:])
|
|
case "inspect-image":
|
|
err = runInspectImage(os.Args[2:])
|
|
case "first-boot":
|
|
err = runFirstBoot(os.Args[2:])
|
|
case "draft":
|
|
err = runDraft(os.Args[2:])
|
|
default:
|
|
usage()
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "error:", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func usage() {
|
|
fmt.Fprintln(os.Stderr, "usage: gbrgames validate [-games DIR] | import [-games DIR] [-all] EXPORT.json | export [-repo R] [-commit SHA] [-out FILE] | boottest-payload [-out FILE] ID | inspect-image [-game ID] [-json] [-no-pull] [IMAGE] | first-boot [-game ID | -image IMAGE] [-env K=V] [-max D] [-quiet D] [-out DIR] | draft -name NAME -image IMAGE [-steam-app ID] [-first-boot REPORT] [-provider ollama|gemini] [-model M]")
|
|
os.Exit(2)
|
|
}
|