TerrainScanner
TerrainScanner — Death Stranding style terrain scanner for PEAK. Provides persistent ground marks, scan outlines, and customizable visuals.
| Last updated | a month ago |
| Total downloads | 2397 |
| Total rating | 3 |
| Categories | Mods Tools World Quality Of Life Client Side All Clients Optimization |
| Dependency string | LIghtPeak-TerrainScanner-1.1.2 |
| Dependants | 1 other package depends on this package |
This mod requires the following mods to function
BepInEx-BepInExPack_PEAK
BepInEx pack for PEAK. Preconfigured and ready to use.
Preferred version: 5.4.75301Cysharp-UniTask
Provides an efficient allocation free async/await integration for Unity.
Preferred version: 2.5.0README
TerrainScanner

Terrain scanner is based on shader and is rendered by GPU. And asynchronous frame rendering, so it is fast and not stuck.
What it shows
- Slope classification (example thresholds used by the module):
- Flat: 0°–30°
- Gentle slope: 30°–50°
- Steep: 50°–90°
These thresholds are configurable via ScanConfig (see below).
Quick install / usage
-
Add the
TerrainScannerscripts (or compiled DLL) into your Unity project'sAssets/folder. The source is located insrc/TerrainScanner/in this repository. -
In your scene, attach
ActiveScanto a GameObject (for example, the Player or Camera). By default the scanner is triggered with theQkey (seeActiveScan.cs). -
Ensure
ScanConfigis properly populated at runtime with the required materials and particle prefabs:scanMaterial(shader for scan wave)markMaterial(instanced shader for marks)markParticle1/markParticle2/markParticle3(optional particle prefabs)
If you're using a mod loader (BepInEx) the plugin can populate these for you at startup.
Configuration (important fields)
Most runtime options live in ScanConfig (src/TerrainScanner/Config.cs). Important values:
horizontalCount,verticalCount— sampling grid size. Larger values increase coverage and precision but cost more CPU.gridStep— spacing between samples (meters).sampling_originHeightOffset— how far above the camera/player the ray origin starts. Increase this to scan higher terrain.sampling_maxDistanceShort/sampling_maxDistanceLong— raycast lengths for ground/ledge and long-range tests.steepSpawnProb,midSpawnProb,flatSpawnProb— per-category particle spawn probabilities.
Tune these values via the ScanConfigManager or by binding them in your plugin's initialization.
Troubleshooting
-
I see only some marks rendered even though scanning detected many hits:
- Make sure the CPU-side
Marksstruct layout matches the HLSLMarksStructuredBuffer. Field order and sizes must match. - Ensure
ComputeBufferis created with the correct stride (useMarshal.SizeOf(typeof(Marks))). - Check the instanced shader does not write depth in the fragment stage (writing
SV_DEPTHin the fragment can cause depth conflicts and hide instances). Move depth calculation to the vertex stage or remove manual depth writes.
- Make sure the CPU-side
-
Rays don't reach high cliffs:
- Increase
sampling_originHeightOffsetandsampling_maxDistanceShort.
- Increase
-
Performance concerns:
- The sampling runs in slices (uses
UniTask.Yield()to avoid blocking the main thread). If you increase resolution, consider reducinghorizontalCount/verticalCountor lowering sample frequency. - Consider limiting how many marks are uploaded to the GPU per frame (e.g. keep only the nearest N marks or prioritize by slope category).
- The sampling runs in slices (uses
Roadmap — Smarter Terrain Scanner (next major feature)
Planned: an "Intelligent Terrain Scanner" that improves scanning quality while staying performant. High-level goals and design notes:
-
Energy-based propagation model
- Each discovered sample carries an energy budget (kinetic + potential). Propagation to neighbors consumes energy for distance traveled and for climbing.
- Branching reduces energy (spawn cost). A cell is revisited only if arriving with strictly more remaining energy (best-energy rule).
-
Priority-driven exploration
- Replace the plain FIFO propagation queue with a priority queue sorted by remaining energy (prefer uphill, higher-energy fronts) so the algorithm finds viable ascent routes sooner.
-
Quantized, memory-efficient state
- Store per-cell discovered heights as quantized keys (e.g. 0.1m precision) in HashSets to avoid float equality problems and to reduce duplicates.
-
Safety & termination
- Global processed-count cap and local energy thresholds to prevent runaway propagation in caves or dense geometry.
-
Runtime tuning and visualization
- Expose energy parameters and propagation limits in
ScanConfigso users can tune behavior. - Add an optional debug overlay to visualize propagation fronts, queued items, and per-cell best-energy values.
- Expose energy parameters and propagation limits in
Why this helps:
- It prevents infinite propagation in complex geometry (caves/overhangs).
- It prioritizes realistic uphill routes, helping scans find reachable ground rather than flooding every neighboring cell.
- It keeps performance predictable and tunable.
Contributing
Contributions, issues, and suggestions are welcome. When opening a PR:
- Explain the problem or feature and include screenshots or logs if relevant.
- Keep changes focused; large refactors are easier to review if split into smaller PRs.
License
This project is licensed under the terms in LICENSE.