Implement reputation propagation — allied factions +50%, rival factions -30%, parent region +25%, sub-regions +10%, individual-to-faction +15% #216

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

Metadata

Field Value
Epic #202 — Reputation Mechanics
Legendary #199 — Reputation & Social Standing
Type Feature
Priority High
Points 8
MoSCoW Must Have
Branch feature/m4-reputation-propagation
Commit Message Implement reputation propagation — allied factions +50%, rival factions -30%, parent region +25%, sub-regions +10%, individual-to-faction +15% (#216)

Background and Context

In a living world, reputation with one entity should affect standing with related entities. Helping the Merchant Guild should improve standing with their allies and hurt standing with their rivals. Gaining favor in a capital city should provide a smaller boost in nearby towns. This is the reputation propagation system.

When a player's reputation changes with any entity, the system cascades proportional changes through the faction relationship graph. The relationships between factions are defined in conf/factions.yaml, which specifies allies, rivals, parent regions, and sub-regions for each faction or settlement.

Propagation is capped at 2 degrees of separation to prevent infinite cascades and keep the system predictable. The propagation percentages are:

  • Allied factions: +50% of the original change
  • Rival factions: -30% of the original change (sign inverted)
  • Parent region: +25% of the original change
  • Sub-regions: +10% of the original change
  • Individual-to-faction: +15% of the original change (NPC rep affects their faction)

Expected Behavior

  1. When modify_reputation(entity, delta) is called, after the primary change is applied, the propagation system fires.
  2. The system reads faction relationships from conf/factions.yaml.
  3. For each relationship type, the proportional delta is calculated and applied to the related entity.
  4. Propagated changes do NOT trigger further propagation beyond 2 degrees of separation.
  5. All propagated changes still fire :reputation_changed events but are tagged as propagated: true.
  6. Propagation respects the -100..+100 clamping on all scores.
  7. If a faction has no relationships defined, no propagation occurs for that entity.

Acceptance Criteria

  • conf/factions.yaml structure is defined with allies, rivals, parent_region, sub_regions fields.
  • Propagation fires automatically when reputation is modified.
  • Allied factions receive +50% of the original delta.
  • Rival factions receive -30% of the original delta (inverted sign).
  • Parent region receives +25% of the original delta.
  • Sub-regions each receive +10% of the original delta.
  • Individual NPC changes propagate +15% to their affiliated faction.
  • Propagation is capped at 2 degrees of separation.
  • Propagated changes are tagged as propagated: true in events.
  • All propagated scores are clamped to -100..+100.

Subtasks

  • Create conf/factions.yaml with sample faction relationship data.
  • Create lib/aethyr/core/reputation/reputation_propagation.rb with the propagation engine.
  • Implement relationship loading from conf/factions.yaml.
  • Implement allied faction propagation (+50%).
  • Implement rival faction propagation (-30%, inverted).
  • Implement parent region propagation (+25%).
  • Implement sub-region propagation (+10%).
  • Implement individual-to-faction propagation (+15%).
  • Add 2-degree cap on cascading propagation.
  • Subscribe to :reputation_changed Wisper event to trigger propagation.
  • Tag propagated events with propagated: true.
  • Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable.
  • Tests (Cucumber): Add tests/unit/reputation_propagation.feature covering all propagation percentages, 2-degree cap, inverted rival propagation, clamping, and event tagging.
  • Tests (Cucumber Integration): Add integration feature in tests/integration/ for end-to-end propagation through a multi-faction relationship graph.
  • 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** | #202 — Reputation Mechanics | | **Legendary** | #199 — Reputation & Social Standing | | **Type** | Feature | | **Priority** | High | | **Points** | 8 | | **MoSCoW** | Must Have | | **Branch** | `feature/m4-reputation-propagation` | | **Commit Message** | `Implement reputation propagation — allied factions +50%, rival factions -30%, parent region +25%, sub-regions +10%, individual-to-faction +15% (#216)` | ## Background and Context In a living world, reputation with one entity should affect standing with related entities. Helping the Merchant Guild should improve standing with their allies and hurt standing with their rivals. Gaining favor in a capital city should provide a smaller boost in nearby towns. This is the reputation propagation system. When a player's reputation changes with any entity, the system cascades proportional changes through the faction relationship graph. The relationships between factions are defined in `conf/factions.yaml`, which specifies allies, rivals, parent regions, and sub-regions for each faction or settlement. Propagation is capped at 2 degrees of separation to prevent infinite cascades and keep the system predictable. The propagation percentages are: - **Allied factions**: +50% of the original change - **Rival factions**: -30% of the original change (sign inverted) - **Parent region**: +25% of the original change - **Sub-regions**: +10% of the original change - **Individual-to-faction**: +15% of the original change (NPC rep affects their faction) ## Expected Behavior 1. When `modify_reputation(entity, delta)` is called, after the primary change is applied, the propagation system fires. 2. The system reads faction relationships from `conf/factions.yaml`. 3. For each relationship type, the proportional delta is calculated and applied to the related entity. 4. Propagated changes do NOT trigger further propagation beyond 2 degrees of separation. 5. All propagated changes still fire `:reputation_changed` events but are tagged as `propagated: true`. 6. Propagation respects the -100..+100 clamping on all scores. 7. If a faction has no relationships defined, no propagation occurs for that entity. ## Acceptance Criteria - [ ] `conf/factions.yaml` structure is defined with allies, rivals, parent_region, sub_regions fields. - [ ] Propagation fires automatically when reputation is modified. - [ ] Allied factions receive +50% of the original delta. - [ ] Rival factions receive -30% of the original delta (inverted sign). - [ ] Parent region receives +25% of the original delta. - [ ] Sub-regions each receive +10% of the original delta. - [ ] Individual NPC changes propagate +15% to their affiliated faction. - [ ] Propagation is capped at 2 degrees of separation. - [ ] Propagated changes are tagged as `propagated: true` in events. - [ ] All propagated scores are clamped to -100..+100. ## Subtasks - [ ] Create `conf/factions.yaml` with sample faction relationship data. - [ ] Create `lib/aethyr/core/reputation/reputation_propagation.rb` with the propagation engine. - [ ] Implement relationship loading from `conf/factions.yaml`. - [ ] Implement allied faction propagation (+50%). - [ ] Implement rival faction propagation (-30%, inverted). - [ ] Implement parent region propagation (+25%). - [ ] Implement sub-region propagation (+10%). - [ ] Implement individual-to-faction propagation (+15%). - [ ] Add 2-degree cap on cascading propagation. - [ ] Subscribe to `:reputation_changed` Wisper event to trigger propagation. - [ ] Tag propagated events with `propagated: true`. - [ ] Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable. - [ ] Tests (Cucumber): Add `tests/unit/reputation_propagation.feature` covering all propagation percentages, 2-degree cap, inverted rival propagation, clamping, and event tagging. - [ ] Tests (Cucumber Integration): Add integration feature in `tests/integration/` for end-to-end propagation through a multi-faction relationship graph. - [ ] 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:37:40 +00:00
freemo self-assigned this 2026-03-16 01:37:40 +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.

Reference: aethyr/Aethyr#216
No description provided.