playlist-data-engine 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +14 -0
  2. package/bin/cli.cjs +85 -0
  3. package/dist/gateway-CDMPqFEH.js +1320 -0
  4. package/dist/gateway-DKa45Uz6.cjs +6 -0
  5. package/dist/gateway.d.ts +1 -0
  6. package/dist/gateway.d.ts.map +1 -1
  7. package/dist/gateway.js +1 -1
  8. package/dist/gateway.mjs +22 -19
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/playlist-data-engine.js +4 -4
  12. package/dist/playlist-data-engine.mjs +30 -27
  13. package/dist/utils/engineDocs.d.ts +33 -0
  14. package/dist/utils/engineDocs.d.ts.map +1 -0
  15. package/docs/DATA_ENGINE_REFERENCE.md +6660 -0
  16. package/docs/USAGE_IN_OTHER_PROJECTS.md +587 -0
  17. package/docs/features/AUDIO_ANALYSIS.md +610 -0
  18. package/docs/features/BEAT_DETECTION.md +5250 -0
  19. package/docs/features/COMBAT_SYSTEM.md +1632 -0
  20. package/docs/features/CONTENT_PACKS.md +464 -0
  21. package/docs/features/CUSTOM_CONTENT.md +603 -0
  22. package/docs/features/ENEMY_GENERATION.md +1711 -0
  23. package/docs/features/EQUIPMENT_SYSTEM.md +2279 -0
  24. package/docs/features/EXTENSIBILITY_GUIDE.md +1106 -0
  25. package/docs/features/GATEWAY_RESOLUTION.md +725 -0
  26. package/docs/features/IRL_SENSORS.md +360 -0
  27. package/docs/features/PLAYLIST_PARSING.md +446 -0
  28. package/docs/features/PREREQUISITES.md +571 -0
  29. package/docs/features/ROLLS_AND_SEEDS.md +687 -0
  30. package/docs/features/XP_AND_STATS.md +1221 -0
  31. package/llms.txt +33 -0
  32. package/package.json +9 -2
  33. package/skills/playlist-data-engine/SKILL.md +69 -0
  34. package/dist/gateway-C_p9Ku3O.js +0 -1211
  35. package/dist/gateway-Ceg-5xug.cjs +0 -1
