initial commit
This commit is contained in:
90
.claude/skills/parse-dungeon/HTML-TEMPLATE.md
Normal file
90
.claude/skills/parse-dungeon/HTML-TEMPLATE.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Data Template Reference
|
||||
|
||||
## Dungeon Data File Structure
|
||||
|
||||
Each dungeon is a TypeScript file in `src/data/` that exports a `DungeonData` object.
|
||||
|
||||
```typescript
|
||||
import type { DungeonData } from "@/types/dungeon";
|
||||
|
||||
export const dungeonSlug: DungeonData = {
|
||||
id: "dungeon-slug",
|
||||
name: "Dungeon Name",
|
||||
descriptionHtml: `Brief layout with <span class="wing-badge wing-arcane">Wing</span> badges if applicable`,
|
||||
headerImage: "/assets/dungeon_name_header.jpg",
|
||||
icon: "/assets/dungeon_dungeon_name.jpg",
|
||||
sections: [
|
||||
{
|
||||
type: "trash",
|
||||
data: {
|
||||
header: "Area Name — Trash Before BossName",
|
||||
content: [
|
||||
{ type: "quickRef", data: { html: `<strong>Environment:</strong> Brief description.` } },
|
||||
{
|
||||
type: "mob",
|
||||
data: {
|
||||
name: "Mob Name (Immune to CC)",
|
||||
nameHtml: `Mob Name <span style="color: var(--accent-red); font-size: 12px;">(Immune to CC)</span>`,
|
||||
tankRelevant: true,
|
||||
abilitiesHtml: [
|
||||
`<a href="https://www.wowhead.com/beta/spell=123456/ability-name">Ability Name</a> — TANK: What to do.`,
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "boss",
|
||||
data: {
|
||||
bossNumber: "Boss 1 · Area/Wing",
|
||||
name: "Boss Name",
|
||||
subtitle: "One-line fight summary",
|
||||
image: "/assets/boss_name_boss_fight.jpg",
|
||||
abilities: [
|
||||
{
|
||||
name: "Ability Name",
|
||||
wowheadUrl: "https://www.wowhead.com/beta/spell=123456/ability-name",
|
||||
role: "tank",
|
||||
importance: "tank-important",
|
||||
descriptionHtml: `<ul><li><span class="warn">Warning.</span></li></ul>`,
|
||||
},
|
||||
{
|
||||
name: "Ability Name",
|
||||
wowheadUrl: "https://www.wowhead.com/beta/spell=123457/ability-name",
|
||||
role: "everyone",
|
||||
importance: "everyone-important",
|
||||
descriptionHtml: `<ul><li>Description.</li></ul>`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{ type: "divider" },
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## Registering in index.ts
|
||||
|
||||
```typescript
|
||||
import { dungeonSlug } from "./dungeon-slug";
|
||||
|
||||
// In dungeonList (alphabetical):
|
||||
{ id: "dungeon-slug", name: "Dungeon Name", icon: "/assets/dungeon_dungeon_name.jpg" },
|
||||
|
||||
// In dungeonDataMap:
|
||||
"dungeon-slug": dungeonSlug,
|
||||
```
|
||||
|
||||
## Roles & Importance
|
||||
|
||||
| Role | Importance | Visual |
|
||||
|------|-----------|--------|
|
||||
| `"tank"` | `"tank-important"` | Blue left border + badge |
|
||||
| `"everyone"` | `"everyone-important"` | Amber left border + badge |
|
||||
| `"healer"` | `"healer-important"` | Green left border + badge |
|
||||
| `"dps"` | `null` | Red badge, no border |
|
||||
|
||||
## HTML Classes: `warn` (red), `tip` (green), `wing-badge wing-arcane/void/light`
|
||||
|
||||
## Wowhead: `<a href="https://www.wowhead.com/beta/spell={ID}/{slug}">Name</a>`
|
||||
145
.claude/skills/parse-dungeon/SKILL.md
Normal file
145
.claude/skills/parse-dungeon/SKILL.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
name: parse-dungeon
|
||||
description: Parses a method.gg dungeon HTML file and adds it to the M+ dungeon reference webapp. Use when the user wants to add a new dungeon, parse a dungeon HTML file, or generate guide content from a dungeon file in the dungeons/ directory.
|
||||
---
|
||||
|
||||
# Parse Dungeon Guide
|
||||
|
||||
Extracts boss info, trash mechanics, and assets from a method.gg dungeon HTML file, then adds the dungeon as a new TypeScript data file in the React webapp.
|
||||
|
||||
## Project Structure
|
||||
|
||||
This is a **React + Vite + shadcn/ui** app. Dungeon content lives in typed data files, not raw HTML.
|
||||
|
||||
- `src/data/*.ts` — one file per dungeon (e.g., `nexus-point-xenas.ts`)
|
||||
- `src/data/index.ts` — ordered dungeon list + data map exports
|
||||
- `src/types/dungeon.ts` — TypeScript types for all data structures
|
||||
- `src/components/dungeon/` — React components that render dungeon data
|
||||
- `public/assets/` — all images (dungeon headers, boss screenshots, dungeon icons)
|
||||
- `parse_dungeon.py` — Python script to extract raw data from method.gg HTML
|
||||
|
||||
## Step 1: Parse the HTML
|
||||
|
||||
Run the extraction script against the target dungeon file:
|
||||
|
||||
```bash
|
||||
source ~/.zshrc && poetry run python parse_dungeon.py dungeons/<filename>.html
|
||||
```
|
||||
|
||||
If the script doesn't accept a CLI argument yet, update `parse_dungeon.py` to accept one via `sys.argv[1]`.
|
||||
|
||||
The script extracts:
|
||||
- **Section content** — full text of each `guide-section-title` section
|
||||
- **Boss images** — `img.section-boss` saved to `public/assets/`
|
||||
- **Mob icons** — `div.mob-icon img` saved to `public/assets/`
|
||||
- **Dungeon header image** — `img.boss--render` saved to `public/assets/`
|
||||
- **Spell links** — all wowhead spell references with context
|
||||
|
||||
**Important:** Images must be saved to `public/assets/`, not `assets/`.
|
||||
|
||||
## Step 2: Identify content
|
||||
|
||||
From the parsed output, identify:
|
||||
|
||||
1. **Bosses** — sections ending in "Boss Fight" (e.g., "Vexamus Boss Fight")
|
||||
2. **Trash sections** — sections ending in "Trash" (e.g., "Vexamus Trash")
|
||||
3. **Mob names** — `h4.mob-name` elements within trash sections
|
||||
4. **Role-specific mechanics** — identify abilities by role:
|
||||
- **Tank:** tank, taunt, face away, defensive, positioning, aggro, kite, knockback, damage taken increase, swap, active mitigation
|
||||
- **Healer:** heavy damage, healing absorb, dispel, disease, poison, curse, magic debuff, raid damage, heal check, ticking DoT
|
||||
- **DPS:** interrupt, CC, burn target, add priority, enrage timer, soothe, purge, DPS check
|
||||
- **Everyone:** dodge, soak, spread, stack, move, kill order, frontal, AoE avoidance
|
||||
|
||||
## Step 3: Create the data file
|
||||
|
||||
Create a new TypeScript file at `src/data/<dungeon-slug>.ts` following the types in `src/types/dungeon.ts`.
|
||||
|
||||
Reference an existing dungeon data file (e.g., `src/data/nexus-point-xenas.ts`) for the exact structure.
|
||||
|
||||
The file must:
|
||||
- Import and conform to `DungeonData` from `@/types/dungeon`
|
||||
- Export a named constant (camelCase of slug, e.g., `pitOfSaron`)
|
||||
- Use HTML strings for rich content (Wowhead links, `<span class="warn">`, etc.) via template literals
|
||||
- Image paths use `/assets/` prefix (served from `public/assets/`)
|
||||
|
||||
Key rules:
|
||||
- **Brevity is critical.** 1-2 sentences max per ability. No paragraphs.
|
||||
- **Include all role-relevant mechanics.** Every boss should have cards for each role that has a distinct responsibility.
|
||||
- **Use role tags:** `tank`, `healer`, `dps`, `everyone` to classify each ability card.
|
||||
- **Role-importance mapping:**
|
||||
- `role: "tank"` → `importance: "tank-important"` (sky-blue left border)
|
||||
- `role: "healer"` → `importance: "healer-important"` (green left border)
|
||||
- `role: "everyone"` → `importance: "everyone-important"` or `null` (amber left border or none)
|
||||
- `role: "dps"` → `importance: null` (red badge, no left border)
|
||||
- **Ability card order per boss:** tank first, then healer, then everyone, then dps.
|
||||
- **Ability descriptions use bullet points** — HTML `<ul><li>...</li></ul>` in the `descriptionHtml` field.
|
||||
- **Mark CC-immune mobs** with `nameHtml` containing a red "(Immune to CC)" span.
|
||||
- **Highlight warnings** with `<span class="warn">` and tips with `<span class="tip">`.
|
||||
- **Environment/quick-ref** content uses `{ type: "quickRef", data: { html: "..." } }` in trash section content arrays.
|
||||
|
||||
## Step 4: Register the dungeon
|
||||
|
||||
Update `src/data/index.ts`:
|
||||
|
||||
1. Add the import for the new dungeon data file
|
||||
2. If replacing a disabled entry in `dungeonList`, remove the `disabled: true` flag
|
||||
3. Add the dungeon to `dungeonDataMap`
|
||||
|
||||
## Step 5: Verify
|
||||
|
||||
```bash
|
||||
make dev
|
||||
```
|
||||
|
||||
- The new dungeon tab appears in the sidebar and is clickable
|
||||
- All boss images render correctly from `public/assets/`
|
||||
- Every boss has a section with abilities
|
||||
- Tank-critical abilities are not missed
|
||||
- Wowhead tooltip links work (hover to verify)
|
||||
- Text is concise — cut any filler words
|
||||
|
||||
## Data Structure Reference
|
||||
|
||||
See `src/types/dungeon.ts` for full types. Key structures:
|
||||
|
||||
```typescript
|
||||
// Dungeon data file exports:
|
||||
export const dungeonSlug: DungeonData = {
|
||||
id: "dungeon-slug", // URL hash
|
||||
name: "Dungeon Name",
|
||||
descriptionHtml: "...", // May contain wing badge spans
|
||||
headerImage: "/assets/dungeon_header.jpg",
|
||||
icon: "/assets/dungeon_icon.jpg",
|
||||
sections: [
|
||||
{ type: "trash", data: { header: "...", content: [...] } },
|
||||
{ type: "boss", data: { bossNumber: "Boss 1 · Wing", name: "...", ... } },
|
||||
{ type: "divider" },
|
||||
// repeat...
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## Wowhead Spell Links
|
||||
|
||||
All ability names must be wowhead links in the HTML strings.
|
||||
|
||||
Format: `<a href="https://www.wowhead.com/beta/spell={ID}/{slug}">Ability Name</a>`
|
||||
|
||||
- The spell ID comes from the parser output (SPELLS WITH CONTEXT section).
|
||||
- The slug is the spell name lowercased with hyphens.
|
||||
- The React app handles tooltip initialization automatically via `useWowheadTooltips` hook.
|
||||
|
||||
## Writing Style
|
||||
|
||||
- **Max 1-2 sentences per ability point.** No paragraphs.
|
||||
- **Use bullet points** — `<ul><li>...</li></ul>` in descriptionHtml.
|
||||
- **Lead with the ability name** as a wowhead link, followed by a dash and the description.
|
||||
- **Ability order:** tank, healer, everyone, dps in each boss's abilities array.
|
||||
- **Tank actions** should be explicit: "Face away", "Use defensive", "Pick up adds", "Position at edge".
|
||||
- **Healer actions** should be explicit: "Dispel immediately", "Heavy healing required", "Heal absorb — heal through before next cast".
|
||||
- **DPS actions** should be explicit: "Interrupt on cooldown", "Burn adds before X", "Soothe enrage".
|
||||
- **Use `warn` for dangers** any role MUST react to.
|
||||
- **Use `tip` for helpful tricks.**
|
||||
- **Include all role-relevant mechanics.** Tag each ability with the most specific role responsible for handling it.
|
||||
- Every boss should have at minimum one `tank-important` card if there is ANY tank-specific mechanic.
|
||||
- Include healer and DPS cards where mechanics specifically require those roles to act.
|
||||
Reference in New Issue
Block a user