// © 2025 Naked People Team. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Engine/DataAsset.h" #include "NPCDirectorConfig.generated.h" class ANPC; // One weighted entry in the spawn pool. Author BP_NPC_Walker / BP_NPC_Stalker (each carrying its // own UNPCTypeDefinition + mesh) and weight them so the crowd composition reads mostly-Walkers. USTRUCT(BlueprintType) struct FNPCSpawnEntry { GENERATED_BODY() UPROPERTY(EditDefaultsOnly, Category = "NPC") ENPCType Type = ENPCType::Walker; UPROPERTY(EditDefaultsOnly, Category = "NPC", meta = (ClampMin = "0.0")) float Weight = 1.0f; }; // Tuning for UNPCDirectorSubsystem (the GDD §17.1 NPCManager). Assigned on // UNakedDesireGameInstance::NPCDirector, mirroring CommissionBoard. All distances in cm. UCLASS(BlueprintType) class NAKEDDESIRE_API UNPCDirectorConfig : public UPrimaryDataAsset { GENERATED_BODY() public: // Pool size / hard cap on simultaneous NPC actors. Should be >= the largest target count. UPROPERTY(EditDefaultsOnly, Category = "Population", meta = (ClampMin = "0")) int32 MaxNPCs = 20; // Target live count by day/night phase (§10.1) — day streets are busier than night. UPROPERTY(EditDefaultsOnly, Category = "Population", meta = (ClampMin = "0")) int32 TargetCountDay = 14; UPROPERTY(EditDefaultsOnly, Category = "Population", meta = (ClampMin = "0")) int32 TargetCountNight = 5; // Reconcile cadence (seconds). 0.5 is plenty — the director is not per-frame. UPROPERTY(EditDefaultsOnly, Category = "Population", meta = (ClampMin = "0.05")) float UpdateInterval = 0.5f; // Spawn ring around the player: spawn between Min and Max (Min keeps NPCs from popping in on top // of the player), recycle past DespawnRadius (kept > Max so crossing the ring doesn't churn). UPROPERTY(EditDefaultsOnly, Category = "Ring", meta = (ClampMin = "0.0")) float SpawnRadiusMin = 1500.0f; UPROPERTY(EditDefaultsOnly, Category = "Ring", meta = (ClampMin = "0.0")) float SpawnRadiusMax = 3500.0f; UPROPERTY(EditDefaultsOnly, Category = "Ring", meta = (ClampMin = "0.0")) float DespawnRadius = 4500.0f; // Weighted classes drawn into the pool at prewarm. Empty = director spawns nothing. UPROPERTY(EditDefaultsOnly, Category = "Population") TArray SpawnTable; UPROPERTY(EditDefaultsOnly, Category = "NPC") TArray> NPCClasses; };