@@ -0,0 +1,571 @@
1
+ # Prerequisites Reference
2
+
3
+ Complete guide to the prerequisite system for skills, spells, and features in the Playlist Data Engine.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Overview](#overview)
10
+ 2. [Skill Prerequisites](#skill-prerequisites)
11
+ 3. [Spell Prerequisites](#spell-prerequisites)
12
+ 4. [Feature Prerequisites](#feature-prerequisites)
13
+ 5. [Validation System](#validation-system)
14
+ 6. [Examples](#examples)
15
+ 7. [API Reference](#api-reference)
16
+ 8. [Best Practices](#best-practices)
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ The Playlist Data Engine supports a comprehensive prerequisite system that allows skills, spells, and features to require specific conditions before they can be learned or used.
23
+
24
+ ### Key Features
25
+
26
+ - **Skill Prerequisites**: Skills can require levels, abilities, other skills, features, or spells
27
+ - **Spell Prerequisites**: Spells can require levels, abilities, features, other spells, or skills
28
+ - **Feature Prerequisites**: Features can require levels, abilities, skills, spells, or subraces
29
+
30
+ ### Design Principles
31
+
32
+ - **Backward Compatible**: Existing skills, spells, races, and characters continue to work
33
+ - **Consistent Pattern**: All prerequisite types follow the same `FeaturePrerequisite` pattern
34
+ - **Validation First**: All prerequisites validated before assignment
35
+ - **Type Safe**: Full TypeScript type safety maintained
36
+ - **Extensible**: Custom content registered same as default content
37
+
38
+ ---
39
+
40
+ ## Skill Prerequisites
41
+
42
+ Skills can have prerequisites that must be met before a character can gain proficiency in them.
43
+
44
+ ### SkillPrerequisite
45
+
46
+ *Also known as: skill requirements, skill conditions*
47
+
48
+ Defines conditions that must be met before a character can gain proficiency in a skill.
49
+
50
+ **Location:** [`src/core/skills/SkillTypes.ts`](src/core/skills/SkillTypes.ts#L23-L47)
51
+
52
+ | Property | Type | Description |
53
+ |----------|------|-------------|
54
+ | `level` | `number?` | Minimum character level required |
55
+ | `abilities` | `Partial<Record<Ability, number>>?` | Minimum ability scores (STR/DEX/CON/INT/WIS/CHA) |
56
+ | `class` | `Class?` | Specific class required |
57
+ | `race` | `Race?` | Specific race required |
58
+ | `skills` | `string[]?` | Skills that must be proficient first (by skill ID) |
59
+ | `features` | `string[]?` | Features that must be learned first (by feature ID) |
60
+ | `spells` | `string[]?` | Spells that must be known first (by spell name) |
61
+ | `custom` | `string?` | Custom condition description (display only) |
62
+
63
+ ### CustomSkill.prerequisites
64
+
65
+ **Location:** [`src/core/skills/SkillTypes.ts`](src/core/skills/SkillTypes.ts#L128)
66
+
67
+ The `CustomSkill` interface includes an optional `prerequisites?: SkillPrerequisite` property. When specified, the skill is filtered out during character generation if prerequisites are unmet.
68
+
69
+ ### Validation
70
+
71
+ Skill prerequisites are validated automatically during:
72
+
73
+ 1. **Skill Registration**: Schema validation ensures prerequisite structure is valid
74
+ 2. **Skill Assignment**: During character generation, skills with unmet prerequisites are filtered out
75
+ 3. **Manual Validation**: Use `SkillValidator.validateSkillPrerequisites()` or `SkillQuery.validatePrerequisites()`
76
+
77
+ ### Example Skills with Prerequisites
78
+
79
+ | Skill | Prerequisites Used |
80
+ |-------|-------------------|
81
+ | Dragon Smithing | `features`, `level`, `class` |
82
+ | Advanced Arcana | `abilities`, `skills`, `level` |
83
+ | Spell Mastery | `spells`, `class`, `level` |
84
+ | Dwarven Warfare | `race` |
85
+
86
+ ```typescript
87
+ import { ExtensionManager } from 'playlist-data-engine';
88
+
89
+ const skills = [
90
+ {
91
+ id: 'dragon_smithing',
92
+ name: 'Dragon Smithing',
93
+ description: 'Craft weapons from dragon scales',
94
+ ability: 'INT' as const,
95
+ prerequisites: {
96
+ features: ['draconic_bloodline'],
97
+ level: 5,
98
+ class: 'Sorcerer' as const
99
+ },
100
+ source: 'custom' as const
101
+ },
102
+ {
103
+ id: 'advanced_arcana',
104
+ name: 'Advanced Arcana',
105
+ description: 'Cast complex spells and understand magical theory',
106
+ ability: 'INT' as const,
107
+ prerequisites: {
108
+ abilities: { INT: 16 },
109
+ skills: ['arcana'],
110
+ level: 7
111
+ },
112
+ source: 'custom' as const
113
+ },
114
+ {
115
+ id: 'spell_mastery',
116
+ name: 'Spell Mastery',
117
+ description: 'Improved control over known spells',
118
+ ability: 'INT' as const,
119
+ prerequisites: {
120
+ spells: ['Fireball', 'Lightning Bolt'],
121
+ class: 'Wizard' as const,
122
+ level: 10
123
+ },
124
+ source: 'custom' as const
125
+ },
126
+ {
127
+ id: 'dwarven_warfare',
128
+ name: 'Dwarven Warfare',
129
+ description: 'Advanced dwarven combat techniques',
130
+ ability: 'STR' as const,
131
+ prerequisites: {
132
+ race: 'Dwarf' as const
133
+ },
134
+ source: 'custom' as const
135
+ }
136
+ ];
137
+
138
+ ExtensionManager.getInstance().register('skills', skills);
139
+ ```
140
+
141
+ ## Spell Prerequisites
142
+
143
+ Spells can have prerequisites that must be met before they can be learned.
144
+
145
+ ### SpellPrerequisite
146
+
147
+ *Also known as: spell requirements, spell conditions*
148
+
149
+ Defines conditions that must be met before a spellcaster can learn a spell.
150
+
151
+ **Location:** [`src/core/spells/SpellTypes.ts`](src/core/spells/SpellTypes.ts#L32-L59)
152
+
153
+ | Property | Type | Description |
154
+ |----------|------|-------------|
155
+ | `level` | `number?` | Minimum character level |
156
+ | `casterLevel` | `number?` | Minimum spellcaster level (if different from character level) |
157
+ | `abilities` | `Partial<Record<Ability, number>>?` | Minimum ability scores |
158
+ | `class` | `Class?` | Specific class required |
159
+ | `race` | `Race?` | Specific race required |
160
+ | `features` | `string[]?` | Features that must be learned first (by feature ID) |
161
+ | `spells` | `string[]?` | Spells that must be known first (by spell name) |
162
+ | `skills` | `string[]?` | Skills that must be proficient first (by skill ID) |
163
+ | `custom` | `string?` | Custom condition description (display only) |
164
+
165
+ ### Spell.prerequisites
166
+
167
+ **Location:** [`src/core/spells/SpellTypes.ts`](src/core/spells/SpellTypes.ts#L80)
168
+
169
+ The `Spell` interface includes an optional `prerequisites?: SpellPrerequisite` property. `SpellManager` automatically filters spells by prerequisites during character generation.
170
+
171
+ ### Validation
172
+
173
+ Spell prerequisites are validated automatically during:
174
+
175
+ 1. **Spell Registration**: Schema validation via `SpellValidator.validateSpell()`
176
+ 2. **Spell Assignment**: During character generation, `SpellManager` filters spells by prerequisites
177
+ 3. **Manual Validation**: Use `SpellValidator.validateSpellPrerequisites()`
178
+
179
+ ### Example Spells with Prerequisites
180
+
181
+ ```typescript
182
+ import { ExtensionManager, SpellManager, CharacterGenerator } from 'playlist-data-engine';
183
+
184
+ // Spell with feature + ability prerequisites
185
+ const dragonBreath = {
186
+ id: 'dragon_breath',
187
+ name: 'Dragon Breath',
188
+ level: 3,
189
+ school: 'Evocation',
190
+ casting_time: '1 action',
191
+ range: '60 ft cone',
192
+ components: ['V', 'S', 'M'],
193
+ duration: 'Instantaneous',
194
+ description: 'Exhale destructive energy',
195
+ prerequisites: {
196
+ features: ['dragon_bloodline'],
197
+ abilities: { CHA: 16 }
198
+ }
199
+ };
200
+
201
+ // Spell with level + class + spell prerequisites
202
+ const limitedMeteorSwarm = {
203
+ id: 'limited_meteor_swarm',
204
+ name: 'Meteor Swarm',
205
+ level: 9,
206
+ school: 'Evocation',
207
+ casting_time: '1 action',
208
+ range: '1 mile',
209
+ components: ['V', 'S'],
210
+ duration: 'Instantaneous',
211
+ description: 'Blazing orbs rain down',
212
+ prerequisites: {
213
+ level: 17,
214
+ class: 'Wizard',
215
+ spells: ['Fireball']
216
+ }
217
+ };
218
+
219
+ // Spell with skill prerequisites
220
+ const arcaneSwordSpell = {
221
+ id: 'arcane_sword',
222
+ name: 'Arcane Sword',
223
+ level: 5,
224
+ school: 'Evocation',
225
+ casting_time: '1 bonus action',
226
+ range: '60 ft',
227
+ components: ['V', 'S', 'M'],
228
+ duration: 'Concentration, 1 minute',
229
+ description: 'Summon a sword of pure magic',
230
+ prerequisites: {
231
+ skills: ['arcana']
232
+ }
233
+ };
234
+
235
+ const manager = ExtensionManager.getInstance();
236
+ manager.register('spells', [dragonBreath, limitedMeteorSwarm, arcaneSwordSpell]);
237
+
238
+ // SpellManager automatically filters spells by prerequisites during character generation
239
+ const character = CharacterGenerator.generate(seed, audioProfile, track);
240
+ const knownSpells = SpellManager.getKnownSpells(character.class, character.level, character);
241
+ // Only includes spells whose prerequisites are met
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Feature Prerequisites
247
+
248
+ Features (class features and racial traits) can have prerequisites that must be met.
249
+
250
+ ### FeaturePrerequisite
251
+
252
+ *Also known as: feature requirements, trait conditions*
253
+
254
+ Defines conditions for class features and racial traits. Note: `SkillPrerequisite` and `SpellPrerequisite` follow the same pattern for consistency.
255
+
256
+ **Location:** [`src/core/features/FeatureTypes.ts`](src/core/features/FeatureTypes.ts#L67-L94)
257
+
258
+ | Property | Type | Description |
259
+ |----------|------|-------------|
260
+ | `level` | `number?` | Minimum level required |
261
+ | `features` | `string[]?` | Features that must be learned first (by ID) |
262
+ | `abilities` | `Partial<Record<Ability, number>>?` | Minimum ability scores required |
263
+ | `class` | `Class?` | Specific class required |
264
+ | `race` | `Race?` | Specific race required |
265
+ | `subrace` | `string?` | Specific subrace required (e.g., 'High Elf', 'Hill Dwarf') |
266
+ | `skills` | `string[]?` | Skills that must be proficient first (by skill ID) |
267
+ | `spells` | `string[]?` | Spells that must be known first (by spell name) |
268
+ | `custom` | `string?` | Custom condition description (display only) |
269
+
270
+ ### Validation
271
+
272
+ Feature prerequisites are validated via `FeatureQuery.validatePrerequisites()` which checks level, abilities, class, race, subrace, skills, spells, features, and custom conditions.
273
+
274
+ ### Example Features with Prerequisites
275
+
276
+ | Feature | Type | Prerequisites Used |
277
+ |---------|------|-------------------|
278
+ | Arcane Mastery | Class feature | `skills`, `level` |
279
+ | Spellblade | Class feature | `spells`, `features` |
280
+ | Elven Battle Training | Racial trait | `skills`, `level` |
281
+
282
+ ```typescript
283
+ import { ExtensionManager } from 'playlist-data-engine';
284
+
285
+ // Class features
286
+ ExtensionManager.getInstance().register('classFeatures', [
287
+ {
288
+ id: 'arcane_mastery',
289
+ name: 'Arcane Mastery',
290
+ description: 'Bonus to spellcasting based on Arcana skill',
291
+ type: 'passive' as const,
292
+ level: 10,
293
+ class: 'Wizard' as const,
294
+ prerequisites: {
295
+ skills: ['arcana'],
296
+ level: 10
297
+ },
298
+ effects: [
299
+ { type: 'passive_modifier' as const, target: 'spell_save_dc', value: 1 }
300
+ ],
301
+ source: 'custom' as const
302
+ },
303
+ {
304
+ id: 'spellblade',
305
+ name: 'Spellblade',
306
+ description: 'Channel spells through your weapon',
307
+ type: 'active' as const,
308
+ level: 10,
309
+ class: 'Eldritch Knight' as const,
310
+ prerequisites: {
311
+ spells: ['Green-Flame Blade', 'Booming Blade'],
312
+ features: ['weapon_bond']
313
+ },
314
+ effects: [
315
+ { type: 'passive_modifier' as const, target: 'spell_strike_damage', value: 4 }
316
+ ],
317
+ source: 'custom' as const
318
+ }
319
+ ]);
320
+
321
+ // Racial traits
322
+ ExtensionManager.getInstance().register('racialTraits', [{
323
+ id: 'elven_battle_training',
324
+ name: 'Elven Battle Training',
325
+ description: 'Advanced elven combat techniques',
326
+ type: 'active' as const,
327
+ race: 'Elf' as const,
328
+ prerequisites: {
329
+ skills: ['athletics', 'perception'],
330
+ level: 3
331
+ },
332
+ effects: [
333
+ { type: 'passive_modifier' as const, target: 'initiative', value: 2 }
334
+ ],
335
+ source: 'custom' as const
336
+ }]);
337
+ ```
338
+
339
+ ## Validation System
340
+
341
+ ### ValidationResult Interfaces
342
+
343
+ | Type | Location | Properties |
344
+ |------|----------|------------|
345
+ | `ValidationResult` | [`src/core/features/FeatureTypes.ts`](src/core/features/FeatureTypes.ts#L238-L247) | `valid: boolean`, `unmet?: string[]`, `errors?: string[]` |
346
+ | `SkillValidationResult` | [`src/core/skills/SkillTypes.ts`](src/core/skills/SkillTypes.ts#L239-L244) | `valid: boolean`, `errors: string[]` (required) |
347
+ | `SpellValidationResult` | Inferred from `SpellValidator` | `valid: boolean`, `errors: string[]` (required) |
348
+
349
+ ### Skill Validation
350
+
351
+ ```typescript
352
+ import { SkillValidator, SkillQuery } from 'playlist-data-engine';
353
+
354
+ // Direct validation
355
+ const result = SkillValidator.validateSkillPrerequisites(
356
+ skill.prerequisites,
357
+ character
358
+ );
359
+
360
+ // Via registry
361
+ const result2 = SkillQuery.getInstance().validatePrerequisites(skill, character);
362
+
363
+ if (!result.valid) {
364
+ console.log('Unmet prerequisites:', result.errors);
365
+ }
366
+ ```
367
+
368
+ ### Spell Validation
369
+
370
+ ```typescript
371
+ import { SpellValidator, validateSpellPrerequisites } from 'playlist-data-engine';
372
+
373
+ // Direct validation
374
+ const result = SpellValidator.validateSpellPrerequisites(
375
+ spell.prerequisites,
376
+ character
377
+ );
378
+
379
+ // Helper function
380
+ const result2 = validateSpellPrerequisites(spell.prerequisites, character);
381
+
382
+ if (!result.valid) {
383
+ console.log('Unmet prerequisites:', result.errors);
384
+ }
385
+ ```
386
+
387
+ ### Feature Validation
388
+
389
+ ```typescript
390
+ import { FeatureQuery } from 'playlist-data-engine';
391
+
392
+ const registry = FeatureQuery.getInstance();
393
+
394
+ const result = registry.validatePrerequisites(feature, character);
395
+
396
+ // Access unmet prerequisites (FeatureQuery-specific)
397
+ if (!result.valid) {
398
+ console.log('Unmet prerequisites:', result.unmet || result.errors);
399
+ }
400
+
401
+ // Or check boolean directly
402
+ const canLearn = registry.meetsPrerequisites(feature, character);
403
+ ```
404
+
405
+ ---
406
+
407
+ ### Prerequisite Validation Rules
408
+
409
+ | Field | Schema Validation | Runtime Check |
410
+ |-------|------------------|---------------|
411
+ | `level` | Number between 1-20 | Compares character level against required |
412
+ | `abilities` | Valid ability keys, scores 1-20 | Checks ability scores meet minimum |
413
+ | `class` | Valid D&D 5e class or registered custom class | Matches character's class |
414
+ | `race` | Valid default race or registered custom race | Matches character's race |
415
+ | `subrace` | Non-empty string | Matches character's subrace |
416
+ | `features` | Array of feature ID strings | IDs in `class_features` array |
417
+ | `skills` | Valid skill IDs (lowercase_with_underscores) | Skills proficient or expertise |
418
+ | `spells` | Array of spell name strings | In `known_spells` or `cantrips` |
419
+ | `custom` | String | Displayed only, not validated |
420
+
421
+ ---
422
+
423
+ ## Examples
424
+
425
+ ### Subrace-Specific Prerequisites
426
+
427
+ Races with subraces can have traits that only apply to specific subraces using the `subrace` prerequisite field:
428
+
429
+ ```typescript
430
+ import { ExtensionManager } from 'playlist-data-engine';
431
+
432
+ // Register a custom race with subraces
433
+ const manager = ExtensionManager.getInstance();
434
+ manager.register('races.data', [{
435
+ race: 'Dragonkin',
436
+ ability_bonuses: { STR: 2, CON: 1, CHA: 1 },
437
+ speed: 30,
438
+ traits: ['Draconic Ancestry', 'Darkvision'],
439
+ subraces: ['Fire Dragonkin', 'Ice Dragonkin', 'Lightning Dragonkin']
440
+ }]);
441
+ manager.register('races', ['Dragonkin']);
442
+
443
+ // Register a subrace-specific trait
444
+ manager.register('racialTraits', [{
445
+ id: 'fire_dragonkin_fire_resistance',
446
+ name: 'Fire Resistance',
447
+ description: 'You have resistance to fire damage.',
448
+ race: 'Dragonkin',
449
+ subrace: 'Fire Dragonkin',
450
+ prerequisites: { subrace: 'Fire Dragonkin' }, // Only Fire Dragonkin get this
451
+ effects: [
452
+ { type: 'ability_unlock', target: 'fire_resistance', value: true }
453
+ ],
454
+ source: 'custom'
455
+ }]);
456
+ ```
457
+
458
+ ### Example: Prerequisite Chains
459
+
460
+ Skills and spells can form chains by requiring each other:
461
+
462
+ ```typescript
463
+ // Basic skill
464
+ const herbLore = {
465
+ id: 'herb_lore',
466
+ name: 'Herb Lore',
467
+ ability: 'WIS',
468
+ source: 'custom'
469
+ };
470
+
471
+ // Advanced skill requiring the basic one
472
+ const advancedHerbalism = {
473
+ id: 'advanced_herbalism',
474
+ name: 'Advanced Herbalism',
475
+ ability: 'INT',
476
+ prerequisites: {
477
+ skills: ['herb_lore'], // Must know Herb Lore first
478
+ level: 5
479
+ },
480
+ source: 'custom'
481
+ };
482
+
483
+ // Master skill requiring both
484
+ const masterHerbalist = {
485
+ id: 'master_herbalist',
486
+ name: 'Master Herbalist',
487
+ ability: 'INT',
488
+ prerequisites: {
489
+ skills: ['herb_lore', 'advanced_herbalism'],
490
+ features: [' Herbalist_certification'],
491
+ level: 10
492
+ },
493
+ source: 'custom'
494
+ };
495
+ ```
496
+
497
+ ---
498
+
499
+ ## API Reference
500
+
501
+ ### SkillValidator
502
+
503
+ **Location:** [`src/core/skills/SkillValidator.ts`](src/core/skills/SkillValidator.ts)
504
+
505
+ | Method | Returns | Description |
506
+ |--------|---------|-------------|
507
+ | `validateSkillPrerequisites(prerequisites, character)` | `SkillValidationResult` | Validate skill prerequisites against a character |
508
+ | `validateSkill(skill)` | `SkillValidationResult` | Validate skill schema including prerequisites |
509
+
510
+ ### SpellValidator
511
+
512
+ **Location:** [`src/core/spells/SpellValidator.ts`](src/core/spells/SpellValidator.ts)
513
+
514
+ | Method | Returns | Description |
515
+ |--------|---------|-------------|
516
+ | `validateSpellPrerequisites(prerequisites, character)` | `SpellValidationResult` | Validate spell prerequisites against a character |
517
+ | `validateSpell(spell)` | `boolean` | Validate spell schema including prerequisites |
518
+
519
+ ### FeatureQuery
520
+
521
+ **Location:** [`src/core/features/FeatureQuery.ts`](src/core/features/FeatureQuery.ts)
522
+
523
+ | Method | Returns | Description |
524
+ |--------|---------|-------------|
525
+ | `validatePrerequisites(feature, character)` | `ValidationResult` | Validate feature prerequisites against a character |
526
+ | `meetsPrerequisites(feature, character)` | `boolean` | Boolean check if prerequisites are met |
527
+ | `getRacialTraitsForSubrace(race, subrace)` | `RacialTrait[]` | Get traits for a specific subrace |
528
+
529
+ ### SkillQuery
530
+
531
+ **Location:** [`src/core/skills/SkillQuery.ts`](src/core/skills/SkillQuery.ts)
532
+
533
+ | Method | Returns | Description |
534
+ |--------|---------|-------------|
535
+ | `validatePrerequisites(skill, character)` | `SkillValidationResult` | Validate skill prerequisites via SkillQuery |
536
+
537
+ ### ExtensionManager
538
+
539
+ **Location:** [`src/core/extensions/ExtensionManager.ts`](src/core/extensions/ExtensionManager.ts)
540
+
541
+ | Method | Returns | Description |
542
+ |--------|---------|-------------|
543
+ | `register(category, items, options?)` | `void` | Register custom races, spells, skills, features, or other content |
544
+
545
+ ---
546
+
547
+ ## Best Practices
548
+
549
+ 1. **Use Prerequisites Judiciously**: Not every skill/spell needs prerequisites. Use them for:
550
+ - Advanced/specialized content
551
+ - Class or race-specific abilities
552
+ - Progression chains (basic → advanced → master)
553
+
554
+ 2. **Provide Clear Descriptions**: When a prerequisite isn't met, the error message should clearly explain why
555
+
556
+ 3. **Test Prerequisite Chains**: If skills/spells require each other, ensure there are no circular dependencies
557
+
558
+ 4. **Consider Custom Conditions**: Use the `custom` field for prerequisites that don't fit the standard types
559
+
560
+ 5. **Document Custom Content**: When creating custom content with prerequisites, document the requirements clearly
561
+
562
+ ---
563
+
564
+ ## See Also
565
+
566
+ - [DATA_ENGINE_REFERENCE.md](../DATA_ENGINE_REFERENCE.md) - Complete API reference
567
+ - [CUSTOM_CONTENT.md](CUSTOM_CONTENT.md) - Custom races and classes guide
568
+ - [USAGE_IN_OTHER_PROJECTS.md](../USAGE_IN_OTHER_PROJECTS.md) - Usage examples
569
+ - [EXTENSIBILITY_GUIDE.md](EXTENSIBILITY_GUIDE.md) - Custom content registration
570
+ - [XP_AND_STATS.md](XP_AND_STATS.md) - Progression and level requirements
571
+ - [EQUIPMENT_SYSTEM.md](EQUIPMENT_SYSTEM.md) - Equipment with prerequisites