AstraTerra Developer Guide
Build And Test
The Makefile uses the repo-local .dotnet path and defaults to a Release build. The mod project expects VINTAGE_STORY to point at a Vintage Story install directory. If unset, it defaults to /Applications/Vintage Story.app on macOS.
For a local Vintage Story smoke test:
Then enable AstraTerra in Vintage Story 1.22.2 and run the manual verification checklist.
Releasing
Bump the version
make bump-minor-version # 0.1.56 -> 0.2.0
make bump-patch-version # 0.1.56 -> 0.1.57
make bump-version VERSION=1.0.0 # explicit
The version lives in two places — modinfo.json and AstraTerraModMetadata.Version —
plus GitHub issue-template placeholders. Always bump through the Makefile rather than
editing any of those by hand. The Makefile calls bump-my-version,
installed once with uv tool install bump-my-version.
BootstrapSmokeTests.Runtime_Version_Stays_In_Sync_With_Modinfo fails if the two source
files drift.
The bump targets deploy
bump-version, and therefore bump-minor-version and bump-patch-version, chain into
deploy, which installs the zip package into your local Vintage Story Mods folder. Use
make bump-version-files VERSION=x.y.z to update the version without deploying.
What happens on merge to main
Two workflows run from the same push, independently:
| Workflow | Runner | Does |
|---|---|---|
release-drafter.yml |
ubuntu-latest |
Reads the version from modinfo.json and creates or renames the draft release to vX.Y.Z, with notes generated from merged pull requests |
tests.yml |
ubuntu-latest |
Tests, builds and packages, and — once the tests and the benchmark have passed — attaches dist/AstraTerra-X.Y.Z.zip to that draft. The zip is a workflow artifact on every run, merge or not |
Release Drafter owns the notes; the packaging job only ever touches assets
(gh release upload --clobber), so the two do not fight. It waits for the draft to appear, and
creates one itself if Release Drafter never got there, so a build is never stranded without
somewhere to land.
Publishing stays manual. Review the draft, confirm the attached zip, then publish — which is
what creates the vX.Y.Z git tag.
Once that release is published, post-release-bump.yml patch-bumps main as
github-actions[bot] and opens the next draft at vX.Y.Z+1. The zip for that
draft is attached by the usual CI on the next merge to main.
A published release is never modified
If main moves after vX.Y.Z has already been published — that is, someone merged without
bumping the version — the job logs a warning and leaves the release alone rather than
overwriting a shipped asset. The package still exists as a workflow artifact. Bump the version
and merge again.
Everything runs on GitHub's runners
The mod compiles against the shipped game assemblies, and CI fetches the linux-x64 client
archive for them: they are managed DLLs, so no job needs a particular operating system. Nothing
here depends on a machine of yours being switched on.
Only the release-package job may write to the repository, and it says so in the job rather
than at the top of the workflow, so the tests and the benchmark run with read-only tokens.
Documentation Site
The documentation site builds with ProperDocs and the MaterialX theme. The configuration lives in properdocs.yml, and the docs toolchain is pinned in docs/requirements.txt.
Install uv before running the documentation targets. make docs-build performs the same strict build used by CI. Pull requests that change the docs or their build configuration are validated without publishing; pushes to main publish the result to the AstraTerra documentation site.
Repository Layout
assets/astraterra/ Runtime JSON, handbook pages, language, shapes, recipes, and textures
src/AstraTerra/ Vintage Story code mod
tests/AstraTerra.Tests/ Unit and asset tests
tools/cataloggen/ Developer-only star catalog generator
tools/milkywaygen/ Developer-only Milky Way texture generator
tools/deepsky/ Stellarium deep-sky plate importer
docs/player/ Player-facing documentation
docs/dev/ Developer-facing documentation
Inside src/AstraTerra/, Astronomy/ is the pure sky model, Client/ is everything that draws or
reads input, Items/ is the Vintage Story item entry point, Constellations/ and Observation/ own
what a book and an instrument remember, and Commands/ and Config/ are the two ways a player
changes anything. Architecture goes through the boundaries between them.
Core References
- Architecture — which folder owns what, and the boundaries between them
- Celestial Model — world clock to a position in the sky, and what the render thread may do
- Latitude And Longitude — where the observer's position comes from, and what Vintage Story does and does not provide
- Extending AstraTerra — the public catalog-replacement API for other mods
- Data Pipeline — the committed catalog assets and the generators behind them
- Manual Verification — in-game smoke checks before release
- Product Scope — goals, non-goals, and deferred work
- Reference Sky Rendering Notes — historical findings that set the rendering baseline
Start with Architecture for the map, Celestial Model for the astronomy, and Extending if you are writing another mod against this one rather than changing it.