# @maya/npc-occupations

40+ NPC occupation templates with work behavior, production, skill progression,
career dynamics, and world-generation job assignment (phase 79.26).

## Modules

| Module         | Role                                                                 |
| -------------- | -------------------------------------------------------------------- |
| `schema.ts`    | The `Occupation` definition type + validation                        |
| `templates.ts` | 50 occupation templates across the nine categories                   |
| `work.ts`      | Work actions, economic output, skill progression, breaks, shifts     |
| `career.ts`    | Hire/fire/change/apprentice/retire, unemployment, player commissions |
| `worldgen.ts`  | Needs-driven occupation assignment during world generation           |

## Quick start

```ts
import {
  getOccupation,
  produceOutput,
  gainSkill,
  assignOccupations,
} from '@maya/npc-occupations';

const smith = getOccupation('blacksmith')!;
const dayOutput = produceOutput(smith, /* skill */ 60, /* hoursWorked */ 10);
// → [{ good: 'tools', quantity: 3, quality: 0.72 }, { good: 'weapons', quantity: 1, ... }]

// Populate a fortress town of 100:
const jobs = assignOccupations(100, {
  food: 2,
  defense: 6,
  craft: 2,
  trade: 1,
  service: 1,
  faith: 1,
  governance: 1,
  entertainment: 1,
});
```

## Authoring a new occupation template

1. Add an `occ({ ... })` entry to `OCCUPATIONS` in `templates.ts`:

   ```ts
   occ({
     id: 'cartographer',          // unique, snake_case
     name: 'Cartographer',
     category: 'craft',           // one of the nine OccupationCategory values
     skills: ['scholarship'],     // Skill[] the job exercises
     workplace: 'workshop',
     outputs: [['maps', 2]],      // [good, baseQuantityPerFullDayAtSkill0]
     income: 15,                  // daily coins at competent skill
     socialClass: 'middle',
     // schedule?: defaults to DAY (08-18, break 13); pass EARLY/NIGHT or a custom window
     // nightShift?: true only for wrap-around (endHour < startHour) schedules
   }),
   ```

2. If the occupation needs a bespoke action sequence, add a `case` to
   `workActions()` in `work.ts`; otherwise it inherits its category's default.
3. `validateOccupation()` runs over every template in the test suite — keep
   hours in `[0, 24)`, income and output quantities non-negative.
4. World-gen picks up the new template automatically via its category.

## Scope

The economy-system integration (§79.26.1.12) lives in the economy domain
(§79.28); this library is the occupation model that feeds it.
