Clone the mod, connect it to the launcher, install the tools, then work on a feature branch. If you only want to play, use Getting Started instead.
For docs site work specifically, see the Contributing Guide which covers
bun run dev, content conventions, and the docs CI pipeline.For repo-root context, see
CONTRIBUTING.md(opens in new tab), a slim pointer to the right docs.
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Git | Any recent version | Version control |
| Python | 3.12+ | Dev tools, validators, standardizers |
| Text editor | VS Code recommended | Editing script files |
| HOI4 | Match mod descriptor | Testing changes in-game |
Optional but useful:
| Tool | Purpose |
|---|---|
| Node.js 24 LTS + Bun | Docs site development only (see the Contributing Guide) |
| GitHub Desktop | Git GUI (recommended) |
| Claude Code | AI-assisted development (see AI Modding Guide) |
Cloning the Repository
Clone the repository with GitHub Desktop by following the Git & GitHub Desktop guide. It walks through installing GitHub Desktop, cloning over HTTPS, and your first commit and push.
-
Team members (write access): clone
https://github.com/MillenniumDawn/Millennium-Dawn.gitdirectly:git clone https://github.com/MillenniumDawn/Millennium-Dawn.git -
Outside contributors: fork the repository first (see GitHub: Fork a repo (opens in new tab)), then clone your fork and add the upstream remote. The Git Workflow guide has the full fork-based walkthrough.
Staying Up to Date
Before starting new work, sync your fork or branch with upstream:
git fetch upstream
git checkout main
git merge upstream/mainOr rebase if you prefer a cleaner history:
git checkout my-feature
git rebase mainFor the detailed sync strategy, see Git Workflow: Staying Up to Date with Main.
Setting Up the Mod for Testing
The checked-in Millennium_Dawn.mod uses path="mod/Millennium-Dawn". For that
path to work, clone the repository into a folder named Millennium-Dawn directly
inside your HOI4 mod directory:
| OS | Default mod directory |
|---|---|
| Windows | C:\Users\<name>\Documents\Paradox Interactive\Hearts of Iron IV\mod\ |
| macOS | ~/Documents/Paradox Interactive/Hearts of Iron IV/mod/ |
| Linux | ~/.local/share/Paradox Interactive/Hearts of Iron IV/mod/ |
- Copy
Millennium_Dawn.modfrom the checkout into the parentmod/directory. If your checkout is elsewhere, changepathin this local copy to the checkout’s absolute path using forward slashes. Do not commit your machine-specific path. - Match HOI4 to
supported_versionin the checkout’s descriptor, not automatically the latest game patch. - In the launcher, use Playsets → Add More Mods and enable Millennium Dawn: Developer Version. Disable Workshop copies and submods in this playset.
- Start a new game to verify the checkout loads.
Development updates may invalidate saves. Keep separate test saves and do not rely on a development checkout for a long-running campaign.
One-Command Setup
The setup script installs pre-commit hooks and Python tool dependencies:
python3 tools/dev_setup.pyThat’s it. Pre-commit hooks will now run automatically on every commit.
To verify your environment at any time:
python3 tools/dev_setup.py --checkFor docs site work, also install the Node and Bun dependencies (see the Contributing Guide:
python3 tools/dev_setup.py --docsPre-commit Hooks
Hooks run automatically on every git commit. They catch:
- Style issues: trailing whitespace, mixed line endings, encoding problems.
- Script errors: mismatched braces, invalid localisation encoding, common HOI4 scripting mistakes.
- Standardization: reports changed files that need formatting. The bulk auto-standardizer is disabled; use the command in the finding on the affected file.
Running Manually
# Run all hooks on specific files
pre-commit run --files common/national_focus/05_SER_focus.txt
# Run a specific hook
pre-commit run md-validate-content
# Update hook versions
pre-commit autoupdateImportant: Never run
pre-commit run --all-files. It rewrites every matching file in the repo and creates hundreds of unrelated changes. Always scope to your modified files.
What Runs Where
| Hook | Pre-commit | CI (PR) | Notes |
|---|---|---|---|
md-validate-content | Yes | Yes | Fast subset; CI runs all batches |
md-validate-defines | Yes | Yes | CI uses vanilla_defines.txt |
md-validate-descriptors | Yes | Yes | Also runs in the core batch job |
fix-localization-encoding | Yes | No | Fixer; CI checks BOM without fixing |
fix-loc-yaml | Yes | No | Pre-commit only |
md-fix-styling | Manual | No | CI checks style in batches |
md-validate-unused-textures | Manual | No | CI cannot run it |
tools-pytest | Pre-push | Yes | CI Tools tests job when tools change |
The CI (PR) column is the Test Suite (test-suite.yml). The full pre-commit vs
CI map, including per-validator strictness, lives in
.claude/docs/validation-pipeline.md.
Dev Tools
All development scripts live in tools/ and can be run by short name:
python3 tools/run.py --list # see all tools
python3 tools/run.py estimate_gdp USA # run by name
python3 tools/run.py find_idea common/ideas/Greek.txt # partial match works
python3 tools/run.py publish_workshop release --full # pass args throughTool Directory Layout
tools/
├── analysis/ Analysis, reference finders, metrics
├── assets/ DDS conversion, GFX generation, texture tools
├── docs_checks/ Docs-site checks (link syntax, a11y, perf, etc.) + check_docs.py runner
├── generators/ Content generators (tribute ideas, focus names)
├── linting/ Style checkers, formatters, encoding validators
├── publishing/ Steam Workshop publishing
├── report_lib/ PR validation report renderer + GitHub Checks API
├── standardization/ Auto-standardizers for focuses, events, decisions, ideas
├── tests/ Test suites for validators
├── validation/ Content validators (events, decisions, variables, etc.)
├── shared_utils.py Shared utilities (Colors, FileOpener, path helpers)
├── loc.py Localisation utilities
├── logging_tool.py Logging utility
├── precommit_validate.py Pre-commit hook: runs commit-stage validators in parallel
├── validate_staged.py Legacy staged-file router (no longer wired into pre-commit)
└── standardize_staged.py Pre-commit hook: routes staged files to standardizersPython dependencies live in pyproject.toml under [dependency-groups] (a runtime group and a dev group); there are no requirements.txt files. tools/dev_setup.py installs them, and pyproject.toml configures Ruff for lint/import order, Black for formatting, and pytest for tests.
See tools/README.md (opens in new tab) for the full documentation.
Changing Tools
Follow Maintaining Tools (opens in new tab)
for text writes, shared helpers, and regression tests. The same README owns the
validator recipe (opens in new tab).
Run python -m pytest for tools/ changes and fix regressions before merge.
VS Code Workspace
The repo includes a pre-configured workspace with Paradox syntax highlighting, trailing whitespace cleanup, and other useful extensions:
- Open VS Code.
- Go to File → Open Workspace.
- Select
.vscode/hoi4_millennium_dawn.code-workspace. - Accept the popup to install recommended extensions.
What’s configured:
- Two extensions for Paradox syntax (highlighting, snippets, problem scanning).
- Trailing whitespace cleanup on save.
- Markdown support, line sorting, CODEOWNERS, editorconfig.
- Workspace folders for better hierarchy in search results.
Code Standards
Keep changes small and easy for another human to maintain. Reuse existing code and queryable state before adding helpers, flags, or configuration. Prefer clear local logic over clever abstractions. The Code Stylization Guide owns the detailed conventions.
Localisation (.yml)
- Edit English only. Other languages are not currently mirrored and may differ.
- 1-space indentation.
- UTF-8 with BOM encoding.
- Remove trailing version numbers after colons (
key: "value", notkey:0 "value").
Script Files (.txt)
- Tab indentation (not spaces).
- Follow the focus, decision, and event logging rules. Dismiss-only event options need no log.
- Follow naming conventions:
TAG_focus_name_here. - Use
is_triggered_only = yesfor events. - Include
ai_will_doin all focuses and decisions. - Remove redundant code (empty trigger blocks). Keep
allowed = { always = no }on slotted ideas that must not appear in the picker.
Docs Content (docs/)
If you are editing the docs site, see the Contributing Guide for the docs-specific rules. The high-level point: frontmatter is required, internal links must be root-relative, and do not hardcode "/Millennium-Dawn/..." (the base path is applied during build).
Day-to-Day Workflow
- Pull latest from
main(or your feature branch). - Create a branch for your work:
git checkout -b my-feature. - Make changes: edit files, test in-game.
- Commit: pre-commit hooks run automatically and flag issues.
- Push your branch:
git push origin my-feature. - Open a PR against
mainon GitHub. - CI validates your PR automatically. Fix any issues flagged.
- Team leader reviews and merges.
PR Descriptions and Handoffs
Use BLUF (Bottom Line Up Front): state the result first, then the supporting facts.
PR descriptions start with ## Bottom line. Explain why when it is not obvious;
include changed behavior and any limits, not a file-by-file narration. Keep reviews
to findings with paths, impact, and a suggested fix. Say what was not verified.
Do not add AI attribution trailers or tool-generated footers. Add Changelog.txt
entries only when requested.
Branch Naming
Use descriptive branch names:
ser-focus-tree: new Serbian focus tree.fix-election-event-bug: bug fix.ai-strategy-updates: AI behavior changes.docs-developer-guide: documentation work.
Related Resources
- Contributing Guide: docs site workflow,
bun run dev, content conventions. - Git Workflow: detailed branch/commit/PR process.
- Code Stylization Guide: formatting and code structure.
- AI Modding Guide: AI tools for development.
- Content Review Guide: quality checklist.
- Git & GitHub Desktop: install GitHub Desktop and clone the mod.
- tools/README.md (opens in new tab): dev tools directory layout.
