Developer Resource

Developer Setup & Workflow

Get your environment ready for Millennium Dawn mod development

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

ToolVersionPurpose
GitAny recent versionVersion control
Python3.10+ (3.12+ recommended)Dev tools, validators, standardizers
Text editorVS Code recommendedEditing script files
HOI4LatestTesting changes in-game

Optional but useful:

ToolPurpose
Node.js 24 LTS + BunDocs site development only
GitKraken or GitHub DesktopGit GUI (pick one)
Claude CodeAI-assisted development (see AI Modding Guide)

Cloning the Repository

Team Members (Write Access)

git clone https://github.com/MillenniumDawn/Millennium-Dawn.git
cd Millennium-Dawn

Outside Contributors (Fork)

  1. Fork the repository on GitHub.
  2. Clone your fork:
    git clone https://github.com/<your-username>/Millennium-Dawn.git
    cd Millennium-Dawn
  3. 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:

OSDefault mod directory
WindowsC:\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/
  1. Copy the Millennium_Dawn.mod file from the cloned repo into the mod/ directory.
  2. In the HOI4 launcher, go to PlaysetsAdd More Mods → enable Millennium Dawn Dev.
  3. Launch the game to verify it works.

One-Command Setup

The setup script installs pre-commit hooks and Python tool dependencies:

python3 tools/setup.py

That’s it. Pre-commit hooks will now run automatically on every commit.

To verify your environment at any time:

python3 tools/setup.py --check

Pre-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 autoupdate

Important: 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

HookPre-commitCI (PR)Notes
check-bracesYesNoPre-commit only
fix-loc-yamlYesNoPre-commit only
validate-localization-encodingYesNoPre-commit only
coding-standardsManualYesRuns on PR, not on commit
check-basic-styleManualYesRuns on PR, not on commit
check-common-mistakesManualYesRuns on PR, not on commit
validate-ai-equipmentYes (no strict)Yes (strict)Strict mode on CI blocks coverage gaps
validate-ideasYes (strict)Yes (informational)CI is informational until pre-existing issues are cleared
validate-definesYesSkippedNeeds 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 through

Tool 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 standardizers

See tools/README.md (opens in new tab) for the full documentation.

Writing a New Validator

  1. Create tools/validation/validate_<topic>.py.
  2. Subclass BaseValidator from tools/validation/validator_common.py.
  3. Use add_error(category, msg, file, line) for structured issues.
  4. Add a pre-commit hook entry in .pre-commit-config.yaml.
  5. 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:

  1. Open VS Code.
  2. Go to FileOpen Workspace.
  3. Select .vscode/hoi4_millennium_dawn.code-workspace.
  4. 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 dependencies

Requires 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

PathContent
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

  1. Pull latest from main (or your feature branch).
  2. Create a branch for your work: git checkout -b my-feature.
  3. Make changes — edit files, test in-game.
  4. Commit — pre-commit hooks run automatically and flag issues.
  5. Push your branch: git push origin my-feature.
  6. Open a PR against main on GitHub.
  7. CI validates your PR automatically. Fix any issues flagged.
  8. Team leader reviews and merges.

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

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 main

Or rebase if you prefer a cleaner history:

git checkout my-feature
git rebase main

Related Resources