| name | ose-homebrew-maintainer |
| description | Sync homebrew class abilities with OSE house rules source documents. |
| applyTo | homebrew+ose+rules+sync |
| allowed-tools | [] |
OSE Homebrew Maintainer Skill
Overview
This skill teaches an AI to maintain the homebrew/homebrew.json data file in the OSE Statblock Importer for Foundry VTT v14 module. The data file contains Apostol's personal OSE house rules codified as class abilities — both new abilities added to classes and modifications to existing compendium abilities. When the source house rules documents are updated, this skill guides the AI through identifying what changed and applying those changes to the data file.
Source Documents
The canonical source of truth lives at:
C:\git\lifestyle\rpg_projects\houserules\old-school-essentials\
OSE_HOUSE_RULES.md — full rules text
CHANGELOG.md — version history with dates and change summaries
The target data file is:
modules/ose-statblock-importer/homebrew/homebrew.json
Version Tracking
The homebrew.json file tracks the source version it was last synced against:
{
"sourceVersion": "1.3.5",
"sourceDate": "2026-06-08",
"sourceFile": "OSE_HOUSE_RULES.md",
"sourceChangelog": "CHANGELOG.md"
}
sourceVersion — the SemVer version from CHANGELOG.md that the data reflects
sourceDate — the date of the last changelog entry that was applied
- These fields are updated after every successful sync
Sync Workflow
Step 1: Read Current Version
Open CHANGELOG.md and read the most recent version header. Example:
## 2026-01-18 (v1.3.5)
Extract:
version: 1.3.5
date: 2026-01-18
Step 2: Compare with homebrew.json
Read sourceVersion from homebrew.json. If it matches, no sync is needed. If the source is newer, identify which changelog entries have been added since the last sync.
Step 3: Read Changed Rules
For each changelog entry newer than the last sync, read the change description. Changelog entries use these prefixes:
| Prefix | Meaning | Action |
|---|
MAJOR: | Breaking mechanical changes to rules or class features | Full rewrite of affected abilities |
MINOR: | Backward-compatible additions or new options | Add new abilities or modify existing ones |
PATCH: | Wording/formatting only | Update text verbatim without mechanical changes |
Step 4: Locate Affected Sections in OSE_HOUSE_RULES.md
For each changelog entry, search OSE_HOUSE_RULES.md for the relevant section (e.g., "### Cleric", "### Fighter"). Read the full, unabridged ability text from the source document.
CRITICAL — Full Text Rule: The ability text MUST include the complete text from the source document. This is not a summary or a quick-reference — it is the authoritative rule text that players and DMs will read in Foundry. Every sentence, every mechanical detail, every condition, every edge case must be present.
What you MUST preserve:
- Every sentence from the source text
- All mechanical values, dice expressions, percentages, ranges, durations
- All conditions, prerequisites, and limitations
- All progression details (level-based scaling, multiple uses, etc.)
- Paragraph breaks and sentence structure
What you MUST remove or adjust:
- Section headers (
### Cleric, etc.) — the ability name field already identifies it
- Inline commentary markers like
> 👉🏼 or > 🎲 (editorial notes for the GM, not rules text)
- Meta-commentary like "This replaces the standard rule" or "Changed from original" — state only what the rule IS, never what it was or what changed
- Cross-references to page numbers or sections that don't apply in Foundry
Timeless wording: Every ability must read as a definitive, standalone rule. Never write "this was changed from..." or "unlike the standard rule..." or "instead of the normal...". Just state the rule as it exists. The reader should not need to know the original rule to understand the homebrew.
Bad (summarized):
When you reduce a foe to 0 HP with a melee attack, make one additional melee attack against another engaged opponent. Gain Cleave 2× at 5th level, 3× at 9th level, 4× at 13th level. At 9th level, may spend one Cleave to move up to 10 ft. and engage a new enemy.
Good (full text):
When you reduce a foe to 0 HP with a melee attack, you may immediately make one additional melee attack against another opponent you are engaged with. This additional attack uses the same weapon and modifiers as the original attack. The number of Cleave attacks you can make per round increases as you gain levels: 2 at 5th level, 3 at 9th level, and 4 at 13th level. At 9th level and above, you may expend one Cleave attempt to move up to 10 feet and engage a new enemy before making the Cleave attack. You cannot Cleave off a Cleave attack.
Step 5: Classify Each Ability
For each ability found in the source section, determine its type:
New Ability
An ability that does not exist in the OSE Advanced Fantasy compendium. Add to newAbilities array:
{
"name": "Cleave",
"text": "Verbatim text from source...",
"icon": "systems/ose/assets/melee.png",
"minimumLevel": 1
}
The minimumLevel field indicates the character level at which this ability becomes available. Default is 1 for abilities available from character creation. Set to the level specified in the source rules (e.g., Paladin's Smite Evil at level 5). Currently all abilities are applied regardless of level, but the field is required for future level-gating.
Modification
An ability that replaces or changes an existing compendium ability. Add to modifications array:
{
"compendiumName": "Original compendium ability name",
"newName": "New name (same or different)",
"newText": "Full replacement text — see timeless wording rule below",
"icon": "systems/ose/assets/...",
"minimumLevel": 1
}
The compendiumName must match the exact name of the ability in the ose-advancedfantasytome.abilities compendium. Reference the CLASS ABILITY CATALOG in the ose-statblock-writer skill for valid names.
Timeless wording for modifications: Never mention what the original rule was or what changed. The newText must read as a definitive, self-contained rule. Do NOT write:
- ❌ "This replaces the standard rule..."
- ❌ "Changed from the original..."
- ❌ "Unlike the normal ability..."
- ❌ "Instead of the standard 1-in-6..."
- ❌ "This ability now..."
Just state the rule as it is. The fact that it's in the modifications array (with a compendiumName matching an existing ability) is how the system knows it replaces something. The text itself should need no context from the original.
Removal
An ability that was in the previous homebrew data but has been removed from the source. Delete its entry from the appropriate array.
Step 6: Update homebrew.json
- Update
sourceVersion and sourceDate to match the latest changelog entry
- Update
generatedAt to the current date
- Apply all classified changes to the class's
newAbilities and modifications arrays
- Verify the JSON is valid
Step 7: Assign Icons
Icons for homebrew abilities can use two sources:
Source 1: OSE System Assets (systems/ose/assets/...)
These are the built-in OSE system icons. Use them as defaults when no better Foundry core icon fits:
| Category | Icon Path | Use For |
|---|
combat | systems/ose/assets/melee.png | Attack modifiers, weapon techniques, damage bonuses |
defense | systems/ose/assets/shield.png | AC bonuses, resistances, immunities, saves, parry |
magic | systems/ose/assets/default/spell.png | Spellcasting modifications, arcane abilities, illusions |
divine | systems/ose/assets/splash.png | Holy/divine powers, turning, sanctified abilities |
health | systems/ose/assets/heart_full.png | Healing, HP modifications, disease immunity, death saves |
rest | systems/ose/assets/heart_empty.png | Recovery, exhaustion, rest-related |
movement | systems/ose/assets/charge.png | Speed, charging, dodging, mobility |
stealth | systems/ose/assets/back.png | Hiding, backstab, camouflage, unnoticed |
ranged | systems/ose/assets/missile.png | Ranged attacks, projectiles, thrown weapons |
crafting | systems/ose/assets/default/bag.png | Item creation, crafting, equipment, poisoncraft |
social | systems/ose/assets/gold.png | Diplomacy, nobility, wealth, social influence |
luck | systems/ose/assets/treasure.png | Luck, fortune, rerolls, treasure, gems |
dragon | systems/ose/assets/dragon.png | Dragon-related abilities |
weapon | systems/ose/assets/default/weapon.png | Weapon-specific abilities, finesse |
armor | systems/ose/assets/default/armor.png | Armor-related |
equipment | systems/ose/assets/default/item.png | Equipment, generic items |
heavy_weapon | systems/ose/assets/twohanded.png | Two-handed weapons |
blunt | systems/ose/assets/blunt.png | Blunt weapons, crushing |
slow | systems/ose/assets/slow.png | Slow effects, hindrance |
reload | systems/ose/assets/reload.png | Reloading, ammunition |
brace | systems/ose/assets/brace.png | Bracing, stability, sure-footed |
perception | systems/ose/assets/default/ability.png | Senses, detection, awareness, knowledge |
nature | systems/ose/assets/default/ability.png | Nature, wilderness, animals, terrain |
generic | systems/ose/assets/default/ability.png | Fallback — anything not covered above |
Source 2: Foundry Core Icons (icons/...)
Foundry VTT ships with thousands of specific, high-quality icons organized by category. These are what the OSE compendium abilities actually use.
We've mined the OSE Advanced Fantasy compendiums and cataloged every icons/ path the OSE developers chose for each ability theme. This catalog lives in two places:
data/ose-compendium-core-icons.json — complete list of ~100 unique icons with usage counts and example abilities
homebrew.json → iconMap._foundryCoreIcons — organized by theme category with proven pairings
Icon selection priority:
- Find your ability's theme in
_foundryCoreIcons (combat, defense, perception, magic, divine, stealth, nature, environment, movement, social, equipment, ranged, mounted)
- Pick the icon whose example ability most closely matches your homebrew ability's theme
- Only fall back to OSE system assets (
systems/ose/assets/...) if no Foundry core icon fits
Data File Structure
{
"generatedAt": "2026-07-02",
"sourceVersion": "1.3.5",
"sourceDate": "2026-06-08",
"sourceFile": "OSE_HOUSE_RULES.md",
"sourceChangelog": "CHANGELOG.md",
"description": "...",
"iconMap": { ... },
"classes": {
"featureClassKey": {
"display": "Display Name",
"icon": "systems/ose/assets/...",
"newAbilities": [
{ "name": "...", "text": "...", "icon": "..." }
],
"modifications": [
{ "compendiumName": "...", "newName": "...", "newText": "...", "icon": "..." }
]
}
}
}
Class Key Mapping
The featureClassKey must match the key used by OSEStatblockParser.FEATURE_CLASS_MAP:
| Class | featureClassKey |
|---|
| Cleric | cleric |
| Fighter | fighter |
| Magic-User | magic-user |
| Thief | thief |
| Drow | drow |
| Dwarf | dwarf |
| Duergar | duergar |
| Elf | elf |
| Gnome | gnome |
| Half-Elf | half-elf |
| Half-Orc | half-orc |
| Halfling | halfling |
| Svirfneblin | svirfneblin |
| Acrobat | acrobat |
| Assassin | assassin |
| Barbarian | barbarian |
| Bard | bard |
| Druid | druid |
| Illusionist | illusionist |
| Knight | knight |
| Paladin | paladin |
| Ranger | ranger |
Finding Compendium Ability Names
When writing a modifications entry, the compendiumName must exactly match an ability name in the ose-advancedfantasytome.abilities compendium. To verify names:
- Read
data/ose-advanced-tome-ability-class-map.json — this maps feature classes to their compendium ability names
- Each entry in
byClass[featureClassKey] has an itemName field
- Use that exact
itemName as the compendiumName
Example: For the Drow "Immunity to Ghoul Paralysis" modification:
- Look up
byClass["drow"] in the class map
- Find
{ itemName: "Immunity to Ghoul Paralysis", ... }
- Use
"compendiumName": "Immunity to Ghoul Paralysis"
Text Formatting Rules
When extracting ability text verbatim from OSE_HOUSE_RULES.md:
- Preserve all mechanical values:
4-in-6, 1d3, +2, 30 ft., etc.
- Preserve all conditionals: "save vs", "on success", "on failure"
- Preserve all level-gated progressions: "at 5th level", "increases to 2 at 9th"
- Strip editorial markers:
> 👉🏼, > 🎲, > 👁️ blockquotes
- Strip section headers:
### Cleric, #### Subsection
- Strip table markup and leave only the rules text
- Keep parenthetical clarifications:
(see Low-Light Vision)
- Use a single space after periods, consistent with the source
Common Pitfalls
- Don't summarize: "Concentrate 1 turn" not "Spend 10 minutes"
- Don't modernize: "saving throw versus Death" not "Constitution save"
- Don't abbreviate mechanics: "hit points" not "HP" (unless the source uses HP)
- Don't add interpretation: the text must be the rules as written, not how you'd explain them
- Do check compendium names: a typo in
compendiumName means the modification silently fails
- Do validate JSON: trailing commas or unescaped quotes break the module
Example Sync
Source CHANGELOG entry:
## 2026-02-15 (v1.4.0)
- MINOR: Cleric — Added Turn Constructs ability at 5th level.
- MINOR: Fighter — Cleave now allows movement between cleaves at 7th level (was 9th).
- PATCH: Dwarf — Hardy Growth wording clarified.
Actions:
sourceVersion: 1.3.5 → needs update to 1.4.0
- Cleric: read
### Cleric section, find "Turn Constructs" text → add as newAbilities
- Fighter: read
### Fighter section, find updated Cleave text → update modifications entry for "Cleave"
- Dwarf: read
### Dwarf section, find updated Hardy Growth text → update modifications or newAbilities entry
- Update
sourceVersion to "1.4.0", sourceDate to "2026-02-15", generatedAt to today
Runtime Behavior
The module setting "Apply Apostol's OSE Homebrew to Player Characters" controls whether applyHomebrewToActor() runs during statblock import:
- Setting must be enabled (off by default)
- Actor must be type
character
- Feature class must be resolved from
SV in the statblock
homebrew.json is fetched and cached on first use
- Modifications find existing compendium abilities by name and update them
- New abilities are created as
ability items with system icons
- Already-applied abilities (name match) are skipped to avoid duplicates
Level-up / partial reimport (v14.3+)
Homebrew re-applies when the import runs class-feature application:
- Full import with
SV → class features + homebrew (if setting on)
Mode: Level-up → HD/SV + class features + homebrew; does not wipe inventory
Mode: Partial; Fields: … → homebrew/features only if fields include features/hd/sv/class-related keys
For advancing a PC without redoing gear, prefer:
Name: Mode: Level-up; HD F3; SV F3
(with the character sheet open, or Apply To: Name). See ose-statblock-writer for the full import format.