feat: author discoverable forest edge
This commit is contained in:
@@ -792,14 +792,21 @@ Completed:
|
||||
player berry harvests thin fruit and leaves; real NPC wood gathers thin the
|
||||
crown and leave a stump. Low and depleted saves restore the same visuals
|
||||
using only `amount_remaining`, with matched Metal comparison frames.
|
||||
39. `Jajce Forest Edge 06`: `tree_forest_grove_01` and
|
||||
`tree_forest_grove_02` now anchor a bounded forest-edge cluster beyond the
|
||||
first 24 m discovery pass. Two decorative trees plus 24 fern, mushroom, and
|
||||
stone instances stay presentation-only. Both finite trees remain reachable,
|
||||
deplete into shared stumps, restore from authoritative amount, and keep the
|
||||
world/save total at eighteen resources.
|
||||
|
||||
Next:
|
||||
|
||||
1. Move the existing `tree_forest_grove_01` and `tree_forest_grove_02` anchors
|
||||
into one bounded forest-edge authoring cluster. Reuse the proven tree amount
|
||||
presentation, preserve both stable IDs, and prove reachable expanding
|
||||
discovery plus depletion/restore without serializing decorative foliage.
|
||||
2. Add livestock only with a real identity and interaction contract.
|
||||
1. Add one named goat as an identity-backed simulation vertical slice: stable
|
||||
animal ID, authoritative position and hunger/feed state, loaded visual
|
||||
binding, and an exact feed interaction shared by one NPC and the player.
|
||||
Feeding must withdraw real pantry food and survive deterministic save/load.
|
||||
2. Add a small herd, breeding, or animal products only after that single-animal
|
||||
identity and conservation contract is proven.
|
||||
|
||||
Do not start with GIS data, a full city, a large asset pack, or more NPC
|
||||
mechanics. The next proof is a beautiful stage for the systems that already
|
||||
|
||||
@@ -912,16 +912,33 @@ gathers thin the crown and ultimately leave a warm-cut stump. Restoring both
|
||||
low and depleted snapshots rebinds the same nodes and reconstructs the same
|
||||
visuals from `ResourceStateRecord.amount_remaining` alone.
|
||||
|
||||
The immediate next slice should apply that proven contract to the existing
|
||||
`tree_forest_grove_01` and `tree_forest_grove_02` anchors as one bounded
|
||||
forest-edge authoring consumer. Preserve both stable IDs, keep decorative
|
||||
canopy/understory outside simulation state, and prove reachable expanding
|
||||
discovery plus depletion/restore with the shared tree presentation. Do not
|
||||
generalize the resource grid to people/buildings/events or introduce
|
||||
active/abstract LOD before those consumers need it.
|
||||
The second authored foliage/resource workflow is complete. The existing
|
||||
`tree_forest_grove_01` and `tree_forest_grove_02` anchors now form one bounded
|
||||
forest edge with two decorative silhouette trees and 24 fern, mushroom, and
|
||||
stone instances in three MultiMesh batches. Both stable IDs and definitions
|
||||
remain authoritative, while village-facing interaction points sit beyond the
|
||||
initial 24 m discovery radius and remain reachable on the Terrain3D-derived
|
||||
navigation mesh. Real NPC depletion leaves the shared stump and restore
|
||||
rebuilds the sparse standing tree from amount alone. The river and forest
|
||||
clusters now share only the terrain-snap, bounded-instance, and anchor-layout
|
||||
code proven by those two consumers.
|
||||
|
||||
The immediate next slice should introduce livestock only through one
|
||||
identity-backed animal vertical slice: one named goat with a stable animal ID,
|
||||
simulation-owned position and hunger/feed state, a loaded presentation binding,
|
||||
and one exact feed interaction available to both an NPC and the player. Feeding
|
||||
must consume real pantry food and save/restore deterministically. Do not make
|
||||
the animal a `ResourceNode`, add a herd, breeding, products, or a generalized
|
||||
animal spatial index before that first identity and conservation contract is
|
||||
honest.
|
||||
|
||||
Recently completed:
|
||||
|
||||
- `Jajce Forest Edge 06`: two existing deep-forest tree IDs now anchor a
|
||||
restrained four-tree silhouette with 24 decorative understory instances.
|
||||
Both targets require expanded loaded-resource discovery, remain reachable,
|
||||
reuse amount-driven crowns/stumps, and preserve the eighteen-resource save
|
||||
contract through real NPC depletion and restore.
|
||||
- `Jajce Resource States 05`: the authored river berry/tree now derive full,
|
||||
low, and depleted visuals from authoritative amounts. Player and NPC
|
||||
extraction drive the changes, save/restore reconstructs low and depleted
|
||||
|
||||
@@ -982,14 +982,15 @@ Raw samples and workload exclusions live in
|
||||
[Simulation scaling baseline 02](benchmarks/SIMULATION_SCALING_BASELINE_02.md)
|
||||
and [Loaded Resource Discovery 01](benchmarks/LOADED_RESOURCE_DISCOVERY_01.md).
|
||||
|
||||
The authored Jajce watercourse, navigation rebake, and first bounded
|
||||
foliage/resource placement proof are complete. The next slice should derive
|
||||
low/depleted berry and tree visuals from authoritative resource amount, cover
|
||||
real NPC/player extraction and save/restore reconstruction, and keep that
|
||||
presentation out of serialized simulation state. Apply the cluster workflow to
|
||||
a second forest edge only after the depletion contract supplies a real second
|
||||
consumer. Do not yet generalize the resource grid or introduce active/abstract
|
||||
simulation LOD.
|
||||
The authored Jajce watercourse, navigation rebake, amount-derived resource
|
||||
visuals, and two bounded foliage/resource placement proofs are complete. The
|
||||
riverbank and forest edge preserve stable finite-resource IDs, separate
|
||||
decorative density from simulation authority, support discovery beyond the
|
||||
first 24 m range, and reconstruct sparse/depleted visuals from authoritative
|
||||
amount. The next slice should introduce one named goat only through a stable
|
||||
simulation identity, authoritative position and feed state, loaded visual
|
||||
binding, exact NPC/player feeding cost, and deterministic save/restore. Do not
|
||||
yet generalize the resource grid or introduce active/abstract simulation LOD.
|
||||
|
||||
The remaining simulation-garden target still aims for:
|
||||
|
||||
|
||||
@@ -577,6 +577,15 @@ selects the farther berry only after expanding beyond the first 24 m range.
|
||||
The matched review lives in
|
||||
[Jajce Resource Grove 04](baselines/JAJCE_RESOURCE_GROVE_04.md).
|
||||
|
||||
Amount-derived berry/tree presentation and the second placement consumer are
|
||||
also complete. `ResourceAmountVisual` reconstructs full, low, and depleted
|
||||
states from authoritative amount without adding save fields. The existing
|
||||
`tree_forest_grove_01` and `tree_forest_grove_02` records now sit inside one
|
||||
bounded forest-edge cluster with reachable interaction points beyond 24 m;
|
||||
forced resolution expands to the stable ID, and real NPC depletion/restore
|
||||
reuses the same crown/stump contract. The matched review lives in
|
||||
[Jajce Forest Edge 06](baselines/JAJCE_FOREST_EDGE_06.md).
|
||||
|
||||
## Test scenarios
|
||||
|
||||
At minimum, exercise:
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Jajce Forest Edge 06
|
||||
|
||||
Captured: 2026-07-18
|
||||
|
||||
## Files
|
||||
|
||||
- [before forest edge](jajce_forest_edge_06_before.png)
|
||||
- [authored forest edge](jajce_forest_edge_06_after.png)
|
||||
- [finite trees depleted](jajce_forest_edge_06_depleted.png)
|
||||
- `world/jajce/ForestEdgeResourceCluster.tscn`
|
||||
- `world/jajce/TerrainResourceCluster.gd`
|
||||
- `tests/jajce_forest_edge_cluster_test.gd`
|
||||
|
||||
The images use the same 1280×720 camera, fixed daylight value, warmup, and
|
||||
Metal renderer. Debug labels are hidden. The before frame shows two generic
|
||||
resource boxes below disconnected south-edge trees. The authored frame uses
|
||||
the same finite IDs as the two central harvestable trees; the depleted frame
|
||||
shows those two as stumps while the decorative forest silhouette remains.
|
||||
|
||||
## Visual reduction
|
||||
|
||||
The forest edge contains:
|
||||
|
||||
- 10 low-poly fern clumps;
|
||||
- 8 oversized cream-stem, warm-cap mushrooms;
|
||||
- 6 flattened forest stones;
|
||||
- 2 decorative deciduous silhouette trees; and
|
||||
- 2 finite harvestable trees with amount-derived crowns and stumps.
|
||||
|
||||
The 24 understory details use three `MultiMeshInstance3D` batches. The two
|
||||
existing south-edge conifers remain outside the cluster and frame it at a
|
||||
larger scale. This keeps the grove legible from the village without turning the
|
||||
whole terrain into dense foliage.
|
||||
|
||||
## Authority and shared authoring contract
|
||||
|
||||
`ResourceAnchors` contains only `tree_forest_grove_01` and
|
||||
`tree_forest_grove_02`, preserving their definitions and the existing total of
|
||||
eighteen finite resources. `DecorativeInstances` contains no `ResourceNode`
|
||||
descendants and never enters saves, reservations, checksums, or conservation.
|
||||
|
||||
The riverbank and forest edge are now the two concrete consumers of
|
||||
`TerrainResourceCluster`. That small shared base owns only their proven scene
|
||||
contract: terrain snapping for authored trees and interaction points, bounded
|
||||
MultiMesh placement, fern mesh construction, resource-anchor enumeration, and
|
||||
presentation statistics. Resource-specific palettes, offsets, and meshes stay
|
||||
in each cluster.
|
||||
|
||||
Both finite trees reuse `HarvestableTreePresentation`. Depletion therefore
|
||||
removes only the authoritative standing trees; the two decorative trees and
|
||||
surrounding conifers remain, giving the living world an honest but not barren
|
||||
silhouette.
|
||||
|
||||
## Discovery, navigation, and restore proof
|
||||
|
||||
The trees moved roughly five metres deeper into the forest edge. Their
|
||||
village-facing interaction points are approximately 26.5 m and 26.2 m from the
|
||||
village origin, beyond the adapter's initial 24 m query. The focused scenario
|
||||
confirms both IDs appear only in the farther query, disables every other wood
|
||||
source, and resolves `tree_forest_grove_01` after more than one range pass.
|
||||
|
||||
The same scenario asks the project-owned navigation map for real paths to both
|
||||
interaction points, verifies each endpoint is reached, and checks every route
|
||||
point against Terrain3D height. No terrain or navigation rebake was needed.
|
||||
|
||||
Finally, the test leaves the first tree at one configured yield, saves that low
|
||||
state, and completes a real reserved NPC gather. The exact yield enters NPC
|
||||
inventory and the tree becomes a stump. Restoring the snapshot rebinds the
|
||||
same stable ID and reconstructs the sparse standing crown from authoritative
|
||||
amount alone.
|
||||
|
||||
## Next slice
|
||||
|
||||
Introduce one named goat as an identity-backed simulation entity rather than a
|
||||
resource prop. Its stable ID, position, and hunger/feed state should be saved;
|
||||
one NPC and the player should share an exact feed interaction that withdraws
|
||||
real pantry food. A herd, breeding, products, and animal spatial indexing stay
|
||||
deferred until that contract is proven.
|
||||
|
||||
## Capture commands
|
||||
|
||||
```bash
|
||||
HOME="$PWD/logs/quality/godot_profile" \
|
||||
APPDATA="$PWD/logs/quality/godot_profile" \
|
||||
LOCALAPPDATA="$PWD/logs/quality/godot_profile" \
|
||||
/Applications/Godot.app/Contents/MacOS/Godot \
|
||||
--path "$PWD" --script res://tools/capture_jajce_lookdev.gd -- \
|
||||
--scene=res://world/jajce/JajceForestEdgeLookdev.tscn \
|
||||
--output=res://docs/baselines/jajce_forest_edge_06_after.png \
|
||||
--hide-resource-labels
|
||||
```
|
||||
|
||||
For the depleted frame, append:
|
||||
|
||||
```text
|
||||
--resource-amount=tree_forest_grove_01:0
|
||||
--resource-amount=tree_forest_grove_02:0
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 518 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://4tlahsqubofd"
|
||||
path="res://.godot/imported/jajce_forest_edge_06_after.png-cc336e5231ac96e8d23247a881a0ec1c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/baselines/jajce_forest_edge_06_after.png"
|
||||
dest_files=["res://.godot/imported/jajce_forest_edge_06_after.png-cc336e5231ac96e8d23247a881a0ec1c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 518 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://gsie1efiik5"
|
||||
path="res://.godot/imported/jajce_forest_edge_06_before.png-ecb42151d9a8db85404cc1153afa0bcf.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/baselines/jajce_forest_edge_06_before.png"
|
||||
dest_files=["res://.godot/imported/jajce_forest_edge_06_before.png-ecb42151d9a8db85404cc1153afa0bcf.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 518 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dnu1owrmly7wf"
|
||||
path="res://.godot/imported/jajce_forest_edge_06_depleted.png-08c916e5b04639615251b670dcd41f56.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/baselines/jajce_forest_edge_06_depleted.png"
|
||||
dest_files=["res://.godot/imported/jajce_forest_edge_06_depleted.png-08c916e5b04639615251b670dcd41f56.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Reference in New Issue
Block a user