Skill v1.0.1
Automated scan100/10015 files
version: "1.0.1" name: godot-genre-horror description: "Expert blueprint for horror games including tension pacing (sawtooth wave: buildup/peak/relief), Director system (macro AI controlling pacing), sensory AI (vision/sound detection), sanity/stress systems (camera shake, audio distortion), lighting atmosphere (volumetric fog, dynamic shadows), and \"dual brain\" AI (cheating director + honest senses). Use for psychological horror, survival horror, or atmospheric games. Trigger keywords: horror_game, tension_pacing, director_system, sensory_perception, sanity_system, volumetric_fog, AI_reaction_time."
Genre: Horror
Expert blueprint for horror games balancing tension, atmosphere, and player agency.
NEVER Do (Expert Anti-Patterns)
Atmosphere & Tension
- NEVER maintain 100% tension at all times; strictly use a Sawtooth Pacing model (buildup → peak/scare → dedicated relief period) to prevent player "numbing" and exhaustion.
- NEVER rely on jump-scares as the primary source of horror; focus on atmosphere, spatial audio cues, and the anticipation of a threat to build genuine dread.
- NEVER make environments pitch black to the point of frustrating navigation; darkness should obscure threats (details), not the floor. Use rim lighting or a limited-battery flashlight.
- NEVER grant the player unlimited resources; survival horror relies on Scarcity. Limited battery, rare ammo, and slow animations are mandatory to force stressful decision-making.
AI & Senses
- NEVER allow AI to detect the player instantly; implement a Suspicion Meter or a 1-3s reaction window before the AI enters full aggression to avoid "unfair cheating" feel.
- NEVER use predictable AI paths; an enemy on a perfect loop is a puzzle, not a predator. Use the Director to periodically "hint" a new destination near the player.
- NEVER use Area3D overlap signals for instant, frame-perfect Line-of-Sight (LoS) checks; use nodeless raycasting via
PhysicsDirectSpaceState3D.intersect_ray()for fixed-physics sync. - NEVER calculate complex AI vision or pathfinding for monsters far outside the camera's frustum; use
VisibleOnScreenNotifier3Dto disable processing logic. - NEVER leave navigation avoidance layers unconfigured on chasing monsters; explicitly assign avoidance masks to prevent visual "stacking" in tight corridors.
Technical & Scarcity
- NEVER use the visual SceneTree (like GridContainer children) as the source of truth for inventory; strictly maintain a typed memory structure like
Dictionary[StringName, Resource]. - NEVER rely on instantiating standard Nodes to store base item stats/definitions; use custom
Resourcescripts to reduce memory overhead and allow direct Inspector editing. - NEVER forget to call
duplicate(true)on an item's Resource when adding to inventory; if items have mutable states (ammo/durability), you will overwrite the global resource otherwise. - NEVER parse massive JSON save files synchronously; strictly offload heavy parsing to the
WorkerThreadPoolto prevent auto-save freezes. - NEVER use standard strings for hot-path IDs (states, item types); strictly use
StringName(&"chasing") for pointer-speed comparisons. - NEVER evaluate exact floating-point equality (sanity == 0.0); strictly use
is_equal_approx()or threshold checks for deterministic triggers. - NEVER write screen-reading shaders expecting Godot 3
SCREEN_TEXTURE; strictly usesampler2Dwithhint_screen_texture. - NEVER instantiate detailed monster meshes or lights without culling; strictly configure
visibility_rangefor automatic HLOD efficiency. - NEVER rely on AnimationPlayer for random flickering; use
Tweenfor programmatic, clean energy manipulation. - NEVER load heavy scare scenes or 4K textures synchronously via
load(); strictly useResourceLoader.load_threaded_request()to prevent frame stalls. - NEVER scale CollisionShape3D non-uniformly; strictly adjust internal shape resource parameters (radius, height) to prevent erratic physics.
- NEVER perform synchronous, heavy file I/O in a Safe Room; strictly use `Thread` and `Mutex` to handle background saving without stalling the main game thread.
- NEVER check for hiding spot types by casting; strictly use `Object` metadata (`set_meta`) for performant, decoupled AI queries.
🛠 Expert Components (scripts/)
Original Expert Patterns
- predator_stalking_ai.gd - Sophisticated "Stalker" AI using dual-brain logic (Director + Senses) and player view-cone avoidance.
- director_pacing.gd - Invisible orchestrator managing the "Sawtooth" tension wave and relief periods.
Modular Components
- monster_los_check.gd - Physics-synced raycasting for high-performance visibility checks.
- flashlight_flicker.gd - Procedural light interference for atmospheric tension.
- inventory_data_storage.gd - Typed data structure for sparse resource management.
- async_scare_loader.gd - Threaded resource loading for hitch-free jump-scares.
- spatial_noise_emitter.gd - Shape-based sound sensing for sensory AI.
- item_state_duplicator.gd - Deep duplication for managing unique weapon/item states.
- fog_claus_intensifier.gd - Volumetric fog manipulation for dread buildup.
- offscreen_logic_suspender.gd - Culling logic for AI processing outside camera view.
- sanity_shader_manager.gd - Instance-uniform driven distortion effects.
- optimized_horror_state_machine.gd - High-speed predator behavior logic.
Core Loop
- Explore: Player navigates a threatening environment.
- Sense: Player hears/sees signs of danger.
- React: Player hides, runs, or fights (disempowered combat).
- Survive: Player reaches safety or solves a puzzle.
- Relief: Brief moment of calm before tension builds again.
Skill Chain
| Phase | Skills | Purpose | |
|---|---|---|---|
| 1. Atmosphere | godot-3d-lighting, godot-audio-systems | Volumetric fog, dynamic shadows, spatial audio | |
| 2. AI | godot-state-machine-advanced, godot-navigation-pathfinding | Hunter AI, sensory perception | |
| 3. Player | characterbody-3d | Leaning, hiding, slow movement | |
| 4. Scarcity | godot-inventory-system | Limited battery, ammo, health | |
| 5. Logic | game-manager | The "Director" system controlling pacing |
Architecture Overview
1. The Director System (Macro AI)
Controls the pacing of the game to prevent constant exhaustion.
# director.gdextends Nodeenum TensionState { BUILDUP, PEAK, RELIEF, QUIET }var current_tension: float = 0.0var player_stress_level: float = 0.0func _process(delta: float) -> void:match current_tension_state:TensionState.BUILDUP:current_tension += 0.5 * deltaif current_tension > 75.0:trigger_event()TensionState.RELIEF:current_tension -= 2.0 * deltafunc trigger_event() -> void:# Hints the Monster AI to check a room NEAR the player, not ON the playermonster_ai.investigate_area(player.global_position + Vector3(randf(), 0, randf()) * 10)
2. Sensory Perception (Micro AI)
The monster's actual senses.
# sensory_component.gdextends Area3Dsignal sound_heard(position: Vector3, volume: float)signal player_spotted(position: Vector3)func check_vision(target: Node3D) -> bool:var space_state = get_world_3d().direct_space_statevar query = PhysicsRayQueryParameters3D.create(global_position, target.global_position)var result = space_state.intersect_ray(query)if result and result.collider == target:return truereturn false
3. Sanity / Stress System
Distorting the world based on fear.
# sanity_manager.gdfunc update_sanity(amount: float) -> void:current_sanity = clamp(current_sanity + amount, 0.0, 100.0)# Effect: Camera Shakecamera_shake_intensity = (100.0 - current_sanity) * 0.01# Effect: Audio Distortionaudio_bus.get_effect(0).drive = (100.0 - current_sanity) * 0.05
Key Mechanics Implementation
Pacing (The Sawtooth Wave)
Horror needs peaks and valleys.
- Safety: Save room.
- Unease: Strange noise, lights flicker.
- Dread: Monster is known to be close.
- Terror: Chase sequence / Combat.
- Relief: Escape to Safety.
The "Dual Brain" AI
- Director (All-knowing): Cheats to keep the alien relevant (teleports it closer if far away, guides it to player's general area).
- Alien (Senses only): Honest AI. Must actually see/hear the player to attack.
3. Hiding-Spot Metadata System
Use decoupled Object metadata so AI can query state without knowing the class.
# hiding_spot.gdfunc _ready():add_to_group("hiding_spots")set_meta("is_occupied", false)# predator_ai.gdfunc search_hiding_spots():for spot in get_tree().get_nodes_in_group("hiding_spots"):if spot.get_meta("is_occupied"):investigate(spot.global_position)
4. Adaptive Audio (Stress Muffling)
Dynamic low-pass filtering via AudioServer.
# audio_stress_manager.gdfunc update_stress(fear_level: float):# Enable LPF effect on Master bus (index 0) if fear is highAudioServer.set_bus_effect_enabled(0, 0, fear_level > 0.5)# Attenuate volume linearlyAudioServer.set_bus_volume_linear(0, 1.0 - (fear_level * 0.4))
5. Safe-Room Multithreaded Save
Use Thread and Mutex to prevent frame drops during checkpoint saves.
# safe_room.gdvar _save_thread: Thread = Thread.new()var _mutex: Mutex = Mutex.new()func trigger_save(data: Dictionary):_mutex.lock()if not _save_thread.is_alive():_save_thread.start(_do_save.bind(data.duplicate(true)))_mutex.unlock()func _do_save(data):var file = FileAccess.open("user://save.dat", FileAccess.WRITE)file.store_var(data)file.close()
Godot-Specific Tips
- Volumetric Fog: Use
WorldEnvironment->VolumetricFogfor instant atmosphere. Animatedensityfor dynamic dread. - Light Occluder 2D: For 2D horror, shadow casting is essential.
- AudioBus: Use
ReverbandLowPassFilteron the Master bus, controlled by scripts, to simulate "muffled" hearing when scared or hiding. - AnimationTree: Use blend spaces to smooth transitions between "Sneak", "Walk", and "Run" animations.
Common Pitfalls
- Constant Tension: Player gets numb. Fix: Enforce "Relief" periods where nothing happens.
- Frustrating AI: AI sees player instantly. Fix: Give AI a "reaction time" or "suspicion meter" before full aggro.
- Too Dark: Player can't see anything. Fix: Darkness should obscure details, not navigation. Use rim lighting or a weak flashlight.
Reference
- Master Skill: godot-master