Upgrade Ground Zero investor biome dressing

This commit is contained in:
2026-05-19 10:52:24 -07:00
parent 63f48bcadf
commit be6486202c
5 changed files with 133 additions and 21 deletions
+1 -1
View File
@@ -822,7 +822,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
- [x] Add a visually verified packaged-client startup test using Sunshine/Moonlight or another real GPU desktop capture path, because QEMU guest-agent screenshots cannot validate the interactive rendered desktop. Added a packaged-client GPU startup visual test runbook, a Windows helper that checks the packaged demo and Sunshine service before capture, and verifier coverage requiring Moonlight/Sunshine evidence instead of QEMU guest-agent screenshots. - [x] Add a visually verified packaged-client startup test using Sunshine/Moonlight or another real GPU desktop capture path, because QEMU guest-agent screenshots cannot validate the interactive rendered desktop. Added a packaged-client GPU startup visual test runbook, a Windows helper that checks the packaged demo and Sunshine service before capture, and verifier coverage requiring Moonlight/Sunshine evidence instead of QEMU guest-agent screenshots.
- [x] Add first realistic playable character proxies for the selected young adult male and female archetypes, replacing the default mannequin/dummy presentation for investor builds. Added selected male/female MVP proxy application to the player controller, workwear material generation, cook coverage for Agrarian character assets, documentation, and verification so the menu-selected archetype changes the possessed pawn instead of leaving one default dummy presentation. - [x] Add first realistic playable character proxies for the selected young adult male and female archetypes, replacing the default mannequin/dummy presentation for investor builds. Added selected male/female MVP proxy application to the player controller, workwear material generation, cook coverage for Agrarian character assets, documentation, and verification so the menu-selected archetype changes the possessed pawn instead of leaving one default dummy presentation.
- [x] Replace box/sphere/cylinder survival objects with readable MVP meshes for campfires, primitive shelter pieces, resource pickups, water sources, wildlife, and gathered items. Added composed native proxy visuals for campfires, primitive shelters, pickups, resource nodes, water sources, and wildlife using cooked Agrarian placeholder mesh assets plus Ground Zero materials, with child visuals set to no collision so gameplay behavior remains unchanged while investor builds read as intentional objects instead of primitive debug shapes. - [x] Replace box/sphere/cylinder survival objects with readable MVP meshes for campfires, primitive shelter pieces, resource pickups, water sources, wildlife, and gathered items. Added composed native proxy visuals for campfires, primitive shelters, pickups, resource nodes, water sources, and wildlife using cooked Agrarian placeholder mesh assets plus Ground Zero materials, with child visuals set to no collision so gameplay behavior remains unchanged while investor builds read as intentional objects instead of primitive debug shapes.
- [ ] Replace the placeholder Ground Zero environment presentation with investor-facing biome dressing: believable terrain material, grass, brush, shrubs, bushes, trees, rocks, water visuals, and local coastal-scrub color variation. - [x] Replace the placeholder Ground Zero environment presentation with investor-facing biome dressing: believable terrain material, grass, brush, shrubs, bushes, trees, rocks, water visuals, and local coastal-scrub color variation. Upgraded the repeatable Ground Zero setup to require denser investor-facing foliage counts and twenty-three labeled variation actors covering trees, brush, shrubs, dry grass mats, rock slabs, water-bank pieces, reeds, and freshwater surface material variation, then extended the verifier/docs so the map no longer qualifies if the visual dressing falls back to sparse placeholder presentation.
- [ ] Add a real water-source visual pass with surface material, edge treatment, scale, and placement that reads as collectable freshwater instead of a placeholder plane. - [ ] Add a real water-source visual pass with surface material, edge treatment, scale, and placement that reads as collectable freshwater instead of a placeholder plane.
- [ ] Add density and sightline tuning so grasses, shrubs, trees, and resource clusters are visible enough to sell the world without hiding gameplay-critical objects. - [ ] Add density and sightline tuning so grasses, shrubs, trees, and resource clusters are visible enough to sell the world without hiding gameplay-critical objects.
- [ ] Preserve realism as the target: use assets, materials, lighting, and environmental dressing that can survive toward MVP production rather than cosmetic throwaways where practical. - [ ] Preserve realism as the target: use assets, materials, lighting, and environmental dressing that can survive toward MVP production rather than cosmetic throwaways where practical.
Binary file not shown.
@@ -11,9 +11,10 @@ space.
tree, shrub, and dry grass materials. tree, shrub, and dry grass materials.
- Wood, fiber, stone, and freshwater actors receive distinct first-pass - Wood, fiber, stone, and freshwater actors receive distinct first-pass
materials. materials.
- First-pass asset variation actors add additional tree canopies/trunks, rounded - Investor-facing asset variation actors add additional tree canopies/trunks,
bushes, grass mats, rock slabs, and a visible freshwater surface with varied rounded bushes, brush clusters, grass mats, rock slabs, water-bank pieces,
meshes, scales, rotations, and material families. reeds, and a visible freshwater surface with varied meshes, scales,
rotations, and material families.
- A first-pass ruin landmark placeholder gives the Ground Zero demo a visible - A first-pass ruin landmark placeholder gives the Ground Zero demo a visible
point of interest using five native placeholder stone pieces: foundation, point of interest using five native placeholder stone pieces: foundation,
wall fragments, a cairn marker, and a threshold. wall fragments, a cairn marker, and a threshold.
@@ -46,11 +47,11 @@ space.
`Scripts/verify_ground_zero_natural_environment_pass.py` checks that the `Scripts/verify_ground_zero_natural_environment_pass.py` checks that the
materials exist, the landscape uses the terrain material, the foliage actor has materials exist, the landscape uses the terrain material, the foliage actor has
the expected instance counts and material assignments, and resource/water actors the expected investor-facing instance counts and material assignments, and
are visually dressed. It also checks the first-pass asset variation layer: resource/water actors are visually dressed. It also checks the asset variation
eleven labeled variation actors, at least four mesh silhouettes, unique scale layer: twenty-three labeled variation actors, at least four mesh silhouettes,
profiles, and coverage across tree, bush, grass, rock, and water visual unique scale profiles, and coverage across tree, bush, grass, rock, and water
families. `Scripts/verify_native_placeholder_meshes.py` checks that playable visual families. `Scripts/verify_native_placeholder_meshes.py` checks that playable
resource/structure/water Blueprints, foliage components, and environment resource/structure/water Blueprints, foliage components, and environment
variation actors use Agrarian-native placeholder meshes rather than template variation actors use Agrarian-native placeholder meshes rather than template
mesh paths. `Scripts/verify_ground_zero_landmark_placeholder.py` checks the mesh paths. `Scripts/verify_ground_zero_landmark_placeholder.py` checks the
+112 -4
View File
@@ -7,7 +7,7 @@ import unreal
MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test" MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test"
PROJECT_ROOT = Path(r"Z:\AgrarianGameBulid") PROJECT_ROOT = Path(unreal.Paths.convert_relative_path_to_full(unreal.Paths.project_dir()))
TILE_ID = "gz_us_ca_pacifica_utm10n_e544_n4160" TILE_ID = "gz_us_ca_pacifica_utm10n_e544_n4160"
HEIGHTMAP_PATH = PROJECT_ROOT / "Data" / "Terrain" / "Unreal" / TILE_ID / f"{TILE_ID}_unreal_1009.r16" HEIGHTMAP_PATH = PROJECT_ROOT / "Data" / "Terrain" / "Unreal" / TILE_ID / f"{TILE_ID}_unreal_1009.r16"
LANDSCAPE_SIZE = 1009 LANDSCAPE_SIZE = 1009
@@ -443,6 +443,114 @@ ENVIRONMENT_VARIATION_ACTORS = [
"scale": unreal.Vector(2.6, 1.6, 1.0), "scale": unreal.Vector(2.6, 1.6, 1.0),
"rotation": unreal.Rotator(0.0, -15.0, 0.0), "rotation": unreal.Rotator(0.0, -15.0, 0.0),
}, },
{
"label": "AGR_GZ_EnvVar_Tree_Canopy_03",
"mesh_key": "chamfer_cube",
"material_key": "tree",
"location_xy": unreal.Vector(-8200.0, 12600.0, 0.0),
"z_offset": 360.0,
"scale": unreal.Vector(1.85, 2.25, 1.35),
"rotation": unreal.Rotator(0.0, 61.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Tree_Trunk_03",
"mesh_key": "cylinder",
"material_key": "wood_resource",
"location_xy": unreal.Vector(-8200.0, 12600.0, 0.0),
"z_offset": 155.0,
"scale": unreal.Vector(0.24, 0.24, 3.25),
"rotation": unreal.Rotator(0.0, 61.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Brush_Coyote_01",
"mesh_key": "chamfer_cube",
"material_key": "shrub",
"location_xy": unreal.Vector(-12600.0, -5100.0, 0.0),
"z_offset": 72.0,
"scale": unreal.Vector(1.7, 1.15, 0.62),
"rotation": unreal.Rotator(0.0, 7.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Brush_Coyote_02",
"mesh_key": "chamfer_cube",
"material_key": "shrub",
"location_xy": unreal.Vector(-10400.0, -8500.0, 0.0),
"z_offset": 74.0,
"scale": unreal.Vector(1.2, 1.85, 0.7),
"rotation": unreal.Rotator(0.0, -38.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Brush_Coyote_03",
"mesh_key": "chamfer_cube",
"material_key": "shrub",
"location_xy": unreal.Vector(-15800.0, -9800.0, 0.0),
"z_offset": 78.0,
"scale": unreal.Vector(1.55, 1.35, 0.58),
"rotation": unreal.Rotator(0.0, 47.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Grass_Mat_03",
"mesh_key": "plane",
"material_key": "grass",
"location_xy": unreal.Vector(-14600.0, -4200.0, 0.0),
"z_offset": 14.0,
"scale": unreal.Vector(3.2, 1.8, 1.0),
"rotation": unreal.Rotator(0.0, 16.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Grass_Mat_04",
"mesh_key": "plane",
"material_key": "grass",
"location_xy": unreal.Vector(-11800.0, -10600.0, 0.0),
"z_offset": 14.0,
"scale": unreal.Vector(2.1, 3.1, 1.0),
"rotation": unreal.Rotator(0.0, -27.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Rock_Slab_03",
"mesh_key": "quarter_cylinder",
"material_key": "stone_resource",
"location_xy": unreal.Vector(-9200.0, -7600.0, 0.0),
"z_offset": 48.0,
"scale": unreal.Vector(0.95, 1.45, 0.55),
"rotation": unreal.Rotator(0.0, 34.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Rock_Slab_04",
"mesh_key": "chamfer_cube",
"material_key": "stone_resource",
"location_xy": unreal.Vector(-18200.0, -5000.0, 0.0),
"z_offset": 42.0,
"scale": unreal.Vector(1.05, 0.72, 0.32),
"rotation": unreal.Rotator(0.0, -64.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Water_Bank_01",
"mesh_key": "quarter_cylinder",
"material_key": "stone_resource",
"location_xy": unreal.Vector(-6150.0, 9700.0, 0.0),
"z_offset": 42.0,
"scale": unreal.Vector(1.4, 0.75, 0.45),
"rotation": unreal.Rotator(0.0, 22.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Water_Reed_01",
"mesh_key": "cylinder",
"material_key": "grass",
"location_xy": unreal.Vector(-8050.0, 9600.0, 0.0),
"z_offset": 74.0,
"scale": unreal.Vector(0.08, 0.08, 1.35),
"rotation": unreal.Rotator(0.0, 11.0, 0.0),
},
{
"label": "AGR_GZ_EnvVar_Water_Reed_02",
"mesh_key": "cylinder",
"material_key": "grass",
"location_xy": unreal.Vector(-6600.0, 11700.0, 0.0),
"z_offset": 68.0,
"scale": unreal.Vector(0.07, 0.07, 1.15),
"rotation": unreal.Rotator(0.0, -19.0, 0.0),
},
] ]
RUIN_PLACEHOLDER_ACTORS = [ RUIN_PLACEHOLDER_ACTORS = [
@@ -496,7 +604,7 @@ RUIN_PLACEHOLDER_ACTORS = [
FOLIAGE_ZONES = { FOLIAGE_ZONES = {
"trees": { "trees": {
"count": 42, "count": 64,
"x_range": (-25000.0, 42000.0), "x_range": (-25000.0, 42000.0),
"y_range": (-12000.0, 42000.0), "y_range": (-12000.0, 42000.0),
"min_elevation_m": 18.0, "min_elevation_m": 18.0,
@@ -504,7 +612,7 @@ FOLIAGE_ZONES = {
"scale_range": (0.75, 1.35), "scale_range": (0.75, 1.35),
}, },
"shrubs": { "shrubs": {
"count": 96, "count": 148,
"x_range": (-42000.0, 45000.0), "x_range": (-42000.0, 45000.0),
"y_range": (-38000.0, 45000.0), "y_range": (-38000.0, 45000.0),
"min_elevation_m": 7.0, "min_elevation_m": 7.0,
@@ -512,7 +620,7 @@ FOLIAGE_ZONES = {
"scale_range": (0.45, 1.05), "scale_range": (0.45, 1.05),
}, },
"grass": { "grass": {
"count": 180, "count": 260,
"x_range": (-46000.0, 46000.0), "x_range": (-46000.0, 46000.0),
"y_range": (-46000.0, 46000.0), "y_range": (-46000.0, 46000.0),
"min_elevation_m": 4.0, "min_elevation_m": 4.0,
@@ -15,9 +15,9 @@ MATERIALS = {
"fresh_water": "/Game/Agrarian/Materials/M_AGR_GZ_FreshWater", "fresh_water": "/Game/Agrarian/Materials/M_AGR_GZ_FreshWater",
} }
EXPECTED_FOLIAGE_COUNTS = { EXPECTED_FOLIAGE_COUNTS = {
"trees": 42, "trees": 64,
"shrubs": 96, "shrubs": 148,
"grass": 180, "grass": 260,
} }
RESOURCE_MATERIALS = { RESOURCE_MATERIALS = {
"AGR_GZ_Wood": "wood_resource", "AGR_GZ_Wood": "wood_resource",
@@ -29,13 +29,16 @@ RESOURCE_MATERIALS = {
"AGR_GZ_FreshWaterSource": "fresh_water", "AGR_GZ_FreshWaterSource": "fresh_water",
} }
VARIATION_PREFIX = "AGR_GZ_EnvVar_" VARIATION_PREFIX = "AGR_GZ_EnvVar_"
EXPECTED_VARIATION_COUNT = 11 EXPECTED_VARIATION_COUNT = 23
EXPECTED_VARIATION_MATERIALS = { EXPECTED_VARIATION_MATERIALS = {
"AGR_GZ_EnvVar_Tree_Canopy": "tree", "AGR_GZ_EnvVar_Tree_Canopy": "tree",
"AGR_GZ_EnvVar_Tree_Trunk": "wood_resource", "AGR_GZ_EnvVar_Tree_Trunk": "wood_resource",
"AGR_GZ_EnvVar_Bush": "shrub", "AGR_GZ_EnvVar_Bush": "shrub",
"AGR_GZ_EnvVar_Brush": "shrub",
"AGR_GZ_EnvVar_Grass": "grass", "AGR_GZ_EnvVar_Grass": "grass",
"AGR_GZ_EnvVar_Rock": "stone_resource", "AGR_GZ_EnvVar_Rock": "stone_resource",
"AGR_GZ_EnvVar_Water_Bank": "stone_resource",
"AGR_GZ_EnvVar_Water_Reed": "grass",
"AGR_GZ_EnvVar_Water": "fresh_water", "AGR_GZ_EnvVar_Water": "fresh_water",
} }
@@ -170,8 +173,8 @@ def main():
if len(variation_meshes) < 4: if len(variation_meshes) < 4:
failures.append(f"expected at least 4 variation mesh silhouettes, got {len(variation_meshes)}") failures.append(f"expected at least 4 variation mesh silhouettes, got {len(variation_meshes)}")
if len(variation_scales) < EXPECTED_VARIATION_COUNT: if len(variation_scales) < 18:
failures.append("environment variation actors should use unique scale profiles") failures.append(f"environment variation actors should use at least 18 scale profiles, got {len(variation_scales)}")
if not {"tree", "wood_resource", "shrub", "grass", "stone_resource", "fresh_water"}.issubset(variation_material_keys): if not {"tree", "wood_resource", "shrub", "grass", "stone_resource", "fresh_water"}.issubset(variation_material_keys):
failures.append("environment variation actors do not cover tree, shrub, grass, resource, and water families") failures.append("environment variation actors do not cover tree, shrub, grass, resource, and water families")