Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
d251c44
Initial commit
clouths Sep 26, 2026
36eccbe
Wiki implementation: all pages, templates, static assets
clouths Sep 26, 2026
236f677
Standalone wiki repo: generator, Makefile, CI
clouths Sep 26, 2026
f4c4ba9
Fix search: bind after DOM ready, Enter follows top result
clouths Sep 26, 2026
2a7629f
Content: ingest community wiki + terminology refactor
clouths Sep 26, 2026
bba6d4f
UI: branding, accent palettes, search shortcuts, home videos, footer
clouths Sep 26, 2026
c370853
Content: robot model icons + license footer
clouths Sep 26, 2026
c46ff55
UI: two-stop palette backgrounds, colorblind modes, a11y, footer fix
clouths Sep 26, 2026
0be7fe7
Content: feature-page images, Scarab icon, tier-ordered catalog
clouths Sep 26, 2026
55370da
UI: flex layout, menu icons, YouTube link, i18n-ready chrome
clouths Sep 26, 2026
2b4bc33
UI: shop category pages, full-height sidenav, current-page selection
clouths Sep 26, 2026
b72b035
UI: pinned sidenav, outline icons, language menu, category overview p…
clouths Sep 26, 2026
ee6214a
Remove community-wiki art assets; add shared placeholder icon
clouths Sep 27, 2026
e8312c5
UI + content: engineering numbers, CT diagram order, tech tree pages,…
clouths Sep 27, 2026
31f5b25
Add player-facing stat reference page (/content/stat-reference/)
clouths Sep 27, 2026
ac244fd
Static client display names (no GBF archive needed) + stale-page cleanup
clouths Sep 27, 2026
731dc4c
Add wiki backlog (recreated in the wiki repo)
clouths Sep 27, 2026
9f110b6
Sidenav: restore always-open categories (no collapsible groups)
clouths Sep 27, 2026
ce75a46
Lock the target category tree (structure only, no backup ingestion)
clouths Sep 27, 2026
d95fc10
Sidenav: keep scroll across navigation, always show the current entry
clouths Sep 27, 2026
6d95931
Sidenav: drop the duplicate Zone map row from Data reference
clouths Sep 27, 2026
7a14e1b
Sidenav: Zone map is now a full category heading like the others
clouths Sep 27, 2026
284dc85
License: switch to Apache-2.0 (all adapted pages rewritten)
clouths Sep 27, 2026
3b9b3f9
Zones: one page per zone + per-zone teleport maps; world map rename; …
clouths Sep 28, 2026
409adc8
Ores: one dedicated page per ore type
clouths Sep 28, 2026
024fde9
Generation: PerpetuumServer2 as a git submodule (server/)
clouths Sep 28, 2026
1b9b69f
Regenerate content from the live database
clouths Sep 28, 2026
53d5eb8
CI: run the build check on pull requests
clouths Sep 28, 2026
cf16144
CI: extract Zola to the workspace, not /usr/local
clouths Sep 28, 2026
04c837e
CI: export PATH within the install step too
clouths Sep 28, 2026
c674a48
CI: correct the zola build invocation for 0.23
clouths Sep 28, 2026
4fb3247
CI: pin actions to SHAs via ratchet, lint pins in workflow
clouths Sep 28, 2026
0a34284
CI: add CodeQL SAST job (C# generator + JS)
clouths Sep 28, 2026
b6d9219
CI: split CodeQL into per-language jobs; add ratchet pin-check job
clouths Sep 28, 2026
0939c33
CI: fix ratchet checksum path (sha512sum -c is CWD-relative)
clouths Sep 28, 2026
539735a
Nav: high-level 4-group menu with prominent All-features link
clouths Oct 1, 2026
3478ff5
Nav: fix caret buttons (JS syntax error) and collapse sub-sub lists
clouths Oct 1, 2026
9f37071
Fixes: mermaid state-diagram labels (broken parse + silent \n)
clouths Oct 1, 2026
53aebbd
Tests: Playwright suite (mermaid syntax + sidenav) with CI job
clouths Oct 1, 2026
ff0d83f
chore: ignore Playwright output dirs
clouths Oct 1, 2026
04b2d91
Nav: Home as 1st item, World top-level below it
clouths Oct 1, 2026
80d2aff
Nav: groups open by default; World 2nd item; All features in Reference
clouths Oct 1, 2026
a1fb940
Nav: auto-open the sub-list containing the current page
clouths Oct 1, 2026
7b73d19
Nav: extend sub-lists + auto-open rule to Content tables and Zones
clouths Oct 1, 2026
9d98901
Nav: highlight the clicked same-page anchor, not its parent entry
clouths Oct 1, 2026
6ee95ea
Nav: selection box spans the whole row, ending after the caret
clouths Oct 1, 2026
175671c
Layout: fill the available width on wide screens
clouths Oct 1, 2026
bfcf3e7
Nav: sync the menu on same-page hash navigation + scroll tests
clouths Oct 1, 2026
1629180
Map: fix wheel-zoom/pan never attaching (map.js ran before the DOM)
clouths Oct 1, 2026
d8f16ad
Map: sane zoom bounds + correct zoom anchor
clouths Oct 1, 2026
6daadbc
Map: allow panning into empty space (25% of viewport stays covered)
clouths Oct 1, 2026
28d8c8c
Zone teleport maps: procedural background + clickable teleports
clouths Oct 2, 2026
e7807f6
Footer: add the Facebook link
clouths Oct 2, 2026
b785c97
Un-track memory.md (local work notes, keep it out of the repo)
clouths Oct 2, 2026
781bffe
Detect a new deployment while a page is open (update toast)
clouths Oct 2, 2026
ea7eb26
Missions: make reward item links real anchors
clouths Oct 2, 2026
a61b463
Layout: two-row topbar, content aligned with the footer, mobile drawer
clouths Oct 2, 2026
727a11c
Zone maps: real terrain from the game's layer files, with display modes
clouths Oct 2, 2026
862b34d
Diagrams: zoom/pan for mermaid diagrams (pie charts stay static)
clouths Oct 2, 2026
6497335
Mobile: line the content panel up with the footer
clouths Oct 2, 2026
e76f84e
Zone maps: roads, 512px terrain, bigger labelled POIs, drop Plain mode
clouths Oct 2, 2026
705ba4f
Zone maps: build terrain from fetched game data in CI
clouths Oct 2, 2026
9da2549
Diagrams: pie charts display without the zoom/pan interactivity
clouths Oct 2, 2026
a2241db
World & play: character page, category recipe cards, production trees…
clouths Oct 2, 2026
b17b4c9
World & play: extension category cards, production trees on item page…
clouths Oct 3, 2026
90d53a3
Maps & extensions rework: zone maps under title, real terrain world m…
clouths Oct 3, 2026
7fc7b68
Maps & sparks rework: Alpha rename, coastline world map with gradient…
clouths Oct 3, 2026
8676471
Sparks: remove the vertical connection tree section
clouths Oct 3, 2026
f54a96e
Tiers: show T1–T4 in the game's convention and link each item's tier …
clouths Oct 3, 2026
79753a6
recipes_data.json: back to the generator's compact format
clouths Oct 3, 2026
865c8d0
Wiki rework: tech tree lines, spark families, tier names, production …
clouths Oct 3, 2026
75b0dfc
World map + zones rework: real TP anchors, hover-reveal lines, family…
clouths Oct 3, 2026
12a8296
World map: fix upside-down orientation, drop TP-less zones; home page…
clouths Oct 3, 2026
5527a97
Topbar: one row on desktop (search + icons right), centered content c…
clouths Oct 3, 2026
97db422
Topbar: search visible at every width, mobile chrome buttons in the d…
clouths Oct 3, 2026
6340e17
World map: pre-zoom, labels above zones, OP Wiki brand, thumb rework
clouths Oct 4, 2026
102bafa
Maps: cursor-anchored zoom, zone-map exit lines + contrast, nav move
clouths Oct 4, 2026
8f32705
Restructure nav (Start/World/Play/Systems) and add Play/Dev mode toggle
clouths Oct 4, 2026
158b108
TP destination selector, world-map cards, nav rework
clouths Oct 4, 2026
8ae368e
Zone index cards + TP-filter, selector display names, tier highlight,…
clouths Oct 4, 2026
8778168
Fix CI: generate fallback thumbnails for ALL no-SVG zones, not just w…
clouths Oct 4, 2026
bb1552a
Dev mode: the menu shows ONLY the Dev group
clouths Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
199 changes: 199 additions & 0 deletions .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Builds the Zola static site and deploys it to GitHub Pages.
# Generated markdown is committed to git, so this build needs no database.

name: Wiki

on:
push:
branches: ["main"]
pull_request:
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write
security-events: write

concurrency:
group: "wiki"
cancel-in-progress: true

env:
ZOLA_VERSION: v0.23.6

jobs:
ratchet:
name: Ratchet (action pins)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # ratchet:actions/checkout@v4

- name: Download ratchet (pinned release)
run: |
set -euo pipefail
curl -sSfL -o /tmp/ratchet.tar.gz \
"https://github.com/sethvargo/ratchet/releases/download/v0.12.0/ratchet_0.12.0_linux_amd64.tar.gz"
echo "0d14cb829d3f5068454402f8198b0d9a29b776c8a070ef3f7e7bbb4f53d16aa15309f8e5042cbb3330b2d415b3c058ef269be946cc267098e2e4ad8a75fa1b5c /tmp/ratchet.tar.gz" | sha512sum -c -
tar xzC /tmp -f /tmp/ratchet.tar.gz

- name: Lint pins
run: /tmp/ratchet lint .github/workflows/wiki.yml

- name: Check pins match their tags
# Resolves the # ratchet: constraints and diffs against the committed
# file: fails when a pinned SHA no longer matches its tag (tag moved
# upstream or was re-pointed). Fix by running 'ratchet update' locally.
run: |
/tmp/ratchet update -out /tmp/wiki.updated.yml .github/workflows/wiki.yml
if ! diff -u .github/workflows/wiki.yml /tmp/wiki.updated.yml; then
echo "::error::Pinned action versions have drifted from their tags. Run 'ratchet update .github/workflows/wiki.yml' and commit the result."
exit 1
fi

sast-csharp:
name: SAST (CodeQL, C#)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # ratchet:actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@1190a975f95ce23525efb6a3fc21ea29567c1b52 # ratchet:github/codeql-action/init@v3
with:
languages: csharp
build-mode: manual
config-file: ./codeql-config.yml

- name: Build generator (.NET)
run: dotnet build generator/Perpetuum.WikiGenerate/Perpetuum.WikiGenerate.csproj -c Release

- name: Analyze
uses: github/codeql-action/analyze@1190a975f95ce23525efb6a3fc21ea29567c1b52 # ratchet:github/codeql-action/analyze@v3

sast-js:
name: SAST (CodeQL, JS)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # ratchet:actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@1190a975f95ce23525efb6a3fc21ea29567c1b52 # ratchet:github/codeql-action/init@v3
with:
languages: javascript-typescript
config-file: ./codeql-config.yml

- name: Analyze
uses: github/codeql-action/analyze@1190a975f95ce23525efb6a3fc21ea29567c1b52 # ratchet:github/codeql-action/analyze@v3

test:
name: Tests (Playwright)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # ratchet:actions/checkout@v4

- name: Cache game layer data (zone map terrain)
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4
with:
path: .assets
key: wiki-zone-layers-v1

- name: Fetch game layer data + generate zone map terrain
# The zone map PNGs are not committed; they are generated here from
# the game's layer data (fetched by tools/fetch_zone_layers.sh —
# Steam dedicated server + the public gamma Drive archive). Zones
# whose layers only ship in the game client keep their committed
# derived PNGs from static/zonemaps-fallback/ (handled by the tool).
run: |
if ! command -v 7z >/dev/null; then
sudo apt-get update && sudo apt-get install -y p7zip-full
fi
bash tools/fetch_zone_layers.sh .assets
OP_ASSETS_DIR="$PWD/.assets" python3 tools/gen_zone_teleport_maps.py

- name: Install Zola
# The runner is non-root, so extract to the workspace, not /usr/local.
run: |
mkdir -p "$GITHUB_WORKSPACE/tools"
curl -sSfL -o /tmp/zola.tar.gz "https://github.com/getzola/zola/releases/download/${ZOLA_VERSION}/zola-${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
tar xzC "$GITHUB_WORKSPACE/tools" -f /tmp/zola.tar.gz
export PATH="$GITHUB_WORKSPACE/tools:$PATH"
echo "$GITHUB_WORKSPACE/tools" >> "$GITHUB_PATH"
zola --version

- name: Build
run: zola build --force -o public

- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # ratchet:actions/setup-node@v4
with:
node-version: 22

- name: Install test dependencies
run: npm ci

- name: Install Chromium
run: npx playwright install --with-deps chromium

- name: Run tests
run: npm test

build:
name: Build (Zola)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # ratchet:actions/checkout@v4

- name: Cache game layer data (zone map terrain)
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4
with:
path: .assets
key: wiki-zone-layers-v1

- name: Fetch game layer data + generate zone map terrain
run: |
if ! command -v 7z >/dev/null; then
sudo apt-get update && sudo apt-get install -y p7zip-full
fi
bash tools/fetch_zone_layers.sh .assets
OP_ASSETS_DIR="$PWD/.assets" python3 tools/gen_zone_teleport_maps.py

- name: Install Zola
# The runner is non-root, so extract to the workspace, not /usr/local.
run: |
mkdir -p "$GITHUB_WORKSPACE/tools"
curl -sSfL -o /tmp/zola.tar.gz "https://github.com/getzola/zola/releases/download/${ZOLA_VERSION}/zola-${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
tar xzC "$GITHUB_WORKSPACE/tools" -f /tmp/zola.tar.gz
# GITHUB_PATH applies from the next step on; export PATH for this step.
export PATH="$GITHUB_WORKSPACE/tools:$PATH"
echo "$GITHUB_WORKSPACE/tools" >> "$GITHUB_PATH"
zola --version

- name: Build
# Zola 0.23 builds from the current directory (no -d flag); the
# default working directory is the repo root where config.toml lives.
run: zola build --force -o public

- name: Upload artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # ratchet:actions/upload-pages-artifact@v3
with:
path: ./public

deploy:
name: Deploy to GitHub Pages
# Deploys only from main (pull_request runs build-only, so PR checks
# never touch the Pages environment).
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # ratchet:actions/deploy-pages@v4
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public/
node_modules/
test-results/
playwright-report/
memory.md
generator/**/bin/
generator/**/obj/
tools/__pycache__/
static/zonemaps/*/
.assets/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "server"]
path = server
url = https://github.com/OpenPerpetuum/PerpetuumServer2.git
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Expand Down
95 changes: 95 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Open Perpetuum Wiki — build tooling.
#
# make build build the static site into public/ (Docker, pinned Zola image)
# make serve local live-reload server on :8085 (Docker; override WIKI_PORT=NNNN)
# make test build + run the Playwright browser tests (needs node +
# npm install; CHROMIUM_PATH=... to skip the Playwright
# Chromium download)
# make zonemaps regenerate the zone teleport maps: real terrain from the
# game's layer data (fetched when no local checkout exists)
# + clickable teleports (pure-stdlib Python, no database)
# make generate regenerate the generated content pages from the database
# make clean remove the build output
#
# The site build (build/serve) never needs a database: the generated markdown is
# committed to git. `make generate` is only needed when the database content
# changes; it requires the .NET 8 SDK and a reachable game database.

ZOLA_IMAGE := ghcr.io/getzola/zola:v0.23.6
PYTHON_IMAGE := python:3.12-slim
WIKI_PORT ?= 8085

# Generator inputs (make generate).
# WIKI_DB SQL Server connection string (falls back to $PERPETUUM_CONNECTIONSTRING)
# WIKI_PLANTRULES directory containing the plant rule files; defaults to the
# server submodule (run `git submodule update --init server` first)
WIKI_DB ?= $(PERPETUUM_CONNECTIONSTRING)
# ?= would not override an empty WIKI_PLANTRULES from the environment, so use ifdef.
ifdef WIKI_PLANTRULES
else
WIKI_PLANTRULES = $(abspath server/src/Perpetuum.ServerService2/data/plantrules)
endif
DOTNET ?= $(shell command -v dotnet 2>/dev/null || echo $(HOME)/.dotnet/dotnet)
TTY_FLAG := $(shell [ -t 0 ] && echo -it || echo -i)

.PHONY: all build serve test zonemaps generate clean

all: build

# Post-process the generated zone teleport maps (static/zonemaps/*.svg):
# REAL terrain backgrounds from the game's layer files, emphasized zone
# border, and clickable teleport links. The game's layer data is NOT in
# this repo; the tool reads it, in order of preference, from:
# 1. a PerpetuumServer2 checkout (sibling ../PerpetuumServer2 or the
# server/ submodule) when one has custom-layers/ — full data
# 2. .assets/ — fetched by tools/fetch_zone_layers.sh (Steam dedicated
# server + the public gamma Drive archive) when no checkout exists;
# zones only available in the game client then keep their committed
# derived PNGs from static/zonemaps-fallback/ (see the tool header)
# Pure standard-library Python — no database, no pip installs.
ASSETS ?= $(patsubst %/custom-layers,%,$(firstword $(wildcard ../PerpetuumServer2/custom-layers ./server/custom-layers .assets/custom-layers)))
zonemaps:
ASSETS="$(ASSETS)"; if [ -z "$$ASSETS" ]; then bash tools/fetch_zone_layers.sh .assets; ASSETS=$$(pwd)/.assets; fi; OP_ASSETS_DIR="$$ASSETS" python3 tools/gen_zone_teleport_maps.py

# Browser tests (tests/): mermaid syntax of every diagram + sidenav behaviour,
# run against the built site. One-time setup: npm install.
test: build
npm test

# Build the static site with the pinned official Zola container (no local
# install). The container runs as root (the image has no alpine coreutils),
# so if a build is ever interrupted and leaves root-owned files in public/,
# `make clean` removes them via a container.
build:
docker run --rm \
-v "$$PWD:/src" \
$(ZOLA_IMAGE) -r /src build --force -o /src/public

# Local live-reload server: http://localhost:$(WIKI_PORT)
serve:
docker run --rm $(TTY_FLAG) \
-u "$$(id -u):$$(id -g)" \
-p "$(WIKI_PORT):1111" \
-v "$$PWD:/src" \
$(ZOLA_IMAGE) -r /src serve -i 0.0.0.0 --no-port-append -u "http://localhost:$(WIKI_PORT)/"

# Regenerate the generated pages (content/content + zone index + zone map +
# search index) from the database. See generator/README.md for the table
# mapping. IMPORTANT: `make zonemaps` must run AFTER `make generate` —
# generate rewrites the raw zone teleport SVGs, and zonemaps post-processes
# them (terrain, markers, links); re-running generate afterwards overwrites
# the post-processed maps with the raw output (the zone-map tests break).
generate:
@test -n "$(WIKI_DB)" || { echo "error: set WIKI_DB (or PERPETUUM_CONNECTIONSTRING)"; exit 1; }
@test -d "$(WIKI_PLANTRULES)" || { echo "error: WIKI_PLANTRULES is not a directory: $(WIKI_PLANTRULES)"; \
echo "hint: run 'git submodule update --init server' (or set WIKI_PLANTRULES to a GameRoot plantrules dir)"; exit 1; }
$(DOTNET) build -c Release generator/Perpetuum.WikiGenerate/Perpetuum.WikiGenerate.csproj
$(DOTNET) run -c Release --no-build --project generator/Perpetuum.WikiGenerate -- \
--connection "$(WIKI_DB)" \
--plantrules "$(WIKI_PLANTRULES)" \
--out content/content \
--zones-out content/zones

clean:
rm -rf public 2>/dev/null || true
if [ -d public ]; then docker run --rm -v "$$PWD/public:/out" alpine:3.20 sh -c "rm -rf /out/*"; rm -rf public; fi
Loading
Loading