Generated reference. This page mirrors
Code/Jobs/README.md, this module's source-of-truth documentation (Standards/02_DOCUMENTATION_STANDARDS.md §1). Edit it there, not here -- this file is regenerated on every docs build and any local edit is silently overwritten.
Jobs¶
Purpose. The group→gang→team hierarchy, job definitions, and joining. See 16_JOBS_FRAMEWORK.md.
Responsibilities.
- TeamGroup — the fixed, closed set of groups (Officials, Civilians, Underground).
- JobDefinition — content, not code: display name, group, gang id, level, max players,
required character permission, mandatory-transit flag, rejoin cooldown, sort order, and
(Milestone 8) CanManufacture — legacy's canmake list, the categories a holder may
manufacture. See
16_JOBS_FRAMEWORK.md §2
for what's still deliberately not modelled (the cantuse blacklist, loadouts, ammo grants,
governance flags, salary).
- IJobRegistry / JobRegistry — every loaded JobDefinition, sorted by SortOrder.
Mirrors IItemRegistry, minus inheritance resolution (jobs don't have ParentId).
- JobsConfiguration — DefaultJobName (the job a never-saved character starts as; legacy's
TEAM_DEFAULT = TEAM_CITIZEN).
- TeamMembership (internal) / IJobService / JobStore — the values themselves:
LoadOrCreateAsync, GetCurrentJobName, JoinJobAsync. JobStore is the one
implementation; nothing else writes a character's job. Follows EconomyStore's
persist-on-write shape — joining is a discrete event, not a per-frame decay.
- /team <jobName> — Jobs' own first real Commands entry, registered by JobsModule.
- Persistence of job membership under jobs/{characterId}
(08_DATA_MODEL.md §8).
Not responsible for.
- Demotion and mutiny. Real governance logic (level/flag checks, quorum, supermajority) —
see 16_JOBS_FRAMEWORK.md §6.
- Job-blacklisting. No blacklist data model exists anywhere in this codebase —
Code/Characters/AccountModeration.cs is account-ban status, unrelated.
- Term-limit auto-expiry. Needs a ticking/polling mechanism, not built here. The rejoin
cooldown half of the same legacy setting is built.
- Salary and payday. Code/Economy/README.md already defers this; still deferred —
crediting a lump sum at join would be inventing a mechanic legacy doesn't actually have.
- Enforcing CanManufacture, or cantuse. CanManufacture (Milestone 8) is recipe data
ready to be read; the /manufacture command that would read it isn't built — see
Code/Items/README.md's "Not responsible for". cantuse (a per-job category blacklist on
using an item, not manufacturing it) isn't modelled at all yet.
- Telling the calling player the outcome of /team. Chat now exists (Milestone 7), but
/team's Execute closure was not revisited to use it — still the same "only in the
server log" limitation /help originally carried, now a real gap rather than a
can't-exist-yet one.
Dependencies. Core (IServiceRegistry, IServiceResolver, IPersistenceBackend,
ISchemaRegistry, IGameLog, IClock), Characters (CharacterId, Character.HasPermission),
Items (ItemCategory, for CanManufacture), Commands (ICommandRegistry, for /team's
registration).
Public API.
- IJobRegistry — Find(string), Get(string), All.
- IJobService — LoadOrCreateAsync(CharacterId), GetCurrentJobName(CharacterId),
JoinJobAsync(Character, string).
- JobDefinition, TeamGroup, JobsConfiguration.
Events published. None yet — a JobChanged event is natural once a consumer (a
scoreboard, a HUD element) needs to react, deferred until that consumer exists, following
Inventories' README's identical deferral.
Persistence. JobDocument { CharacterId, CurrentJobName, CooldownUntil } under
jobs/{characterId}, schema version 1.
Not unit-tested. JobRegistry's own constructor (dedupe-by-AssetId, sort by
SortOrder) has no test. JobDefinition.AssetId is computed from GameResource.ResourceName
and unsettable without a real engine-loaded asset — the identical reason
UnitTests/Items/ItemRegistryTests.cs never constructs a real ItemRegistry either, testing
only its separately-exposed ResolveInheritance (against ItemDefinitionFixture, not
ItemDefinition). JobRegistry has no equivalently-complex static method worth extracting
the same way, so it's left untested, matching ItemRegistry's own constructor precedent
rather than inventing a new technique. JobStoreTests.cs avoids the same problem entirely by
using a FakeJobRegistry keyed however the test chooses, not by any real JobDefinition's
own AssetId.
Future improvements.
- Demotion and mutiny, once governance logic is designed as its own pass.
- Job-blacklisting, once a blacklist data model exists.
- Term-limit auto-expiry, once a ticking mechanism for Jobs is built.
- Salary/payday, once a recurring-tick mechanism exists for Economy to drive.
- The /manufacture command reading CanManufacture, once target-agnostic world-position
resolution exists (see Code/Items/README.md).
- The cantuse blacklist, loadouts, and starting ammo grants — real features, not fields.
- A reply-to-caller path for /team, now that Chat exists but hasn't been wired to it.