No description
  • TypeScript 63.8%
  • Vue 28.6%
  • CSS 6.4%
  • HTML 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Tronax b158279e8a
docs: README with logo, badges, architecture guide and roadmap
Full English README for the project:

- brand logo, shields.io badges (Vue, TypeScript, Vite, Pinia, Tailwind,
  Vitest, license, save target) and a gameplay screenshot above the fold
- feature overview of the Phase 1 vertical slice
- tech stack table and getting-started guide with a script reference
- project structure tree with per-directory intent
- architecture notes: pure engine layer vs. Pinia stores, fully derived
  persisted state, acyclic store graph, ticks vs. away-time handling,
  versioned save envelope with sanitising imports
- the core game math (geometric costs, thermal throttling, offline
  progress) and a pointer to the tuning constants
- phased roadmap (operations/hyperscale) noting that the TechUpgrade
  schema and later-phase hardware already exist in the catalog
- screenshot pair contrasting the overheated and cooled basement states
2026-10-02 15:02:39 +02:00
.vscode chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
docs docs: README with logo, badges, architecture guide and roadmap 2026-10-02 15:02:39 +02:00
public chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
src feat(ui): metrics dashboard, 42U rack view, supply depot and offline modal 2026-10-02 15:02:37 +02:00
.gitignore chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
index.html chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
LICENSE chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
package-lock.json chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
package.json chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
README.md docs: README with logo, badges, architecture guide and roadmap 2026-10-02 15:02:39 +02:00
tsconfig.json chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00
vite.config.ts chore: scaffold Vue 3 + Vite + TypeScript project shell 2026-10-02 15:01:09 +02:00

ServerFarm Architect logo

ServerFarm Architect

An idle tycoon game about building a basement rack into a hyperscale data center.

Start with one 42U rack, a modest grid hookup and an open window for cooling — buy servers, keep them powered and cooled, automate the chaos, and scale all the way to an IPO.

Vue 3 TypeScript Vite Pinia Tailwind CSS Vitest License: MIT Saves

Gameplay screenshot: a healthy 4-node basement farm running at 100% efficiency


About

ServerFarm Architect is a browser-based incremental/idle game. You earn cash by fulfilling compute workloads; every dollar can be reinvested into more servers, better cooling, or beefier power infrastructure. The simulation is honest: nodes draw real watts, dump real heat, and go offline when the grid runs dry.

Phase 1 (this repository) is a playable vertical slice: one 42U rack, the full power → heat → cooling → throttle → income loop, buy-max economics, and a versioned save system with offline progress.

Features (Phase 1)

  • Live 42U rack — servers slot in bottom-up with blinking status LEDs: 🟢 online · 🟡 heat-throttled · 🔴 unpowered. Multi-U chassis span their rows correctly.
  • Coupled resource simulation — compute (TFLOPS) earns cash, but every node draws power (W) and dumps heat (Wt). Cooling hardware competes with compute for the same grid.
  • Thermal throttling — saturate your cooling and revenue efficiency falls to max(0.2, cooling / heat) while the room temperature gauge climbs.
  • Geometric cost scaling — every purchase gets 15% pricier, with closed-form bulk pricing powering the ×1 / ×10 / Max buttons at O(1).
  • Fixed-step tick engine — 10 simulation ticks per second on requestAnimationFrame, decoupled from render rate; identical game speed on a 60 Hz and a 144 Hz monitor.
  • Offline progress — close the tab, come back tomorrow: away time is credited at 50% efficiency, capped at 24 h, and reported in a welcome-back dialog. Hidden-tab gaps are caught up automatically.
  • Robust saves — versioned localStorage envelope, autosave every 10 s plus saves on purchase/tab-hide/unload, and sanitising imports that survive corrupt or partially invalid save data.
  • Unit-tested math — the entire formula layer (cost scaling, efficiency, offline earnings, save round-trips) is covered by Vitest.

Tech stack

Layer Choice
Framework Vue 3 — Composition API, <script setup>
Bundler / dev server Vite 8
Language TypeScript 5.9 (strict, verbatimModuleSyntax)
State Pinia 4 (setup stores, hand-rolled versioned persistence)
Styling Tailwind CSS 4 (CSS-first @theme, dark cyberpunk design system)
Icons lucide-vue-next
Tests Vitest

Getting started

