# mod-hirelings — Plan

Fun/QoL project: FFXIV-retainer-style hirelings, built goblin-flavored and AC-native rather than
importing FFXIV terminology. Hire a hireling, send them on a job, get crafting materials/rare
minions/etc back via mail -- whether or not you're online when the timer ends. Additive, not a
bank replacement.

## Design pillars

- **Goblin/Steamwheedle Cartel flavor**, not FFXIV terms. "Hirelings," not "Retainers." Mail
  arrives from a Steamwheedle-flavored sender identity, giving an in-fiction reason jobs resolve
  through an off-screen courier network instead of a person you have to go find.
- **Mailbox-first delivery.** Missions resolve on a timer in the DB regardless of whether the
  player is online; rewards land in the mailbox whenever the player next checks it. This is the
  actual FFXIV-retainer feel (send them off, forget about it, come back later) and sidesteps
  needing the player present at some NPC to "collect."
- **Additive rewards**, not power creep -- crafting mats, rare minions/toys/cosmetics, not
  raid-tier gear or anything that outcompetes existing profession/dungeon loops.
- **Multi-faction idea, deferred.** Eventually let players pick between different
  factions/cartels to send hirelings through (different reward flavor per faction?) -- explicitly
  not v0 scope, parked under "Later ideas" below.

## Key technical finding: mail sender doesn't need a real NPC

Confirmed against `src/server/game/Mails/Mail.h` / `Mail.cpp` and existing core usage
(`src/server/game/Entities/Player/PlayerMisc.cpp:494`, `Player.cpp:16265`):
`MailSender(MAIL_CREATURE, entry)` only needs a `creature_template` **row** to exist -- the client
sends `CMSG_CREATURE_QUERY` to resolve the name/icon for the "From:" line, and the server answers
from the template table without ever checking whether that entry is spawned anywhere. The core
does exactly this for real (birthday mail from `34337 /* The Postmaster */`, brew-of-the-month
mail from `27487`) -- neither is a placed, findable NPC.

This unlocks two things for this module:

1. **The mission-resolution "sender" can be a template-only creature entry** (from this module's
   921000-921099 range) that never gets spawned -- no world placement needed just to make mail
   look like it came from somewhere.
2. **Possible later flourish:** give each individual hireling its own template-only entry (named
   after however the player named their hireling) so reward mail literally reads "From: " -- filed under "Later ideas," not needed for v0's simple test missions.

## Status

- **v0 (this session, not yet in-game tested):** hello-world scaffold only. Module loads
  (`Hirelings_World::OnStartup` logs a confirmation), `Hirelings.Enable` config flag reads
  correctly, `.hireling` command registers and responds with a placeholder line. No hireling
  gameplay, no DB schema, no SQL yet.

## Roadmap (agreed direction, 2026-08-14)

Agreed near-term scope, roughly in sequence:

1. **Some way to create hirelings.** Needs a `characters` DB table (something like
   `mod_hirelings_hirelings`: owner guid, hireling id, name, level/tier placeholder for later).
   Acquisition flow TBD at implementation time -- simplest v1 is probably a gossip option on the
   summon object itself ("Hire a new agent...") rather than a separate flow.
2. **Some way to summon them -- a clickable world object**, FFXIV-summoning-bell equivalent.
   Leaning toward a **static placed `GameObjectScript`** ("Hireling's Contract Board" -- a
   corkboard/notice-board fits Warcraft's goblin-trading-post aesthetic better than a bell) over a
   summoned NPC, since this is meant to be a fixed destination players return to, not a
   short-lived prop like `mod-waygate-network`'s portal. Needs a `gameobject_template` entry (from
   this module's 921000-921099 range) and a placement location -- not picked yet, open question
   for implementation time. Clicking it opens a gossip menu (hire / view active missions / collect
   -- collect may end up redundant once mailbox delivery is in, see design pillars above).
3. **Simple test missions.** Timer-based: send a hireling on a job, store
   `(hireling_id, mission_id, start_time, end_time)`, a `WorldScript` tick (or `TaskScheduler`)
   checks for completions and mails the reward via `MailDraft::SendMailTo` using a template-only
   `MAIL_CREATURE` sender (see "Key technical finding" above) -- no world placement required for
   this to work correctly even for missions that resolve while the player is offline. Reward pool
   for the *test* missions can be trivial/placeholder (a couple of cheap items) -- the point is
   proving the create -> send -> timer -> mail loop end-to-end before any real content design.

## Later ideas (explicitly deferred past the above three)

- **Hirelings visible in the world** while at the contract board (a cosmetic companion-style
  summon, not gameplay-relevant).
- **Leveling hirelings via completed missions** -- unlocks longer/better missions over time,
  mirrors FFXIV retainer leveling.
- **Multi-faction choice** -- different cartels/factions to route missions through, possibly with
  different flavor/reward bias per faction.
- **Per-hireling personalized mail sender** (see "Key technical finding" above) -- cute, not
  functionally necessary.
- **Customizing hirelings** (appearance, naming flourishes) beyond the base name given at
  creation.

## Open questions for whoever picks up step 1/2/3 next

- Exact `mod_hirelings_hirelings` schema (characters DB) -- fields beyond owner guid/id/name not
  nailed down yet.
- Where the Contract Board gameobject actually gets placed in the world for v1 testing -- probably
  somewhere convenient near a capital city for iteration, not final content placement.
- Mission definition storage -- hardcoded list to start (mirrors `mod-waygate-network` v1's
  hardcoded-then-data-driven arc), or world-DB table from the start? Worth deciding before writing
  the mission-completion query, per the lesson in `mod-waygate-network/PLAN.md` about how painful
  hardcoded-then-migrate was there.