Files
Project-M/Assets/_Project/Scripts/Client/Presentation/DecalConfig.cs
T
kronic 649f656833 Decals: explosion scorch pool + cover damage-cracks + room-arena scars (Phase 1.5b bundle 2)
All procedural, client-only, observe-only in PresentationSystemGroup, zero
netcode surface (read existing replicated state). Shared FeedbackFx decal
primitives (scorch blob + crack star meshes + transparent decal material).
ScorchDecalSystem: static RequestScorch queue -> pooled fading discs
(mirrors DynamicLightSystem), wired from the barrel boom, reusable by the
geyser. CoverDamageSystem: crack accretion keyed on BlightClutter.Remaining
(Variant 4) + proximity-gated shatter-scorch. RoomDressingSystem: persistent
arena scars on a distinct hash sub-stream, torn down with dressing. Knobs in
DecalConfig. Cover cracks use decals (not URPMaterialPropertyBaseColor) because
the Synty prop shader is not Hybrid-Per-Instance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 12:58:33 -07:00

69 lines
3.5 KiB
C#

using UnityEngine;
namespace ProjectM.Client
{
/// <summary>
/// Live-tunable knobs for the client-only DECALS slice (Phase 1.5b bundle 2: explosion scorch pool, cover
/// damage cracks, room-arena scars). A static bridge (mirrors <see cref="WorldFeelConfig"/> / <see cref="FeelConfig"/>)
/// so values can be poked at runtime via MCP <c>execute_code</c> without a recompile
/// (e.g. <c>ProjectM.Client.DecalConfig.ScorchColor = ...;</c>). Read ONLY by the decal presentation systems
/// (<see cref="ScorchDecalSystem"/>, <see cref="CoverDamageSystem"/>) and <see cref="RoomDressingSystem"/> — all
/// managed, main-thread. NEVER read from a [BurstCompile] system (managed-static + Color-in-Burst hazards).
/// <see cref="ResetDefaults"/> re-stamps on play-enter via [RuntimeInitializeOnLoadMethod] because statics survive
/// fast-enter-playmode reloads (else a poked value leaks across play-enters).
/// </summary>
public static class DecalConfig
{
/// <summary>Master gate for every decal (scorch pool + cover cracks + room scars).</summary>
public static bool Enabled;
// ---- explosion scorch pool (ScorchDecalSystem) ----
/// <summary>Scorch disc radius as a multiple of the explosion radius passed to RequestScorch.</summary>
public static float ScorchRadiusMul;
/// <summary>Seconds a fresh scorch holds at full strength before it starts fading.</summary>
public static float ScorchHoldSec;
/// <summary>Seconds a scorch fades from full to gone (then returns to the pool).</summary>
public static float ScorchFadeSec;
/// <summary>Peak scorch tint (dark char); the alpha is the peak opacity it fades from.</summary>
public static Color ScorchColor;
/// <summary>Max live scorch decals; the oldest is recycled past this.</summary>
public static int ScorchPoolCap;
// ---- cover damage cracks (CoverDamageSystem) ----
/// <summary>Crack-decal tint (dark).</summary>
public static Color CoverCrackColor;
/// <summary>Max crack decals accreted around one cover rock as it is carved to 0.</summary>
public static int CoverCrackMaxCount;
/// <summary>Drop a small ground scorch/debris mark where a cover rock shattered.</summary>
public static bool CoverShatterScorch;
// ---- room-arena scars (RoomDressingSystem) ----
/// <summary>Persistent crack/scorch detail decals laid at the room arena centre (0 = off).</summary>
public static int RoomArenaDecalCount;
/// <summary>Room-arena scar tint (dark, subtle).</summary>
public static Color RoomDecalColor;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void ResetDefaults()
{
Enabled = true;
// scorch pool — slightly inside the blast radius so it reads as the burn, not the danger ring
ScorchRadiusMul = 0.85f;
ScorchHoldSec = 4f;
ScorchFadeSec = 6f;
ScorchColor = new Color(0.05f, 0.04f, 0.03f, 0.85f); // near-black char, mostly opaque at peak
ScorchPoolCap = 24;
// cover cracks
CoverCrackColor = new Color(0.06f, 0.05f, 0.05f, 0.8f);
CoverCrackMaxCount = 3;
CoverShatterScorch = true;
// room-arena scars
RoomArenaDecalCount = 3;
RoomDecalColor = new Color(0.08f, 0.07f, 0.06f, 0.5f); // subtle
}
}
}