Skip to main content

Hyveon

A cost-efficient, multi-game dedicated server platform on AWS Fargate with a local management UI and a fully serverless Discord bot. Servers only run — and only cost money — while somebody is playing; the rest of the time the account is silent except for a handful of near-free Lambdas.

What you get​

  • On-demand Fargate tasks per game (no persistent ECS service, no idle cost).
  • EFS with per-game access points so each world is isolated yet persistent.
  • Auto-DNS — a Lambda UPSERTs {game}.{yourdomain} on task start and DELETEs it on stop. HTTPS-fronted games terminate TLS via an in-task Caddy sidecar (Let's Encrypt automatic HTTPS) that proxies 443 to the game's declared web port, and any additional ports stay reachable per their visibility — no load balancer or ACM certificate for game traffic. (The Discord custom domain is separate: it fronts a Lambda Function URL with CloudFront and does use an ACM certificate — see Infra program.)
  • Watchdog Lambda that stops servers after a configurable idle window.
  • Packaged Electron desktop app (Nest.js backend + React dashboard) to start/stop, edit config, stream logs, and track costs — no HTTP server, the renderer talks to the backend over Electron IPC.
  • Serverless Discord bot — two Node.js Lambdas plus DynamoDB and Secrets Manager handle every slash command; no 24/7 bot process.
  • Six Lambda packages, four always deployed. interactions, followup, update-dns, and watchdog are always deployed. Two are conditional: health-check is provisioned once, shared across games, when at least one game declares a healthCheck; @hyveon/lambda-efs-seeder is deployed once per game that declares file_seeds — zero, one, or many instances, never a fixed count.

Choose your path​

The rest of the site is organised around three roles. Pick the one that matches what you're doing right now:

  • Setup guide — from a blank AWS account to a running game server, in order.
  • Install — per-OS steps to get the packaged app running, including getting past the unsigned-build warning (see the code-signing roadmap for the plan to change that).
  • User guide — day-to-day operation: starting/stopping servers from the dashboard or Discord, reading the cost panel, checking logs.
  • Maintainer guide — working on the code: monorepo layout, tests, lint, CI, release/deploy mechanics, load-bearing invariants not to break.

Component reference​

Deep-dives on each piece, for when the guides hand-wave past something:

  • Architecture overview — the diagram below in full, with every arrow annotated.
  • Infra program — the Pulumi Automation API program: every file, resource, and AWS service touched.
  • Management app — the Nest.js API, React dashboard, and @hyveon/shared library.
  • Lambdas — the six Node.js Lambda packages (interactions, followup, update-dns, watchdog, health-check, efs-seeder — the last two are conditional).

High-level architecture​

High-level architecture

The desktop app's first-run wizard bootstraps AWS from a blank account — no separate CLI tool to install or run. After that, the control plane is the dashboard, the Discord bot, or EventBridge schedules. No persistent server process — only the Fargate tasks themselves cost money, and only while they're running.

For the full breakdown (Discord bot internals, control-loop Lambdas, and the /server-start sequence) see the architecture overview.

Repository map​

The repository root is the npm-workspaces root — one package.json at the top installs every workspace below in a single npm install.

Hyveon/
├── app/ # Electron desktop app (Nest.js + React)
│ └── packages/
│ ├── shared/ # @hyveon/shared
│ ├── cloud-aws/ # @hyveon/cloud-aws — AWS implementations of the cloud-agnostic contracts
│ ├── desktop-main/ # @hyveon/desktop-main (Nest.js IPC microservice)
│ ├── desktop-preload/ # @hyveon/desktop-preload — contextBridge preload script (window.hyveon)
│ ├── infra/ # @hyveon/infra — Pulumi Automation API program (all AWS resources)
│ ├── web/ # @hyveon/web (React + Vite renderer)
│ └── lambda/
│ ├── interactions/ # Discord Function URL entry point
│ ├── followup/ # async ECS work + Discord PATCH
│ ├── update-dns/ # Route 53 on task state change
│ ├── watchdog/ # idle detection + auto-stop
│ ├── health-check/ # conditional, shared — provisioned when any game declares healthCheck
│ └── efs-seeder/ # conditional, per game — writes declarative file_seeds to a game's EFS volume
├── build/ # icon source art + generator for packaging
├── docs/ # this site
├── electron.vite.config.ts # electron-vite build config (main/preload/renderer)
├── electron-builder.yml # packaged-installer config
└── README.md