# `pack.toml` Manifest Spec

## Purpose

`pack.toml` is the root manifest of a modpack project.

Its job is to define:

- what the pack is
- which files define authored pack structure
- where related project files live
- which generated and optional rule files are used

`pack.toml` is **not** a dumping ground for full mod lists, generated lock data, caches, or UI state.

It also should not store machine-local launch runtime paths or virtual-install details.

It should stay:

- small
- explicit
- readable
- easy to diff
- easy for both humans and tools to understand

---

## Design principles

1. `pack.toml` is the root manifest, not a database export.
2. It should describe project structure, not duplicate mod list contents.
3. Paths should be project-relative, not absolute.
4. The file should be stable under normal editing.
5. Tables should be used to keep fields organized as the manifest grows.

---

## Recommended structure

A recommended `pack.toml` uses these sections:

- `[pack]`
- `[layout]`
- `[paths]`

Optional future sections may be added later, such as `[features]`, but should not be introduced without a clear use case.

Example:

```toml
[pack]
name = "My Modpack"
rimworld_version = "1.5"
pack_format_version = 1
author = "Natalia"
description = "Large themed pack focused on combat, factions, and QoL."

[layout]
mod_files = [
  "mods/00_core.list",
  "mods/10_libraries.list",
  "mods/20_ui.list",
  "mods/30_gameplay.list",
  "mods/40_qol.list",
  "mods/50_overhaul.list",
  "mods/60_factions.list",
  "mods/70_combat.list",
  "mods/80_graphics.list",
  "mods/90_textures.list",
  "mods/99_patch.list",
]

[paths]
config_dir = "config/Mod_Configs"
ordering_rule_files = [
  "rules/ordering/30_combat.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
diagnostics_file = "generated/diagnostics.json"
resolved_load_order_file = "generated/resolved_load_order.txt"
local_mods_dir = "local/mods"
```

---

## Section: `[pack]`

This section contains human-facing pack metadata.

### Required fields

#### `name`
Type: string

Human-readable pack name.

Example:

```toml
[pack]
name = "My Modpack"
```

#### `rimworld_version`
Type: string

The target RimWorld version.

This should be stored as a string, not a numeric TOML value.

Example:

```toml
[pack]
rimworld_version = "1.5"
```

#### `pack_format_version`
Type: integer

Version of the modpack manifest/layout format.

This allows future migration and compatibility handling.

Example:

```toml
[pack]
pack_format_version = 1
```

### Optional fields

#### `author`
Type: string

Human-readable pack author name.

#### `description`
Type: string

Short human-readable description of the pack.

### Recommended `[pack]` example

```toml
[pack]
name = "My Modpack"
rimworld_version = "1.5"
pack_format_version = 1
author = "Natalia"
description = "Large themed pack focused on combat, factions, and QoL."
```

---

## Section: `[layout]`

This section defines authored pack structure.

### Required fields

#### `mod_files`
Type: array of strings

Ordered list of `.list` files that define the authored modpack contents.

This field is one of the most important fields in the manifest.

Rules:

- order matters
- entries should be relative paths from the pack root
- file order should be taken from this array, not implicit filesystem enumeration
- each path should be unique

Example:

```toml
[layout]
mod_files = [
  "mods/00_core.list",
  "mods/10_libraries.list",
  "mods/20_ui.list",
  "mods/30_gameplay.list",
  "mods/40_qol.list",
  "mods/50_overhaul.list",
  "mods/60_factions.list",
  "mods/70_combat.list",
  "mods/80_graphics.list",
  "mods/90_textures.list",
  "mods/99_patch.list",
]
```

---

## Section: `[paths]`

This section defines related project-local paths.

These paths should point to authored or generated content connected to the pack.

All paths should be:

- relative to the pack root
- written using forward slashes
- interpreted as project-local paths

Absolute paths should be avoided.

### Recommended fields

#### `config_dir`
Type: string

Path to authored configuration files that belong to the pack.

Example:

```toml
[paths]
config_dir = "config/Mod_Configs"
```

#### `ordering_rules_file`
Type: string

Path to structured ordering rules.

Example:

```toml
[paths]
ordering_rule_files = [
  "rules/ordering/30_combat.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
```

#### `diagnostics_file`
Type: string

Path to generated diagnostics output.

Example:

```toml
[paths]
diagnostics_file = "generated/diagnostics.json"
```

#### `resolved_load_order_file`
Type: string

Path to a human-readable resolved load order export.

Example:

```toml
[paths]
resolved_load_order_file = "generated/resolved_load_order.txt"
```

#### `local_mods_dir`
Type: string

Path to pack-local authored mods or compatibility patches.

Example:

```toml
[paths]
local_mods_dir = "local/mods"
```

### Recommended `[paths]` example

```toml
[paths]
config_dir = "config/Mod_Configs"
ordering_rule_files = [
  "rules/ordering/30_combat.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
diagnostics_file = "generated/diagnostics.json"
resolved_load_order_file = "generated/resolved_load_order.txt"
local_mods_dir = "local/mods"
```

---

## Required vs optional fields

### Required
- `[pack].name`
- `[pack].rimworld_version`
- `[pack].pack_format_version`
- `[layout].mod_files`