# Prerequisites: Node.js 22+ (20.19+ works) and npm
npm install
npm run dev        # → http://localhost:5173
Script What it does
npm run dev Start the Vite dev server with HMR
npm run build Type-check (vue-tsc) then bundle for production
npm run preview Serve the production build locally
npm run typecheck Run vue-tsc --noEmit only
npm run test Run the unit test suite once
npm run test:watch Run Vitest in watch mode

The game autosaves to localStorage under the key serverfarm-architect:save. The footer's Wipe save button (guarded by a confirm dialog) resets to a fresh basement.

Project structure

src/
├── engine/            # Pure TypeScript — no Vue, no Pinia, fully unit-tested
│   ├── constants.ts   #   every tunable balance value in one commented table
│   ├── formulas.ts    #   cost scaling, thermal efficiency, offline earnings
│   ├── ticker.ts      #   fixed-timestep GameTicker on requestAnimationFrame
│   ├── save.ts        #   versioned save envelope + SaveManager
│   ├── format.ts      #   number/money/watts/duration formatting
│   └── *.test.ts      #   Vitest suites for the formula and save layers
├── types/
│   └── models.ts      # Strict schemas: ServerNode, Rack, CoolingUnit,
│                      # PowerSource, TechUpgrade, reports
├── data/
│   └── hardware.ts    # Static hardware catalog (servers/cooling/power)
├── stores/            # Pinia
│   ├── datacenter.ts  #   infrastructure state + all derived metrics
│   └── economy.ts     #   money ledger (leaf store, dependency-acyclic)
├── composables/
│   └── useGameLoop.ts # Boot conductor: hydrate → offline audit → tick → save
├── components/
│   ├── MetricsDashboard.vue
│   ├── RackView.vue
│   ├── ShopPanel.vue
│   ├── OfflineProgressModal.vue
│   └── ui/CapacityBar.vue
├── App.vue
├── main.ts
└── style.css          # Tailwind v4 theme + dark data-center design system

Architecture notes

  • The engine is pure. src/engine/ imports nothing from Vue or Pinia. Every formula is a side-effect-free function, which makes the balance math trivially testable and portable (e.g. into a Web Worker later).
  • Stores derive everything. Only instance lists (racks, servers, cooling units, power sources) are persisted. Power allocation, heat load, slot occupancy, income — all are computed getters, so the save file can never contradict the simulation.
  • Acyclic store graph. economy is a leaf; datacenter → economy is the only cross-store edge. The game loop injects the income rate into the economy tick.
  • Ticks vs. away-time. The GameTicker simulates fixed 100 ms steps while the page is visible. Frame gaps beyond 5 s (hidden tab, suspended laptop) are routed through the same offline calculator used at boot — no tick storms, no double simulation.
  • Saves are versioned. SaveManager wraps contributors in a { version, savedAt, contributors } envelope; unknown versions are discarded with a warning, ready for future migrations. Store imports sanitise aggressively (unknown catalog ids, slot collisions, junk numbers).

The core math

Hardware cost (per stack, N = units already owned):

cost(next)       = baseCost × growth^N            (growth = 1.15 by default)
cost(count)      = baseCost × growth^N × (growth^count − 1) / (growth − 1)
maxAffordable(N) = ⌊ log( budget × (growth − 1) / baseCost×growth^N + 1 ) / log growth ⌋

Thermal throttling (from the design spec):

efficiency = heat ≤ cooling ? 1 : max(0.2, cooling / heat)
income     = Σ powered nodes' TFLOPS × $5/TFLOPS × efficiency

Offline progress (boot-time audit and hidden-tab catch-up):

credited = min(elapsed, 24 h)
earned   = incomePerSec × credited × 0.5

All constants (tick rate, offline cap, baseline grid/cooling/bandwidth, market rate, throttle floor, starting cash) live in src/engine/constants.ts with commentary.

Roadmap

Phase Scope
1 — Basement ✅ Single 42U rack, power/heat/cooling loop, offline progress, saves
2 — Operations Tech tree & research points, sysadmin/NOC staff, random incidents (drive failure, DDoS, power spike) with manual → automated resolution, additional racks & halls, redundancy mechanics for UPS/generators, bandwidth as a real bottleneck
3 — Hyperscale Prestige "Data Center Relocation / IPO" trading infrastructure for permanent Venture Capital multipliers, GPU/immersion endgame hardware, longevity & wear

The TechUpgrade schema and phase-2/3 hardware entries already exist in the catalog and type layer — later phases plug into them.

Screenshots

Overheated basement Cooled & healthy
Throttled: amber LEDs, 51.6 °C, 29% efficiency Healthy: green LEDs, 26.7 °C, 100% efficiency

License

MIT © 2026 Tronax