Files
bs-roster-parser/README.md
root 948d98accb Initial commit: bs-roster-parser v1.0.0
Python library for parsing BattleScribe/NewRecruit roster JSON.
Extracted from Nachmund Tracker's processJSON, ported JS→Python.

- parse_roster(json_string) / parse_roster_file(path) → RosterSummary
- Extracts: unit name, pts, CP, model count, weapon breakdown per model variant
- Handles: variable-model-count units, nested costs, compound upgrades
- Unicode apostrophe-safe unit lookup (find_unit)
- to_dict() for JSON serialization
- 8/8 tests passing on real roster data (27 units, 2815pts)
2026-06-18 03:04:16 +00:00

67 lines
1.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# bs-roster-parser
Python library for parsing BattleScribe/NewRecruit roster JSON into flat unit lists with costs, model counts, and weapon breakdowns.
## Install
```bash
pip install git+https://git.homelab.local/kaykayyali/bs-roster-parser.git
```
Or clone and install locally:
```bash
git clone https://git.homelab.local/kaykayyali/bs-roster-parser.git
cd bs-roster-parser
pip install -e .
```
## Usage
```python
from bs_roster_parser import parse_roster_file
# Parse a roster file
summary = parse_roster_file("roster.json")
# Access units
for unit in summary.units:
print(f"{unit.name}: {unit.pts}pts, {unit.model_count} models")
for model in unit.breakdown:
print(f" {model.name} ×{model.count}")
if model.weapons:
print(f" Weapons: {', '.join(model.weapons)}")
# Aggregate stats
print(f"Total: {summary.total_pts}pts, {summary.total_cp} CP")
print(f"Units: {summary.unit_count}, Models: {summary.total_models}")
# Find a specific unit
gaunt = summary.find_unit("Gaunt's Ghosts")
# Export to dict/JSON
import json
print(json.dumps(summary.to_dict(), indent=2))
```
## What it extracts
Each unit includes:
- **name** — display name (custom name if set, otherwise catalogue name)
- **pts** — total points cost (including descendant costs for variable-model-count units)
- **cp** — crusade points
- **model_count** — total models (summed from child model nodes)
- **breakdown** — per-model-variant list with names, counts, and detected weapons
- **type** — `unit` or `model`
The roster summary includes:
- **roster_name**, **game_system**, **faction** (detected from first force)
- **points_limit** (from costLimits)
- **total_pts**, **total_cp**, **unit_count**, **total_models**
## Origin
Extracted from the [Nachmund Tracker](https://git.homelab.local/kaykayyali/Nachmund-Tracker) project's `processJSON` function, ported from JavaScript to Python and generalized as a reusable library.
## License
MIT