{"schemaVersion":1,"record":{"key":"lesson/npc-perception","type":"lesson","id":"npc-perception","lang":"en","title":"NPC perception and target memory","summary":"Separate world state from character knowledge: visibility, last observation, forgetting and readable reactions.","updatedAt":"2026-10-20","status":"active","url":"https://gamemechanics.pro/en/lessons/npc-perception/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/npc-perception.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/npc-perception.md","aliases":[],"tags":["npc-ai","perception","state-machines"],"sourceIds":["source-52855da41e5f6f4d"],"sources":[{"id":"source-52855da41e5f6f4d","title":"Martin Walsh: Modeling Perception and Awareness in Splinter Cell Blacklist","url":"https://www.gameaipro.com/GameAIPro2/GameAIPro2_Chapter28_Modeling_Perception_and_Awareness_in_Tom_Clancy%27s_Splinter_Cell_Blacklist.pdf","verifiedAt":null}],"sections":[{"id":"prerequisites","title":"Prerequisites","body":"Game code knows every object's coordinates. An NPC does not have to. Here, AI means a character behavior algorithm rather than a language model."},{"id":"principle","title":"The principle","body":"Separate observation from decision. Perception reports “target visible” or “noise heard,” memory retains the last known location, and behavior selects an action. Martin Walsh's Game AI Pro 2 chapter examines perception and awareness as game models where consistent rules and feedback matter.\n\nStart with [States and transitions](/en/lessons/state-machines/). Explicitly define which information each state can access. If an NPC uses hidden player coordinates after losing sight, that should be a deliberate game rule rather than accidental data leakage.\n\n<span id=\"example-an-observation-drone\"></span>"},{"id":"example","title":"Practical example","body":"### An observation drone\n\nIn this original teaching model, a drone detects the player within a 90° sector and 8 m range if a ray to a target sample point is unobstructed. Radius alone is insufficient: a wall blocks observation. A ray to one point is also a simplification and can behave oddly at cover edges.\n\nWhile the target is visible, the drone updates its last known position. After losing sight, it searches that position for two seconds, then resumes its route. It does not update memory through a wall.\n\nIllustrative pseudocode, not code for a particular engine:\n\n```text\nvisible = within_range(target) and within_cone(target) and clear_ray(target)\nif visible:\n    memory.position = target.position\n    memory.expires_at = now + 2.0\n    state = tracking\nelse if now < memory.expires_at:\n    state = searching\n    search_position = memory.position\nelse:\n    state = patrol\n```\n\nBefore the first observation, memory is assumed to be expired. This variant provides short memory without modeling accumulating suspicion. Add suspicion only if the gameplay rule needs it."},{"id":"mistakes","title":"Common mistakes","body":"- Range checks without obstruction checks let the NPC see through walls.\n- Search uses the hidden target's current location, making memory effectively omniscient.\n- States change without a cue, leaving the player unsure whether detection occurred."},{"id":"checks","title":"Verify it","body":"- Display the debug sector, ray, state and memory position.\n- Check a target in front, behind, behind a wall and at the range boundary.\n- Move the player after losing visibility and confirm the memory point stays fixed.\n- With discrete updates, check memory expiry on the first tick after its deadline."},{"id":"agent-task","title":"Prompt for an AI agent","body":"> Implement separate observation, memory and drone state. Prepare four test scenes and log transition reasons. State the ray and update-frequency simplifications. Visually identify searching without relying on color alone.\n\nReview through the [State Machine](/en/lenses/#schell-028) and [Feedback](/en/lenses/#schell-063) lenses."}],"relations":[{"type":"requires","direction":"outgoing","label":"Before you start","key":"lesson/state-machines","title":"States and transitions","url":"https://gamemechanics.pro/en/lessons/state-machines/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/state-machines.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/state-machines.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"lesson/npc-action-selection","title":"How an NPC selects an action","url":"https://gamemechanics.pro/en/lessons/npc-action-selection/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/npc-action-selection.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/npc-action-selection.md"},{"type":"explains","direction":"outgoing","label":"Apply the principle","key":"mechanic/boss-fight-atlas--boss-cover-line-of-sight","title":"Cover and line of sight","url":"https://gamemechanics.pro/en/knowledge/mechanic/boss-fight-atlas--boss-cover-line-of-sight/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/mechanic/boss-fight-atlas--boss-cover-line-of-sight.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/mechanic/boss-fight-atlas--boss-cover-line-of-sight.md"},{"type":"explains","direction":"outgoing","label":"Apply the principle","key":"mechanic/voice-audio--family-22","title":"Stealth, lures and noise control","url":"https://gamemechanics.pro/en/knowledge/mechanic/voice-audio--family-22/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/mechanic/voice-audio--family-22.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/mechanic/voice-audio--family-22.md"},{"type":"practices","direction":"outgoing","label":"Put it into practice","key":"practice/maintenance-patrol","title":"Maintenance patrol","url":"https://gamemechanics.pro/en/knowledge/practice/maintenance-patrol/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/practice/maintenance-patrol.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/practice/maintenance-patrol.md"},{"type":"related","direction":"outgoing","label":"Related materials","key":"lesson/state-machines","title":"States and transitions","url":"https://gamemechanics.pro/en/lessons/state-machines/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/state-machines.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/state-machines.md"},{"type":"reviews","direction":"outgoing","label":"Review through a lens","key":"lens/schell-028","title":"The State Machine","url":"https://gamemechanics.pro/en/knowledge/lens/schell-028/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lens/schell-028.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lens/schell-028.md"},{"type":"reviews","direction":"outgoing","label":"Review through a lens","key":"lens/schell-063","title":"Feedback","url":"https://gamemechanics.pro/en/knowledge/lens/schell-063/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lens/schell-063.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lens/schell-063.md"},{"type":"contains","direction":"incoming","label":"Learning paths","key":"path/npc-behavior","title":"NPC behavior","url":"https://gamemechanics.pro/en/learn/npc-behavior/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/path/npc-behavior.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/path/npc-behavior.md"}],"placements":[],"supersededBy":[],"attributes":{"category":"engineering","level":"intermediate","minutes":6},"endsAt":null,"provenance":"Original gamemechanics.pro material. Check illustrative examples in your own project.","license":"CC-BY-4.0","codeLicense":"MIT","attribution":"gamemechanics.pro contributors"}}