### Optional but recommended
- `[paths].config_dir`
- `[paths].ordering_rule_files`
- `[paths].activation_rule_files`

### Optional
- `[pack].author`
- `[pack].description`
- `[paths].diagnostics_file`
- `[paths].resolved_load_order_file`
- `[paths].local_mods_dir`

---

## Path rules

All path values in `pack.toml` should follow these rules:

1. They are relative to the pack root.
2. They use forward slashes.
3. They should refer only to project-local files and directories.
4. They should not use absolute filesystem paths.
5. They should not rely on platform-specific path syntax.

Good:

```toml
resolved_load_order_file = "generated/resolved_load_order.txt"
```

Bad:

```toml
resolved_load_order_file = "C:\\Users\\someone\\Desktop\\resolved_load_order.txt"
```

---

## Validation rules

A tool or agent reading `pack.toml` should validate at least the following:

1. `[pack].name` exists and is non-empty.
2. `[pack].rimworld_version` exists and is non-empty.
3. `[pack].pack_format_version` exists and is a supported integer.
4. `[layout].mod_files` exists and is non-empty.
5. All `mod_files` entries are unique.
6. All declared paths are relative paths.
7. `[paths].ordering_rule_files`, if present, contains unique relative paths.
8. `[paths].activation_rule_files`, if present, contains unique relative paths.
9. Referenced files or directories that are missing should produce diagnostics, not silent failure.

---

## Editing rules

When modifying `pack.toml`:

- preserve unrelated fields
- preserve comments when possible
- do not reorder arrays or sections without reason
- do not inline full mod list contents into the manifest
- do not insert generated metadata into `[pack]`, `[layout]`, or `[paths]`

If the tool edits TOML while preserving formatting and comments, a style-preserving TOML editor should be used.

---

## What belongs in `pack.toml`

Appropriate contents include:

- pack identity
- pack format version
- ordered list of `.list` files
- paths to config, rule files, lock, and diagnostics files
- small project-level metadata
- pack-local paths that are intended to travel with the project

---

## What must not go in `pack.toml`

The following do not belong in `pack.toml`:

- full mod entry lists
- resolved package IDs for every mod
- workshop metadata dumps
- timestamps for every resolved entry
- caches
- UI/editor state
- window layout
- selected tabs
- machine-local launch roots
- machine-local per-pack save-data/config roots
- symlink runtime directories
- generated diagnostics payloads
- large compatibility databases

These belong in `.list` files, rule files, or generated output files instead.

---

## Minimal example

```toml
[pack]
name = "My Modpack"
rimworld_version = "1.5"
pack_format_version = 1

[layout]
mod_files = [
  "mods/00_core.list",
  "mods/10_libraries.list",
  "mods/20_ui.list",
  "mods/30_gameplay.list",
]

[paths]
config_dir = "config/Mod_Configs"
ordering_rule_files = [
  "rules/ordering/30_combat.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
```

---

## Full recommended example

```toml
[pack]
name = "My Modpack"
rimworld_version = "1.5"
pack_format_version = 1
author = "Natalia"
description = "Large themed pack focused on combat, factions, and QoL."

[layout]
mod_files = [
  "mods/00_core.list",
  "mods/10_libraries.list",
  "mods/20_ui.list",
  "mods/30_gameplay.list",
  "mods/40_qol.list",
  "mods/50_overhaul.list",
  "mods/60_factions.list",
  "mods/70_combat.list",
  "mods/80_graphics.list",
  "mods/90_textures.list",
  "mods/99_patch.list",
]

[paths]
config_dir = "config/Mod_Configs"
ordering_rule_files = [
  "rules/ordering/30_combat.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
activation_rule_files = [
  "rules/activation/40_patches.toml",
]
diagnostics_file = "generated/diagnostics.json"
resolved_load_order_file = "generated/resolved_load_order.txt"
local_mods_dir = "local/mods"
```

---

## Non-goals

`pack.toml` should not assume:

- that all packs have local mods
- that all packs use snapshots
- that all packs use exports
- that the manifest is the source of individual mod entries
- that generated files are intended for hand-editing
- that launch runtime configuration belongs in the project manifest

---

## Suggested agent guidance

The agent should follow these rules:

1. Treat `pack.toml` as the root manifest.
2. Read `layout.mod_files` as the authoritative ordered list of `.list` files.
3. Treat paths in `[paths]` as project-relative.
4. Keep `pack.toml` small and explicit.
5. Do not store full mod lists in `pack.toml`.
6. Do not store generated lock or diagnostics data in `pack.toml`.
7. Treat `[paths].activation_rule_files` as activation logic layered on top of resolved entries.
8. Preserve comments and unrelated fields when editing if possible.

---

## Compact machine-oriented summary

```text
pack.toml:
- root manifest for the modpack project
- organized into [pack], [layout], and [paths]

required:
- [pack].name
- [pack].rimworld_version
- [pack].pack_format_version
- [layout].mod_files

[layout].mod_files:
- ordered list of authored .list files
- authoritative file order
- relative paths only

[paths]:
- project-relative paths to config, lock, ordering rules, activation rules, diagnostics, and local content

must not contain:
- full mod entries
- generated lock data
- caches
- UI state
- large generated metadata
```
