Implement DevoteeNPC data model — name, specialty, skill_level, assignment, loyalty, morale #219

Open
opened 2026-03-16 01:38:47 +00:00 by freemo · 0 comments
Owner

Metadata

Field Value
Epic #203 — Devotee System
Legendary #199 — Reputation & Social Standing
Type Feature
Priority Medium
Points 5
MoSCoW Must Have
Branch feature/m4-devotee-npc-data-model
Commit Message Implement DevoteeNPC data model — name, specialty, skill_level, assignment, loyalty, morale (#219)

Background and Context

The Devotee system allows players with high reputation to recruit NPC followers. Each devotee is a persistent companion with their own attributes that affect their usefulness and determine whether they remain loyal.

The DevoteeNPC class extends Mobile (the base NPC class) with devotee-specific fields. A devotee has a specialty that determines what tasks they can perform, a skill level that determines how well they perform, a current assignment, and loyalty/morale stats that fluctuate based on player actions.

Devotees are stored in player.info["devotees"] as an array of serialized DevoteeNPC objects. This allows devotees to persist across sessions and be loaded when the player logs in.

Expected Behavior

  1. DevoteeNPC extends Mobile with additional fields:
    • specialty: One of :harvest, :guard, :trade, :craft
    • skill_level: Integer 1-10, determines effectiveness at their specialty
    • assignment: Current task (string or nil if idle)
    • loyalty: Integer 0-100, starts at 50
    • morale: Integer 0-100, starts at 50
  2. DevoteeNPC.new(name:, specialty:, skill_level: 1) creates a new devotee with default loyalty (50) and morale (50).
  3. to_hash serializes all devotee fields for persistence.
  4. DevoteeNPC.from_hash(data) reconstructs a devotee from serialized data.
  5. Devotees are stored in player.info["devotees"] as an array of hashes.
  6. loyalty and morale are clamped to 0-100.
  7. idle? returns true if assignment is nil.

Acceptance Criteria

  • DevoteeNPC class exists in lib/aethyr/core/reputation/devotee_npc.rb.
  • Class extends Mobile with specialty, skill_level, assignment, loyalty, and morale fields.
  • specialty is validated to be one of :harvest, :guard, :trade, :craft.
  • skill_level is clamped to 1-10.
  • loyalty and morale are clamped to 0-100 with default of 50.
  • to_hash and DevoteeNPC.from_hash round-trip correctly.
  • idle? returns true when assignment is nil.
  • Devotees persist correctly in player.info["devotees"].

Subtasks

  • Create lib/aethyr/core/reputation/devotee_npc.rb with the DevoteeNPC class.
  • Implement initialization with required fields and defaults.
  • Implement specialty validation.
  • Implement skill_level clamping (1-10).
  • Implement loyalty and morale with clamping (0-100) and defaults (50).
  • Implement to_hash serialization.
  • Implement DevoteeNPC.from_hash deserialization.
  • Implement idle? method.
  • Implement persistence to/from player.info["devotees"].
  • Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable.
  • Tests (Cucumber): Add tests/unit/devotee_npc.feature covering initialization, field validation, clamping, serialization round-trip, idle detection, and persistence.
  • Tests (Cucumber Integration): Add integration feature in tests/integration/ for devotee creation, persistence across save/load, and interaction with player info.
  • Tests (Profiling): Run bundle exec rake unit_profile and verify no performance regressions.
  • Quality: Verify coverage >=97% via bundle exec rake unit. If coverage is <97% then review the current unit test coverage report at build/tests/unit/coverage/ and use it to write new Cucumber based unit tests to improve code coverage. Specifically, write Cucumber/Gherkin style unit tests that are descriptively named and specifically improve coverage on whichever file has the most uncovered lines by writing tests that will target the uncovered lines in the report. Once that is done rerun bundle exec rake unit to verify all tests pass and coverage is above >=97%. Only mark this as complete once coverage is >=97%, if not repeat this task as many times as is needed until coverage reaches >=97%.
  • Quality: Run bundle exec rake (default task: unit tests with coverage) and bundle exec rake integration, fix any errors if needed ensuring both pass across entire code base, do not ignore any failure even if it seems unrelated to this commit, fix it.

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
## Metadata | Field | Value | |-------|-------| | **Epic** | #203 — Devotee System | | **Legendary** | #199 — Reputation & Social Standing | | **Type** | Feature | | **Priority** | Medium | | **Points** | 5 | | **MoSCoW** | Must Have | | **Branch** | `feature/m4-devotee-npc-data-model` | | **Commit Message** | `Implement DevoteeNPC data model — name, specialty, skill_level, assignment, loyalty, morale (#219)` | ## Background and Context The Devotee system allows players with high reputation to recruit NPC followers. Each devotee is a persistent companion with their own attributes that affect their usefulness and determine whether they remain loyal. The `DevoteeNPC` class extends `Mobile` (the base NPC class) with devotee-specific fields. A devotee has a specialty that determines what tasks they can perform, a skill level that determines how well they perform, a current assignment, and loyalty/morale stats that fluctuate based on player actions. Devotees are stored in `player.info["devotees"]` as an array of serialized DevoteeNPC objects. This allows devotees to persist across sessions and be loaded when the player logs in. ## Expected Behavior 1. `DevoteeNPC` extends `Mobile` with additional fields: - `specialty`: One of `:harvest`, `:guard`, `:trade`, `:craft` - `skill_level`: Integer 1-10, determines effectiveness at their specialty - `assignment`: Current task (string or nil if idle) - `loyalty`: Integer 0-100, starts at 50 - `morale`: Integer 0-100, starts at 50 2. `DevoteeNPC.new(name:, specialty:, skill_level: 1)` creates a new devotee with default loyalty (50) and morale (50). 3. `to_hash` serializes all devotee fields for persistence. 4. `DevoteeNPC.from_hash(data)` reconstructs a devotee from serialized data. 5. Devotees are stored in `player.info["devotees"]` as an array of hashes. 6. `loyalty` and `morale` are clamped to 0-100. 7. `idle?` returns true if `assignment` is nil. ## Acceptance Criteria - [ ] `DevoteeNPC` class exists in `lib/aethyr/core/reputation/devotee_npc.rb`. - [ ] Class extends `Mobile` with specialty, skill_level, assignment, loyalty, and morale fields. - [ ] `specialty` is validated to be one of `:harvest`, `:guard`, `:trade`, `:craft`. - [ ] `skill_level` is clamped to 1-10. - [ ] `loyalty` and `morale` are clamped to 0-100 with default of 50. - [ ] `to_hash` and `DevoteeNPC.from_hash` round-trip correctly. - [ ] `idle?` returns true when assignment is nil. - [ ] Devotees persist correctly in `player.info["devotees"]`. ## Subtasks - [ ] Create `lib/aethyr/core/reputation/devotee_npc.rb` with the `DevoteeNPC` class. - [ ] Implement initialization with required fields and defaults. - [ ] Implement specialty validation. - [ ] Implement skill_level clamping (1-10). - [ ] Implement loyalty and morale with clamping (0-100) and defaults (50). - [ ] Implement `to_hash` serialization. - [ ] Implement `DevoteeNPC.from_hash` deserialization. - [ ] Implement `idle?` method. - [ ] Implement persistence to/from `player.info["devotees"]`. - [ ] Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable. - [ ] Tests (Cucumber): Add `tests/unit/devotee_npc.feature` covering initialization, field validation, clamping, serialization round-trip, idle detection, and persistence. - [ ] Tests (Cucumber Integration): Add integration feature in `tests/integration/` for devotee creation, persistence across save/load, and interaction with player info. - [ ] Tests (Profiling): Run `bundle exec rake unit_profile` and verify no performance regressions. - [ ] Quality: Verify coverage >=97% via `bundle exec rake unit`. If coverage is <97% then review the current unit test coverage report at `build/tests/unit/coverage/` and use it to write new Cucumber based unit tests to improve code coverage. Specifically, write Cucumber/Gherkin style unit tests that are descriptively named and specifically improve coverage on whichever file has the most uncovered lines by writing tests that will target the uncovered lines in the report. Once that is done rerun `bundle exec rake unit` to verify all tests pass and coverage is above >=97%. Only mark this as complete once coverage is >=97%, if not repeat this task as many times as is needed until coverage reaches >=97%. - [ ] Quality: Run `bundle exec rake` (default task: unit tests with coverage) and `bundle exec rake integration`, fix any errors if needed ensuring both pass across **entire** code base, do not ignore any failure even if it seems unrelated to this commit, fix it. ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done.
freemo added this to the v1.3.0 milestone 2026-03-16 01:38:47 +00:00
freemo self-assigned this 2026-03-16 01:38:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
Reference: aethyr/Aethyr#219
No description provided.