Add edible plant resource nodes

This commit is contained in:
2026-05-17 16:01:06 -07:00
parent d69311363d
commit 054552202d
11 changed files with 155 additions and 6 deletions
+3 -1
View File
@@ -533,7 +533,9 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
`BP_StoneResourceNode`, placed in the Ground Zero resource pass, and covered
by focused stone-resource verification.
- [x] Add fiber resource.
- [ ] Add edible plant resource.
- [x] Add edible plant resource. Added `BP_EdiblePlantResourceNode` as a
gatherable food-yield node, placed deterministic Ground Zero forage nodes, and
extended resource verification to cover edible plant harvest sources.
- [ ] Add water gathering interaction.
- [x] Add resource depletion.
- [ ] Add respawn rules for MVP.
Binary file not shown.
+6 -3
View File
@@ -418,14 +418,17 @@ Data Assets should describe content. Server code should enforce gameplay rules.
### Gatherable Resources
The 0.1.F resource baseline uses `AAgrarianResourceNode` for simple gatherable
world resources. Wood, fiber, and stone each have item definitions, resource
Blueprints, deterministic Ground Zero placements, replicated remaining harvest
counts, and bare-hand gathering through the shared interaction path.
world resources. Wood, fiber, stone, and edible plants each have item
definitions or yield definitions, resource Blueprints, deterministic Ground Zero
placements, replicated remaining harvest counts, and bare-hand gathering through
the shared interaction path.
Stone specifically is represented by `DA_Item_Stone` and
`BP_StoneResourceNode`. Ground Zero includes stone nodes in slope, exposed
terrain, and valley-edge positions so primitive tools, campfires, and early
construction recipes have an in-world source instead of relying on debug grants.
Edible plants are represented by `BP_EdiblePlantResourceNode`, which yields the
MVP `food` item from scrub, grassland, and drainage-candidate forage patches.
### Wildlife Navigation
+5
View File
@@ -8,6 +8,8 @@ height, slope, and drainage-candidate analysis.
- Wood: scrub/woodland and hillside patches.
- Fiber: grassland, scrub, and drainage-candidate areas.
- Edible plants: coastal scrub, grassland, and drainage-candidate forage
patches that yield the MVP `food` item.
- Stone: slope, exposed terrain, and valley-edge areas.
Freshwater remains separate because the water-source roadmap item follows this
@@ -16,6 +18,8 @@ pass and should be implemented as its own gameplay actor/system.
## Implementation
- Added `BP_StoneResourceNode` through `Scripts/setup_playable_blueprints.py`.
- Added `BP_EdiblePlantResourceNode` through
`Scripts/setup_playable_blueprints.py`.
- Updated `Scripts/setup_ground_zero_demo_map.py` to place deterministic Ground
Zero resource nodes.
- Added `Scripts/verify_ground_zero_resources.py` to validate node presence,
@@ -27,6 +31,7 @@ The map now contains:
- Wood nodes: `4`
- Fiber nodes: `5`
- Edible plant nodes: `3`
- Stone nodes: `4`
These counts include the original demo wood and fiber nodes so the first player
+27
View File
@@ -73,6 +73,11 @@ ENVIRONMENT_MATERIALS = {
"color": unreal.LinearColor(0.55, 0.49, 0.28, 1.0),
"roughness": 0.93,
},
"edible_plant_resource": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_EdiblePlant_Resource",
"color": unreal.LinearColor(0.22, 0.46, 0.18, 1.0),
"roughness": 0.9,
},
"stone_resource": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Stone_Sandstone",
"color": unreal.LinearColor(0.43, 0.40, 0.35, 1.0),
@@ -87,6 +92,7 @@ ENVIRONMENT_MATERIALS = {
RESOURCE_MATERIAL_BY_LABEL_PREFIX = {
"AGR_GZ_Wood": "wood_resource",
"AGR_GZ_Fiber": "fiber_resource",
"AGR_GZ_EdiblePlant": "edible_plant_resource",
"AGR_GZ_Stone": "stone_resource",
"AGR_DemoWoodResource": "wood_resource",
"AGR_DemoFiberResource": "fiber_resource",
@@ -245,6 +251,27 @@ BIOME_RESOURCE_ACTORS = [
"z_offset": 65.0,
"rotation": unreal.Rotator(0.0, 114.0, 0.0),
},
{
"label": "AGR_GZ_EdiblePlant_CoastalScrub_01",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode",
"location_xy": unreal.Vector(-31400.0, -7600.0, 0.0),
"z_offset": 58.0,
"rotation": unreal.Rotator(0.0, 21.0, 0.0),
},
{
"label": "AGR_GZ_EdiblePlant_Grassland_02",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode",
"location_xy": unreal.Vector(6200.0, -26800.0, 0.0),
"z_offset": 58.0,
"rotation": unreal.Rotator(0.0, -48.0, 0.0),
},
{
"label": "AGR_GZ_EdiblePlant_DrainageCandidate_03",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode",
"location_xy": unreal.Vector(-9400.0, 12800.0, 0.0),
"z_offset": 58.0,
"rotation": unreal.Rotator(0.0, 96.0, 0.0),
},
{
"label": "AGR_GZ_Stone_Slope_01",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_StoneResourceNode",
+13
View File
@@ -10,6 +10,7 @@ WORLD_FOLDER = f"{BLUEPRINT_ROOT}/World"
WOOD_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Wood"
FIBER_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Fiber"
STONE_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Stone"
FOOD_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Food"
PLACEHOLDER_MESH_FOLDER = "/Game/Agrarian/Environment/PlaceholderMeshes"
PLACEHOLDER_MESH_SOURCES = {
@@ -60,6 +61,18 @@ BLUEPRINTS = [
"mesh": MESH_CUBE_PATH,
"scale": unreal.Vector(0.9, 0.75, 0.45),
},
{
"asset": "BP_EdiblePlantResourceNode",
"folder": RESOURCE_FOLDER,
"parent": unreal.AgrarianResourceNode,
"defaults": {
"yield_item_definition": FOOD_ITEM_PATH,
"remaining_harvests": 8,
"quantity_per_harvest": 1,
},
"mesh": MESH_CYLINDER_PATH,
"scale": unreal.Vector(0.65, 0.65, 0.85),
},
{
"asset": "BP_Campfire",
"folder": STRUCTURE_FOLDER,
+80
View File
@@ -0,0 +1,80 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
FILES = {
"setup_item_definitions.py": ROOT / "Scripts" / "setup_item_definitions.py",
"setup_playable_blueprints.py": ROOT / "Scripts" / "setup_playable_blueprints.py",
"setup_ground_zero_demo_map.py": ROOT / "Scripts" / "setup_ground_zero_demo_map.py",
"verify_playable_blueprints.py": ROOT / "Scripts" / "verify_playable_blueprints.py",
"verify_ground_zero_resources.py": ROOT / "Scripts" / "verify_ground_zero_resources.py",
"GroundZeroResourcePass.md": ROOT / "Docs" / "Terrain" / "GroundZeroResourcePass.md",
"TechnicalDesignDocument.md": ROOT / "Docs" / "TechnicalDesignDocument.md",
"AGRARIAN_DEVELOPMENT_ROADMAP.md": ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md",
}
EXPECTED = {
"setup_item_definitions.py": [
'"asset": "DA_Item_Food"',
'"item_id": "food"',
'"item_type": unreal.AgrarianItemType.FOOD',
],
"setup_playable_blueprints.py": [
'FOOD_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Food"',
'"asset": "BP_EdiblePlantResourceNode"',
'"yield_item_definition": FOOD_ITEM_PATH',
'"remaining_harvests": 8',
'"quantity_per_harvest": 1',
],
"setup_ground_zero_demo_map.py": [
'"edible_plant_resource"',
'"/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode"',
'"AGR_GZ_EdiblePlant_CoastalScrub_01"',
'"AGR_GZ_EdiblePlant_Grassland_02"',
'"AGR_GZ_EdiblePlant_DrainageCandidate_03"',
],
"verify_playable_blueprints.py": [
'"/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode"',
'"yield_item_id": "food"',
],
"verify_ground_zero_resources.py": [
'"food": [',
'"AGR_GZ_EdiblePlant_CoastalScrub_01"',
"edible plant",
],
"GroundZeroResourcePass.md": [
"Edible plants:",
"`food` item",
"Added `BP_EdiblePlantResourceNode`",
"Edible plant nodes: `3`",
],
"TechnicalDesignDocument.md": [
"edible plants",
"`BP_EdiblePlantResourceNode`",
"MVP `food` item",
"forage patches",
],
"AGRARIAN_DEVELOPMENT_ROADMAP.md": [
"[x] Add edible plant resource.",
"`BP_EdiblePlantResourceNode`",
"Ground Zero forage nodes",
],
}
def main():
missing = []
for label, path in FILES.items():
text = path.read_text(encoding="utf-8")
for snippet in EXPECTED[label]:
if snippet not in text:
missing.append(f"{label}: {snippet}")
if missing:
raise RuntimeError("Edible plant resource verification failed: " + "; ".join(missing))
print("Agrarian edible plant resource verification complete.")
if __name__ == "__main__":
main()
+6
View File
@@ -17,6 +17,11 @@ EXPECTED_RESOURCE_LABELS = {
"AGR_GZ_Fiber_Scrub_03",
"AGR_GZ_Fiber_DrainageCandidate_04",
],
"food": [
"AGR_GZ_EdiblePlant_CoastalScrub_01",
"AGR_GZ_EdiblePlant_Grassland_02",
"AGR_GZ_EdiblePlant_DrainageCandidate_03",
],
"stone": [
"AGR_GZ_Stone_Slope_01",
"AGR_GZ_Stone_Slope_02",
@@ -67,6 +72,7 @@ def main():
"Ground Zero resource verification complete: "
f"{len(EXPECTED_RESOURCE_LABELS['wood'])} wood, "
f"{len(EXPECTED_RESOURCE_LABELS['fiber'])} fiber, "
f"{len(EXPECTED_RESOURCE_LABELS['food'])} edible plant, "
f"{len(EXPECTED_RESOURCE_LABELS['stone'])} stone nodes."
)
+7
View File
@@ -23,6 +23,13 @@ EXPECTED = {
},
"yield_item_id": "stone",
},
"/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode": {
"properties": {
"remaining_harvests": 8,
"quantity_per_harvest": 1,
},
"yield_item_id": "food",
},
"/Game/Agrarian/Blueprints/Structures/BP_Campfire": {
"properties": {
"fuel_seconds": 180.0,