diff --git a/Assets/_Project/Scripts/Authoring/Automation/FabricatorAuthoring.cs b/Assets/_Project/Scripts/Authoring/Automation/FabricatorAuthoring.cs index 114ba3809..c6947eae1 100644 --- a/Assets/_Project/Scripts/Authoring/Automation/FabricatorAuthoring.cs +++ b/Assets/_Project/Scripts/Authoring/Automation/FabricatorAuthoring.cs @@ -15,10 +15,10 @@ namespace ProjectM.Authoring public class FabricatorAuthoring : MonoBehaviour { [Tooltip("Input resource id consumed per run (1=Aether, 2=Ore, 3=Biomass).")] - public byte InResourceId = 2; // Ore + public byte InResourceId = ResourceId.Ore; [Min(1)] public int InAmount = 1; [Tooltip("Output resource id deposited to the global ledger (4 = EB-2 Charge / turret ammo).")] - public byte OutResourceId = 4; // Charge + public byte OutResourceId = ResourceId.Charge; [Min(1)] public int OutAmount = 3; [Min(1)] public int PeriodTicks = 30; [Tooltip("EB-2: 1 = ledger-fed (consume the input from the shared ledger; no conveyor). 0 = M7 MachineInput chain.")] diff --git a/Assets/_Project/Scripts/Authoring/Automation/HarvesterAuthoring.cs b/Assets/_Project/Scripts/Authoring/Automation/HarvesterAuthoring.cs index df21fd65e..5e8ebc3b2 100644 --- a/Assets/_Project/Scripts/Authoring/Automation/HarvesterAuthoring.cs +++ b/Assets/_Project/Scripts/Authoring/Automation/HarvesterAuthoring.cs @@ -13,7 +13,7 @@ namespace ProjectM.Authoring public class HarvesterAuthoring : MonoBehaviour { [Tooltip("Resource id this generator produces (1=Aether, 2=Ore, 3=Biomass).")] - public byte OutputResourceId = 2; // Ore + public byte OutputResourceId = ResourceId.Ore; [Min(1)] public int Yield = 1; [Min(1)] public int PeriodTicks = 60; diff --git a/Assets/_Project/Scripts/Authoring/Building/StructureCatalogAuthoring.cs b/Assets/_Project/Scripts/Authoring/Building/StructureCatalogAuthoring.cs index 1104e01ba..ca38787d0 100644 --- a/Assets/_Project/Scripts/Authoring/Building/StructureCatalogAuthoring.cs +++ b/Assets/_Project/Scripts/Authoring/Building/StructureCatalogAuthoring.cs @@ -1,6 +1,7 @@ using ProjectM.Simulation; using Unity.Entities; using UnityEngine; +using UnityEngine.Serialization; namespace ProjectM.Authoring { @@ -23,8 +24,8 @@ namespace ProjectM.Authoring [Tooltip("Wall structure ghost prefab (StructureAuthoring{Wall} + GhostAuthoring).")] public GameObject WallPrefab; - [Tooltip("Ore cost to build a wall.")] - [Min(0)] public int WallCostOre = 4; + [Tooltip("Biomass cost to build a wall.")] + [Min(0)] [FormerlySerializedAs("WallCostOre")] public int WallCostBiomass = 4; [Tooltip("Pylon cosmetic-beacon ghost prefab (StructureAuthoring{Pylon} + GhostAuthoring).")] public GameObject PylonPrefab; @@ -69,7 +70,7 @@ namespace ProjectM.Authoring Type = StructureType.Wall, Prefab = GetEntity(authoring.WallPrefab, TransformUsageFlags.Dynamic), CostResourceId = ResourceId.Biomass, // DR-042 C6b: walls cost Biomass (the dead currency's only sink) - CostAmount = authoring.WallCostOre, + CostAmount = authoring.WallCostBiomass, }); } diff --git a/Assets/_Project/Scripts/Authoring/Combat/EnemyAuthoring.cs b/Assets/_Project/Scripts/Authoring/Combat/EnemyAuthoring.cs index c81cbb4b2..ce1d6d697 100644 --- a/Assets/_Project/Scripts/Authoring/Combat/EnemyAuthoring.cs +++ b/Assets/_Project/Scripts/Authoring/Combat/EnemyAuthoring.cs @@ -66,7 +66,7 @@ namespace ProjectM.Authoring // {ChargerAuthoring(LungeState), SpitterAuthoring(SpitterState)} — both would match ZERO AI passes. if (GetComponent() != null && spitter != null) Debug.LogError($"Enemy '{authoring.name}' has BOTH ChargerAuthoring and SpitterAuthoring; it would match no AI pass and never move. Remove one.", authoring); - if (GetComponent() != null) { kind = ZoneEnemyMath.KindCharger; windup = 30; } + if (GetComponent() != null) { kind = ZoneEnemyMath.KindCharger; windup = (byte)Tuning.ChargerWindupTicks; } else if (spitter != null) { kind = ZoneEnemyMath.KindSpitter; windup = (byte)Mathf.Clamp(spitter.WindupTicks, 1, 255); } else if (GetComponent() != null) { kind = ZoneEnemyMath.KindSwarmer; windup = (byte)Tuning.AttackWindupTicks; /* B4: match the server windup (grunt-path swarmers use GruntWindupTicks); baked 6 was a snap-ramp lie */ } AddComponent(entity, new EnemyTelegraph { WindupTicks = windup, Kind = kind }); diff --git a/Assets/_Project/Scripts/Authoring/Player/PlayerCharacterAuthoring.cs b/Assets/_Project/Scripts/Authoring/Player/PlayerCharacterAuthoring.cs index 8faf00b49..90112fb24 100644 --- a/Assets/_Project/Scripts/Authoring/Player/PlayerCharacterAuthoring.cs +++ b/Assets/_Project/Scripts/Authoring/Player/PlayerCharacterAuthoring.cs @@ -24,7 +24,7 @@ namespace ProjectM.Authoring public class PlayerCharacterAuthoring : MonoBehaviour { [Tooltip("Sharpness of ground velocity smoothing (higher = snappier).")] - public float GroundedMovementSharpness = 15f; + public float GroundedMovementSharpness = CharacterComponent.DefaultGroundedSharpness; public AuthoringKinematicCharacterProperties CharacterProperties = AuthoringKinematicCharacterProperties.GetDefault(); diff --git a/Assets/_Project/Scripts/Client/Onboarding/OnboardingSystem.cs b/Assets/_Project/Scripts/Client/Onboarding/OnboardingSystem.cs index bf97f0c79..e227bc5cc 100644 --- a/Assets/_Project/Scripts/Client/Onboarding/OnboardingSystem.cs +++ b/Assets/_Project/Scripts/Client/Onboarding/OnboardingSystem.cs @@ -25,7 +25,7 @@ namespace ProjectM.Client [UpdateInGroup(typeof(PresentationSystemGroup))] public partial class OnboardingSystem : SystemBase { - const float ExpeditionRegionXMin = 500f; // player x past this = the +1000 expedition region (mirrors HudSystem) + const float ExpeditionRegionXMin = RegionMath.RegionBoundaryX; // player x past this = the +1000 expedition region (mirrors HudSystem) GameObject _go; UIDocument _doc; diff --git a/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs b/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs index 6d3538199..5159d4232 100644 --- a/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs +++ b/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs @@ -45,7 +45,7 @@ namespace ProjectM.Client static readonly Color SlotSelBg = new(0.16f, 0.26f, 0.32f, 0.95f); static readonly Color SlotIdleBorder = new(1f, 1f, 1f, 0.08f); const int MaxPips = 12; - const float ExpeditionRegionXMin = 500f; // camera x past this = the +1000 expedition region (DR-013) + const float ExpeditionRegionXMin = RegionMath.RegionBoundaryX; // camera x past this = the +1000 expedition region (DR-013) GameObject _hudGo; UIDocument _doc; diff --git a/Assets/_Project/Scripts/Client/UI/WorldLauncher.cs b/Assets/_Project/Scripts/Client/UI/WorldLauncher.cs index 31ace2fbc..fbb130803 100644 --- a/Assets/_Project/Scripts/Client/UI/WorldLauncher.cs +++ b/Assets/_Project/Scripts/Client/UI/WorldLauncher.cs @@ -102,7 +102,7 @@ namespace ProjectM.Client Busy = false; } - static void Seed(World world, ConnectionMode mode, string address, ushort port) + static void Seed(World world, byte mode, string address, ushort port) { if (world is not { IsCreated: true }) return; var em = world.EntityManager; diff --git a/Assets/_Project/Scripts/Simulation/Connection/ConnectionConfig.cs b/Assets/_Project/Scripts/Simulation/Connection/ConnectionConfig.cs index 3d84bb037..a7c477990 100644 --- a/Assets/_Project/Scripts/Simulation/Connection/ConnectionConfig.cs +++ b/Assets/_Project/Scripts/Simulation/Connection/ConnectionConfig.cs @@ -11,17 +11,19 @@ namespace ProjectM.Simulation /// NetworkStreamRequestConnect and clears . Direct IP/LAN only for now — /// Unity Relay is deferred to a later pass. Created per-world as a singleton. /// - public enum ConnectionMode : byte + /// Connection intent values (byte-const, matching the project's op/id convention — not an enum, so + /// they stay safe if a consumer is ever [BurstCompile]d). Written to . + public static class ConnectionMode { - None, - Host, - Join, + public const byte None = 0; + public const byte Host = 1; + public const byte Join = 2; } public struct ConnectionConfig : IComponentData { /// What to do with this world's network stream. - public ConnectionMode Mode; + public byte Mode; /// Dotted IPv4 to connect to (Join). Ignored for Host (binds AnyIpv4). public FixedString64Bytes Address; diff --git a/Assets/_Project/Scripts/Simulation/Debug/TuningConfig.cs b/Assets/_Project/Scripts/Simulation/Debug/TuningConfig.cs index adf4d61ab..13beab0d9 100644 --- a/Assets/_Project/Scripts/Simulation/Debug/TuningConfig.cs +++ b/Assets/_Project/Scripts/Simulation/Debug/TuningConfig.cs @@ -74,7 +74,7 @@ namespace ProjectM.Simulation RecoverTailTicks = 9f, DashCooldownTicks = 36f, // tune: was 45 (0.75s) -> 0.60s, snappier horde-kiter cadence DashSharpness = 200f, - ChargerWindupTicks = 30f, + ChargerWindupTicks = Tuning.ChargerWindupTicks, ChargerLungeSpeed = 16f, ChargerLungeDurationTicks = 18f, ChargerWhiffStaggerTicks = 36f, diff --git a/Assets/_Project/Scripts/Simulation/Items/InventorySlot.cs b/Assets/_Project/Scripts/Simulation/Items/InventorySlot.cs index bb9f84dc6..acbfee33d 100644 --- a/Assets/_Project/Scripts/Simulation/Items/InventorySlot.cs +++ b/Assets/_Project/Scripts/Simulation/Items/InventorySlot.cs @@ -23,7 +23,7 @@ namespace ProjectM.Simulation /// subscene MUST be re-baked (consistently in both worlds) or the connect handshake desyncs. /// [GhostComponent(OwnerSendType = SendToOwnerType.All)] - [InternalBufferCapacity(24)] + [InternalBufferCapacity(Tuning.InventoryMaxSlots)] public struct InventorySlot : IBufferElementData { /// Item carried in this slot (0 = empty/unused; aligns with InventoryMath's 0-id no-op). diff --git a/Assets/_Project/Scripts/Simulation/Player/CharacterComponents.cs b/Assets/_Project/Scripts/Simulation/Player/CharacterComponents.cs index 03621905c..6ab28633a 100644 --- a/Assets/_Project/Scripts/Simulation/Player/CharacterComponents.cs +++ b/Assets/_Project/Scripts/Simulation/Player/CharacterComponents.cs @@ -16,6 +16,10 @@ namespace ProjectM.Simulation [Serializable] public struct CharacterComponent : IComponentData { + /// The CC's default grounded-movement smoothing sharpness — the single source for GetDefault, the + /// authoring default, DashSystem's base, and the death-state reset. + public const float DefaultGroundedSharpness = 15f; + /// How quickly RelativeVelocity is lerped toward the target velocity on the ground. public float GroundedMovementSharpness; @@ -26,7 +30,7 @@ namespace ProjectM.Simulation { return new CharacterComponent { - GroundedMovementSharpness = 15f, + GroundedMovementSharpness = DefaultGroundedSharpness, StepAndSlopeHandling = BasicStepAndSlopeHandlingParameters.GetDefault(), }; } diff --git a/Assets/_Project/Scripts/Simulation/Player/DashSystem.cs b/Assets/_Project/Scripts/Simulation/Player/DashSystem.cs index 61e6f0336..35935cf1c 100644 --- a/Assets/_Project/Scripts/Simulation/Player/DashSystem.cs +++ b/Assets/_Project/Scripts/Simulation/Player/DashSystem.cs @@ -32,7 +32,7 @@ namespace ProjectM.Simulation // Feel knobs are LIVE-tunable via the TuningConfig singleton (MC-0): OnUpdate reads it each tick and falls // back to TuningConfig.Defaults() when absent (release builds / EditMode), so behaviour is identical to the // old baked consts. DefaultSharpness (the restore target) + SimTickRate stay compile-time (not tuned). - const float DefaultSharpness = 15f; // CharacterComponent.GetDefault() base + const float DefaultSharpness = CharacterComponent.DefaultGroundedSharpness; // CharacterComponent.GetDefault() base const float SimTickRate = 60f; [BurstCompile] diff --git a/Assets/_Project/Scripts/Simulation/Player/PlayerDeathStateSystem.cs b/Assets/_Project/Scripts/Simulation/Player/PlayerDeathStateSystem.cs index 9e4aee360..55e81f72d 100644 --- a/Assets/_Project/Scripts/Simulation/Player/PlayerDeathStateSystem.cs +++ b/Assets/_Project/Scripts/Simulation/Player/PlayerDeathStateSystem.cs @@ -48,7 +48,7 @@ namespace ProjectM.Simulation if (SystemAPI.HasComponent(entity)) { var cc = SystemAPI.GetComponent(entity); - cc.GroundedMovementSharpness = 15f; + cc.GroundedMovementSharpness = CharacterComponent.DefaultGroundedSharpness; SystemAPI.SetComponent(entity, cc); } } diff --git a/Assets/_Project/Scripts/Simulation/Tuning.cs b/Assets/_Project/Scripts/Simulation/Tuning.cs index c72acfb08..2bc3a859f 100644 --- a/Assets/_Project/Scripts/Simulation/Tuning.cs +++ b/Assets/_Project/Scripts/Simulation/Tuning.cs @@ -51,6 +51,11 @@ namespace ProjectM.Simulation /// under interp lag (>= ~250ms reaction + interp buffer; Slice 1 readability). 0/1 = near-instant (legacy). public const int AttackWindupTicks = 22; + /// Charger lunge telegraph windup (ticks). Single source shared by EnemyBaker (the baked client + /// danger-ramp denominator) and TuningConfig.Defaults, mirroring the Grunt AttackWindupTicks pattern so the + /// baked telegraph can't drift from the server windup. + public const int ChargerWindupTicks = 30; + // ---- Production / automation (M7: Harvester/Conveyor/Fabricator) ---- /// Max production cycles a single machine awards in one process (bounds within-session diff --git a/Assets/_Project/Scripts/Simulation/World/RegionComponents.cs b/Assets/_Project/Scripts/Simulation/World/RegionComponents.cs index a8cfeb5b6..26c4d4475 100644 --- a/Assets/_Project/Scripts/Simulation/World/RegionComponents.cs +++ b/Assets/_Project/Scripts/Simulation/World/RegionComponents.cs @@ -42,6 +42,10 @@ namespace ProjectM.Simulation /// transiently-coexisting arenas can never interact in the shared PhysicsWorld. public const float RoomStrideX = 500f; + /// Region-flip boundary X (half the expedition offset): a player/camera past this reads as the + /// +1000 expedition region. Single source for the HUD / onboarding / atmosphere region checks (DR-013). + public const float RegionBoundaryX = ExpeditionOffsetX * 0.5f; + /// /// World-space origin of expedition room sub-slot (0 or 1 — the run FSM /// ping-pongs consecutive rooms between two offsets so the next room spawns at the idle slot while the