Text-first parsing and modding support library for Europa Universalis V data files, with optional MCP server and Kivy desktop GUI
Project description
EU5Miner (core)
The core library of the EU5Miner umbrella. See the umbrella README.md for install and layout.
EU5Miner is a text-first Python library for reading, indexing, and planning edits to Europa Universalis V data and mod files.
This is an unofficial community project. It is not affiliated with, endorsed by, or sponsored by Paradox Interactive or the Europa Universalis V development team.
The repository and published package do not include game assets. Real-file validation and many install-backed workflows expect a locally available EU5 installation.
Release 0.8.0 is the current umbrella release; the previous 0.7.x and 0.6.x lines stay supported.
The current release focuses on the major moddable text-based file families:
- Clausewitz-style script text used in
common,events,setup, andmap_data - GUI script
- Localization YAML
- JSON metadata
- Semicolon-delimited CSV
The project is intentionally test-heavy. Core functionality is validated against representative real EU5 install files so later parser work is anchored in observed game behavior instead of assumptions.
Module paths and extras
This package is the single eu5miner distribution. It exposes three Python modules:
eu5miner— core library and CLI (always available).eu5miner.mcp— MCP server (requires the[mcp]extra).eu5miner.gui— Kivy desktop UI (requires the[gui]extra).
Without the matching extra, importing eu5miner.mcp or eu5miner.gui raises an ImportError directing you to install the extra.
Status
The 0.8.x line is published from this umbrella as a single eu5miner wheel with optional extras (pip install eu5miner[mcp], eu5miner[gui], eu5miner[all]). The MCP server and GUI are submodules inside the unified package rather than separate distributions.
Compared with 0.5.0, the 0.6.x line expanded the stable read-only inspection seam with initial entity browsing for economy, diplomacy, government, religion, and map while keeping the public API deliberately curated.
- The root package, grouped domain packages,
eu5miner.inspection, and theeu5miner.modsfacade are intended for real use. - The CLI is intended as a thin convenience surface over the same library APIs.
- Additional helper layers and future editing surfaces are still expected to evolve before
1.0. - API coverage is intentionally incomplete relative to the full game data surface; missing families and API adjustments should still be expected during the preview line.
In practice, this release is suitable for install inspection, virtual filesystem queries, representative parsing, typed domain reads, and the current mod update planning and application workflow. It is not yet a promise that every exported helper will remain unchanged across future minor releases.
Install
pip install eu5miner
Or with the optional surfaces:
pip install eu5miner[mcp] # adds eu5miner.mcp
pip install eu5miner[gui] # adds eu5miner.gui
pip install eu5miner[all]
Python 3.12 and uv are required for development.
Development
Within the umbrella workspace:
cd EU5Miner
uv sync --extra=dev
cd packages/core
uv run pytest
uv run ruff check .
uv run mypy src
uv build
The repo is stored under OneDrive. The Windows setup script at scripts/setup-centralized-uv.ps1 points UV_PROJECT_ENVIRONMENT at %USERPROFILE%\.venvs\EU5Miner, sets UV_LINK_MODE=copy for OneDrive-safe uv operations, and runs uv sync --extra dev there.
Run the broader optional sweep explicitly when you want wider install-backed coverage:
uv run python -m pytest -m broad
CLI
The project ships a thin CLI:
eu5miner inspect-install
eu5miner list-systems
eu5miner list-files --phase in_game --subpath gui --limit 10
eu5miner analyze-script --representative scripted_trigger
eu5miner report-system --install-root C:\EU5 --system economy
eu5miner report-system --install-root C:\EU5 --system diplomacy
eu5miner plan-mod-update --install-root C:\EU5 --mod-root C:\mods\my_mod --phase in_game --subtree common/buildings --content-root C:\work\content
eu5miner apply-mod-update --install-root C:\EU5 --mod-root C:\mods\my_mod --phase in_game --subtree common/buildings --content-root C:\work\content
These seven commands and their documented arguments are the intended thin CLI contract. Higher-level automation should prefer the library facades in eu5miner.inspection and eu5miner.mods rather than depending on internal CLI helpers.
list-systems and report-system provide install-backed summaries for the major connected systems currently implemented in the library: economy, diplomacy, government, religion, interface, and map.
The mod workflow commands print a structured report to stdout, note: advisories for planned metadata actions such as replace_path additions, and warning: diagnostics for intended outputs that will still be shadowed by later sources.
Library
The root package intentionally stays narrow. It exposes install discovery, VFS primitives, and the public mod workflow facade:
from pathlib import Path
from eu5miner import ContentPhase, GameInstall, VirtualFilesystem, plan_mod_update
install = GameInstall.discover(r"C:\Program Files (x86)\Steam\steamapps\common\Europa Universalis V")
vfs = VirtualFilesystem.from_install(install)
merged = vfs.get_merged_file(ContentPhase.IN_GAME, Path("gui") / "agenda_view.gui")
assert merged is not None
update = plan_mod_update(
vfs,
"my_mod",
ContentPhase.IN_GAME,
Path("common") / "buildings",
intended_relative_paths=(Path("common") / "buildings" / "a.txt",),
content_by_relative_path={Path("common") / "buildings" / "a.txt": "building = {}\n"},
)
The root package does not also re-export install inspection helpers or domain parsing helpers. Keep those imports explicit so downstream code can depend on the intended stable seams.
For downstream GUI and MCP consumers that need a stable read-only seam for install discovery, high-level system summaries, and initial entity browsing, use eu5miner.inspection instead of reaching into CLI helpers:
from eu5miner import GameInstall
from eu5miner.inspection import (
get_system_entity,
format_install_summary,
format_system_report,
get_system_report,
inspect_install,
list_entity_systems,
list_system_entities,
list_supported_systems,
)
summary = inspect_install(r"C:\Program Files (x86)\Steam\steamapps\common\Europa Universalis V")
print(format_install_summary(summary))
systems = list_supported_systems()
economy_report = get_system_report(
GameInstall.discover(summary.root),
"economy",
)
print(format_system_report(economy_report))
entity_systems = list_entity_systems()
economy_entities = list_system_entities(
GameInstall.discover(summary.root),
"economy",
)
iron = get_system_entity(
GameInstall.discover(summary.root),
"economy",
"iron",
)
This inspection facade is the stable public entrypoint for install summaries, available system listing, install-backed system report retrieval, and a deliberately narrow entity-browsing seam. The current browseable subset is intentionally limited to one primary entity family per system: economy goods, diplomacy casus belli, government government types, religion religions, and map linked locations. That keeps the preview API useful for GUI and MCP read-only flows without overcommitting to a generic graph API across every catalog family yet.
Repeated inspection entity queries are cached process-locally per install, system, and mod-root context. If a mutating workflow can change inspection results, invalidate the affected system entries with eu5miner.inspection.invalidate_system_entity_cache(...) or otherwise refresh the inspection cache state before querying again.
For domain adapters and higher-level helpers, prefer grouped package entrypoints when you are working within one concept area:
from eu5miner.domains.diplomacy import (
build_diplomacy_graph_catalog,
build_war_flow_catalog,
parse_casus_belli_document,
parse_country_interaction_document,
parse_peace_treaty_document,
parse_subject_type_document,
parse_wargoal_document,
)
from eu5miner.domains.economy import (
build_market_catalog,
parse_goods_document,
parse_price_document,
)
from eu5miner.domains.government import build_government_catalog, parse_government_type_document
from eu5miner.domains.localization import build_localization_bundle
from eu5miner.domains.map import build_linked_location_document, parse_default_map_document
from eu5miner.domains.religion import build_religion_catalog, parse_religion_document
from eu5miner.domains.units import parse_unit_category_document
casus_belli_document = parse_casus_belli_document(
"sample_cb = { war_goal_type = superiority }\n"
)
wargoal_document = parse_wargoal_document(
"superiority = { type = superiority attacker = { conquer_cost = 1 } }\n"
)
peace_treaty_document = parse_peace_treaty_document(
"peace_example = { effect = { make_subject_of = { type = subject_type:sample_subject } } }\n"
)
subject_type_document = parse_subject_type_document(
"sample_subject = { level = 1 allow_subjects = no }\n"
)
country_interaction_document = parse_country_interaction_document(
"sample_country_interaction = { type = diplomacy }\n"
)
war_catalog = build_war_flow_catalog(
casus_belli_documents=(casus_belli_document,),
wargoal_documents=(wargoal_document,),
peace_treaty_documents=(peace_treaty_document,),
subject_type_documents=(subject_type_document,),
)
diplomacy_catalog = build_diplomacy_graph_catalog(
casus_belli_documents=(casus_belli_document,),
wargoal_documents=(wargoal_document,),
peace_treaty_documents=(peace_treaty_document,),
subject_type_documents=(subject_type_document,),
country_interaction_documents=(country_interaction_document,),
)
goods_document = parse_goods_document("iron = { method = mining category = raw_material }\n")
price_document = parse_price_document("build_road = { gold = 10 }\n")
market_catalog = build_market_catalog(
goods_documents=(goods_document,),
price_documents=(price_document,),
)
government_type_document = parse_government_type_document(
"monarchy = { heir_selection = cognatic government_power = legitimacy }\n"
)
government_catalog = build_government_catalog(
government_type_documents=(government_type_document,),
)
religion_document = parse_religion_document("example_faith = { group = abrahamic }\n")
religion_catalog = build_religion_catalog(religion_documents=(religion_document,))
default_map_document = parse_default_map_document('setup = "definitions.txt"\n')
localization_bundle = build_localization_bundle(
(("sample.yml", 'l_english:\nSAMPLE_KEY: "Sample"\n'),)
)
unit_category_document = parse_unit_category_document(
"sample_category = { is_army = yes startup_amount = 1 }\n"
)
For mod update workflows in the preview release, eu5miner.mods remains the stable higher-level seam, while the CLI stays a thin wrapper over the same plan/apply/report operations.
The built-in apply_mod_update(...) flow already invalidates matching inspection entity caches when the planned update still carries install-backed context. Lower-level direct write helpers such as materialize_targeted_mod_emission(...) remain inspection-agnostic on purpose, so callers using those helpers directly must own any required inspection cache refresh or invalidation themselves.
The broad eu5miner.domains convenience export remains available for callers that genuinely want one import hub across many domains, but grouped packages are the preferred stable seam when the concept area is clear. Avoid reaching into internal implementation modules such as eu5miner.domains.diplomacy.casus_belli or eu5miner.domains.map.map_text from downstream code.
Testing
The default baseline keeps uv run pytest warning-free even when plugin-specific pytest options are unavailable.
When the development environment includes pytest-timeout via uv sync --extra dev, the suite also applies a global per-test timeout and preserves the per-test @pytest.mark.timeout(...) overrides used by parser-sensitive tests.
Configuration
The test suite and install-discovery helpers use this precedence for the game install path:
EU5_INSTALL_DIR- The default Steam install path on Windows
Documentation
- Umbrella planning entrypoint: ROADMAP.md
- Umbrella release history: CHANGELOG.md
- Migration notes for the workspace consolidation: RENAMING.md
- Execution-ready work packages: documents/specs/README.md
- Architecture constraints and layering rules: documents/architecture.md
- Developer environment notes for the OneDrive/
uvworkflow: documents/development-environment.md 1.0boundary and blocker set: documents/v1-scope.md and documents/v1-release-readiness.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eu5miner-0.8.0.tar.gz.
File metadata
- Download URL: eu5miner-0.8.0.tar.gz
- Upload date:
- Size: 292.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a40795ac27244a20174173f079462d944bbe9300230d4f3fe7884fb76eea0a3
|
|
| MD5 |
3eeca7671fbbb56154fa05c78166bdda
|
|
| BLAKE2b-256 |
abe09c7cb3a52a5b93ff0e7525b4b913ae88918192fee3ecf0f9c456db3ef224
|
File details
Details for the file eu5miner-0.8.0-py3-none-any.whl.
File metadata
- Download URL: eu5miner-0.8.0-py3-none-any.whl
- Upload date:
- Size: 209.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27c341dc84d4da9d7d8c65b9e65b80fc0262cceb9649838649c369b2e4a3ba5b
|
|
| MD5 |
712f97bdf8d7b40368c3809ffe806515
|
|
| BLAKE2b-256 |
182a870163695c7923767bf612bf4b0d7821ec87be7fd21de0d7e90de75263f9
|