This guide covers everything you need to start contributing: prerequisites, cloning, tooling, pre-commit hooks, and the day-to-day development workflow.
New contributors: Start with the Contributing Guide for an overview of what we accept and how to submit changes.
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Git | Any recent version | Version control |
| Python | 3.10+ (3.12+ recommended) | Dev tools, validators, standardizers |
| Text editor | VS Code recommended | Editing script files |
| HOI4 | Latest | Testing changes in-game |
Optional but useful:
| Tool | Purpose |
|---|---|
| Node.js 24 LTS + Bun | Docs site development only |
| GitKraken or GitHub Desktop | Git GUI (pick one) |
| Claude Code | AI-assisted development (see AI Modding Guide) |
Cloning the Repository
Team Members (Write Access)
git clone https://github.com/MillenniumDawn/Millennium-Dawn.git
cd Millennium-DawnOutside Contributors (Fork)
- Fork the repository on GitHub.
- Clone your fork:
git clone https://github.com/<your-username>/Millennium-Dawn.git cd Millennium-Dawn - Add the upstream remote:
git remote add upstream https://github.com/MillenniumDawn/Millennium-Dawn.git
See Git Workflow for the full fork-based workflow.
Setting Up the Mod for Testing
After cloning, the mod folder must be in the correct location for HOI4 to detect it:
| 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 the
Millennium_Dawn.modfile from the cloned repo into themod/directory. - In the HOI4 launcher, go to Playsets → Add More Mods → enable Millennium Dawn Dev.
- Launch the game to verify it works.
One-Command Setup
The setup script installs pre-commit hooks and Python tool dependencies:
python3 tools/setup.pyThat’s it. Pre-commit hooks will now run automatically on every commit.
To verify your environment at any time:
python3 tools/setup.py --checkPre-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 — auto-reformats focuses, events, decisions, and ideas to MD conventions
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 check-braces
# 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 |
|---|---|---|---|
check-braces | Yes | No | Pre-commit only |
fix-loc-yaml | Yes | No | Pre-commit only |
validate-localization-encoding | Yes | No | Pre-commit only |
coding-standards | Manual | Yes | Runs on PR, not on commit |
check-basic-style | Manual | Yes | Runs on PR, not on commit |
check-common-mistakes | Manual | Yes | Runs on PR, not on commit |
validate-ai-equipment | Yes (no strict) | Yes (strict) | Strict mode on CI blocks coverage gaps |
validate-ideas | Yes (strict) | Yes (informational) | CI is informational until pre-existing issues are cleared |
validate-defines | Yes | Skipped | Needs vanilla file not in CI runner |
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
├── 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 standardizersSee tools/README.md (opens in new tab) for the full documentation.
Writing a New Validator
- Create
tools/validation/validate_<topic>.py. - Subclass
BaseValidatorfromtools/validation/validator_common.py. - Use
add_error(category, msg, file, line)for structured issues. - Add a pre-commit hook entry in
.pre-commit-config.yaml. - Add a CI entry in
.github/workflows/coding-pipeline.yml.
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
Docs Site Setup
The documentation site lives under docs/ and is built with Astro (opens in new tab).
Setup
python3 tools/setup.py --docs # installs Node.js + Bun dependenciesRequires Node.js 24 LTS (opens in new tab) and Bun (opens in new tab).
Local Preview
cd docs
bun run dev # opens at http://localhost:4321/Before Opening a Docs PR
cd docs
bun run ci # runs full check suite (lint, typecheck, build)Content Structure
| Path | Content |
|---|---|
docs/src/content/pages/ | Top-level pages (FAQ, Getting Started) |
docs/src/content/resources/ | Developer resource guides |
docs/src/content/tutorials/ | Player and developer tutorials |
docs/src/content/countries/ | Country-specific documentation |
docs/src/content/navigation/ | Site navigation and footer |
Content uses Markdown with frontmatter. Internal links must be root-relative (/dev-resources/guide-name/). Do not hardcode the base path.
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.
Branch Naming
Use descriptive branch names:
ser-focus-tree— new Serbian focus treefix-election-event-bug— bug fixai-strategy-updates— AI behavior changesdocs-developer-guide— documentation work
Staying Up to Date
Sync your branch with main regularly to avoid merge conflicts:
git fetch upstream
git checkout main
git merge upstream/main
git checkout my-feature
git merge mainOr rebase if you prefer a cleaner history:
git checkout my-feature
git rebase mainRelated Resources
- Contributing Guide — What we accept, fork workflow, AI policy
- 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