Implement HarvestNode data model with 12 fields #239

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

Metadata

Field Value
Parent Epic Epic: Harvesting System (#209)
Legendary Crafting & Resource Economy (#200)
Type Feature
Priority High
MoSCoW Must Have
Points 8
Branch feature/m4-harvest-node-data-model
Commit Message Implement HarvestNode data model with 12 fields (#239)

Background and Context

The harvesting system requires a robust data model to represent harvestable resource nodes scattered throughout the game world. Each HarvestNode represents a single harvestable location (e.g., an ore vein, an herb patch, a timber stand). The data model must capture all the information needed for skill checks, quality calculations, depletion/respawn mechanics, and world placement.

This is the foundational data model that all other harvesting features depend on. Without it, neither personal harvesting nor devotee-delegated harvesting can function.

Expected Behavior

A new HarvestNode class (or equivalent data structure) is created with the following 12 fields:

  1. resource_type (String) — The type of resource this node yields (e.g., "iron_ore", "silverleaf", "oak_timber").
  2. quality_range (Range) — The base quality range for resources harvested from this node (e.g., 20..80). The actual quality is modified by the harvester's skill.
  3. respawn_rate (Integer) — The number of seconds until this node respawns after full depletion.
  4. skill_required (String) — The crafting/harvesting skill required to harvest this node (e.g., "mining", "herbalism", "woodcutting").
  5. depletion_count (Integer) — The number of times this node can be harvested before it is fully depleted.
  6. max_depletion (Integer) — The maximum depletion count (used to reset current_depletion on respawn).
  7. current_depletion (Integer) — The current number of times this node has been harvested since last respawn. When current_depletion >= depletion_count, the node is depleted.
  8. respawn_timer (Float or nil) — The game time at which this node will respawn. nil if the node is not currently depleted.
  9. area_id (String) — The identifier of the area/room where this node is located.
  10. position (Hash or coordinate object) — The specific position within the area for display and interaction purposes.
  11. yields (Array<Hash>) — A list of possible yield items with their drop rates and quantities (e.g., [{item: "iron_ore", chance: 0.8, qty: 1..3}, {item: "gemstone", chance: 0.05, qty: 1}]).
  12. difficulty (Integer) — A difficulty rating (1-100) that factors into the skill check formula.

The model should support:

  • Serialization/deserialization for persistence.
  • A depleted? method that returns true when current_depletion >= depletion_count.
  • A respawn! method that resets current_depletion to 0 and clears respawn_timer.
  • A harvest! method that increments current_depletion and sets respawn_timer when fully depleted.
  • Loading node definitions from a YAML configuration file (e.g., conf/harvest_nodes.yaml).

Acceptance Criteria

  • HarvestNode class exists with all 12 fields properly defined with appropriate types and defaults.
  • depleted? returns true when current_depletion >= depletion_count, false otherwise.
  • respawn! resets current_depletion to 0 and sets respawn_timer to nil.
  • harvest! increments current_depletion by 1 and sets respawn_timer when the node becomes fully depleted.
  • HarvestNode instances can be serialized to and deserialized from a persistent format.
  • Node definitions can be loaded from conf/harvest_nodes.yaml.
  • All 12 fields are validated on initialization (e.g., quality_range must be a valid range, depletion_count must be positive).
  • The model integrates with the existing game object hierarchy.

Subtasks

  • Create the HarvestNode class with all 12 fields, accessors, and initialization logic.
  • Implement depleted?, respawn!, and harvest! methods.
  • Implement YAML-based loading from conf/harvest_nodes.yaml.
  • Implement serialization/deserialization for game persistence.
  • Add input validation for all 12 fields on initialization.
  • Create sample conf/harvest_nodes.yaml with at least 5 example node definitions.
  • Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable.
  • Tests (Cucumber): Add tests/unit/harvest_node_model.feature covering field validation, depleted? logic, respawn! reset, harvest! depletion tracking, YAML loading.
  • Tests (Cucumber Integration): Add integration feature in tests/integration/ for harvest node lifecycle (create, harvest, deplete, respawn).
  • 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 | |---|---| | **Parent Epic** | Epic: Harvesting System (#209) | | **Legendary** | Crafting & Resource Economy (#200) | | **Type** | Feature | | **Priority** | High | | **MoSCoW** | Must Have | | **Points** | 8 | | **Branch** | `feature/m4-harvest-node-data-model` | | **Commit Message** | `Implement HarvestNode data model with 12 fields (#239)` | ## Background and Context The harvesting system requires a robust data model to represent harvestable resource nodes scattered throughout the game world. Each `HarvestNode` represents a single harvestable location (e.g., an ore vein, an herb patch, a timber stand). The data model must capture all the information needed for skill checks, quality calculations, depletion/respawn mechanics, and world placement. This is the foundational data model that all other harvesting features depend on. Without it, neither personal harvesting nor devotee-delegated harvesting can function. ## Expected Behavior A new `HarvestNode` class (or equivalent data structure) is created with the following 12 fields: 1. **resource_type** (`String`) — The type of resource this node yields (e.g., `"iron_ore"`, `"silverleaf"`, `"oak_timber"`). 2. **quality_range** (`Range`) — The base quality range for resources harvested from this node (e.g., `20..80`). The actual quality is modified by the harvester's skill. 3. **respawn_rate** (`Integer`) — The number of seconds until this node respawns after full depletion. 4. **skill_required** (`String`) — The crafting/harvesting skill required to harvest this node (e.g., `"mining"`, `"herbalism"`, `"woodcutting"`). 5. **depletion_count** (`Integer`) — The number of times this node can be harvested before it is fully depleted. 6. **max_depletion** (`Integer`) — The maximum depletion count (used to reset `current_depletion` on respawn). 7. **current_depletion** (`Integer`) — The current number of times this node has been harvested since last respawn. When `current_depletion >= depletion_count`, the node is depleted. 8. **respawn_timer** (`Float` or `nil`) — The game time at which this node will respawn. `nil` if the node is not currently depleted. 9. **area_id** (`String`) — The identifier of the area/room where this node is located. 10. **position** (`Hash` or coordinate object) — The specific position within the area for display and interaction purposes. 11. **yields** (`Array<Hash>`) — A list of possible yield items with their drop rates and quantities (e.g., `[{item: "iron_ore", chance: 0.8, qty: 1..3}, {item: "gemstone", chance: 0.05, qty: 1}]`). 12. **difficulty** (`Integer`) — A difficulty rating (1-100) that factors into the skill check formula. The model should support: - Serialization/deserialization for persistence. - A `depleted?` method that returns `true` when `current_depletion >= depletion_count`. - A `respawn!` method that resets `current_depletion` to 0 and clears `respawn_timer`. - A `harvest!` method that increments `current_depletion` and sets `respawn_timer` when fully depleted. - Loading node definitions from a YAML configuration file (e.g., `conf/harvest_nodes.yaml`). ## Acceptance Criteria - [ ] `HarvestNode` class exists with all 12 fields properly defined with appropriate types and defaults. - [ ] `depleted?` returns `true` when `current_depletion >= depletion_count`, `false` otherwise. - [ ] `respawn!` resets `current_depletion` to 0 and sets `respawn_timer` to `nil`. - [ ] `harvest!` increments `current_depletion` by 1 and sets `respawn_timer` when the node becomes fully depleted. - [ ] HarvestNode instances can be serialized to and deserialized from a persistent format. - [ ] Node definitions can be loaded from `conf/harvest_nodes.yaml`. - [ ] All 12 fields are validated on initialization (e.g., `quality_range` must be a valid range, `depletion_count` must be positive). - [ ] The model integrates with the existing game object hierarchy. ## Subtasks - [ ] Create the `HarvestNode` class with all 12 fields, accessors, and initialization logic. - [ ] Implement `depleted?`, `respawn!`, and `harvest!` methods. - [ ] Implement YAML-based loading from `conf/harvest_nodes.yaml`. - [ ] Implement serialization/deserialization for game persistence. - [ ] Add input validation for all 12 fields on initialization. - [ ] Create sample `conf/harvest_nodes.yaml` with at least 5 example node definitions. - [ ] Docs: Update YARD comments on affected classes and methods. Update relevant Docusaurus documentation pages if applicable. - [ ] Tests (Cucumber): Add `tests/unit/harvest_node_model.feature` covering field validation, depleted? logic, respawn! reset, harvest! depletion tracking, YAML loading. - [ ] Tests (Cucumber Integration): Add integration feature in `tests/integration/` for harvest node lifecycle (create, harvest, deplete, respawn). - [ ] 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:41:40 +00:00
freemo self-assigned this 2026-03-16 01:41: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.

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