<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=NPC_and_monster_navigation_collision</id>
	<title>NPC and monster navigation collision - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=NPC_and_monster_navigation_collision"/>
	<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=NPC_and_monster_navigation_collision&amp;action=history"/>
	<updated>2026-09-19T06:37:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://g1r-mp.com/wiki/index.php?title=NPC_and_monster_navigation_collision&amp;diff=761&amp;oldid=prev</id>
		<title>QCherry: Document G1R:MP 0.1.2 navigation collision</title>
		<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=NPC_and_monster_navigation_collision&amp;diff=761&amp;oldid=prev"/>
		<updated>2026-09-04T13:52:45Z</updated>

		<summary type="html">&lt;p&gt;Document G1R:MP 0.1.2 navigation collision&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{DISPLAYTITLE:NPC and monster navigation collision}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff5f5; border:1px solid #d13b3b; border-left:5px solid #d13b3b; color:#111111; padding:0.85rem 1rem; margin:0.75rem 0 1rem;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:#111111; font-weight:bold; letter-spacing:0.04em;&amp;quot;&amp;gt;AVAILABLE FROM UPDATE 0.1.2&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:#111111; margin-top:0.25rem;&amp;quot;&amp;gt;This navigation-collision system and the APIs described below are available in G1R:MP 0.1.2 and later.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NPCs and monsters share one authoritative server navigation-collision service. It combines two selectable static layers with mandatory dynamic character separation:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;builtin&amp;lt;/code&amp;gt;: verified MainMap blockers baked into the server package;&lt;br /&gt;
* &amp;lt;code&amp;gt;custom&amp;lt;/code&amp;gt;: bounded blockers created by server-side Lua resources;&lt;br /&gt;
* dynamic capsules: connected players, NPCs and monsters; always enabled.&lt;br /&gt;
&lt;br /&gt;
The baked MainMap layer is a conservative 2.5D no-go representation. It is not a Recast navmesh or terrain heightfield. It includes verified navigation-exclusion volumes and exact supported collision primitives for relevant world objects such as tree trunks; it does not infer blockers from broad mesh bounds or tree crowns.&lt;br /&gt;
&lt;br /&gt;
== Collision-source modes ==&lt;br /&gt;
&lt;br /&gt;
Every NPC and monster uses &amp;lt;code&amp;gt;combined&amp;lt;/code&amp;gt; by default:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Mode !! Static collision sources&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;combined&amp;lt;/code&amp;gt; || Baked MainMap blockers and enabled custom blockers&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;builtin&amp;lt;/code&amp;gt; || Baked MainMap blockers only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;custom&amp;lt;/code&amp;gt; || Enabled custom blockers only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Mode values are case-sensitive. Select the mode at spawn time when the initial position must be validated against a specific layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot; line&amp;gt;&lt;br /&gt;
local monsterId = spawnMonster(&amp;quot;scavenger&amp;quot;, 20, 5, 2, 0, {&lt;br /&gt;
    navigationCollisionMode = &amp;quot;custom&amp;quot;,&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
local npcId = spawnNpc(&amp;quot;Gate Guard&amp;quot;, &amp;quot;guard_01&amp;quot;, 24, 5, 2, 180, {&lt;br /&gt;
    navigationCollisionMode = &amp;quot;combined&amp;quot;,&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The mode can be changed later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot; line&amp;gt;&lt;br /&gt;
setMonsterNavigationCollisionMode(monsterId, &amp;quot;builtin&amp;quot;)&lt;br /&gt;
setNpcNavigationCollisionMode(npcId, &amp;quot;custom&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current value is exposed as &amp;lt;code&amp;gt;getMonsterData(monsterId).navigationCollisionMode&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;getNpcData(npcId).navigationCollisionMode&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;navigationCollisionMode&amp;lt;/code&amp;gt; is independent from &amp;lt;code&amp;gt;navigationMode&amp;lt;/code&amp;gt;. Collision mode selects the static geometry that must be respected. Navigation mode selects built-in AI decisions or direct scripted movement goals. Player, NPC and monster capsule separation remains active in every combination, and clients never become authoritative.&lt;br /&gt;
&lt;br /&gt;
Changing a collision mode invalidates the entity&amp;#039;s cached path. Material custom-blocker changes selectively revalidate affected cached paths; spatially unrelated paths are not globally rebuilt.&lt;br /&gt;
&lt;br /&gt;
== Resource-owned blocker API ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
createAiNavigationBlocker(definition)              -- string ID or false&lt;br /&gt;
updateAiNavigationBlocker(blockerId, definition)   -- bool&lt;br /&gt;
setAiNavigationBlockerEnabled(blockerId, enabled)  -- bool&lt;br /&gt;
destroyAiNavigationBlocker(blockerId)              -- bool&lt;br /&gt;
getAiNavigationBlockerData(blockerId)              -- table or false&lt;br /&gt;
getAiNavigationBlockers()                          -- table&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Blocker IDs are opaque decimal strings and must not be converted to Lua 5.1 numbers. A resource can inspect or mutate only blockers it created. Enabled geometry participates in the shared custom layer seen by all AI entities that use &amp;lt;code&amp;gt;custom&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;combined&amp;lt;/code&amp;gt;. Stopping or restarting a resource removes all blockers owned by that resource.&lt;br /&gt;
&lt;br /&gt;
All coordinates and dimensions use metres. Supported definitions are boxes, cylinders and simple convex polygons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot; line&amp;gt;&lt;br /&gt;
local gate = createAiNavigationBlocker({&lt;br /&gt;
    shape = &amp;quot;box&amp;quot;,&lt;br /&gt;
    x = 125.0, y = -48.0, z = 2.0,&lt;br /&gt;
    width = 2.5, depth = 0.8, height = 4.0,&lt;br /&gt;
    yaw = 30,&lt;br /&gt;
    enabled = true,&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
local pillar = createAiNavigationBlocker({&lt;br /&gt;
    shape = &amp;quot;cylinder&amp;quot;,&lt;br /&gt;
    x = 130.0, y = -45.0, z = 2.0,&lt;br /&gt;
    radius = 1.5, height = 4.0,&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
local restrictedArea = createAiNavigationBlocker({&lt;br /&gt;
    shape = &amp;quot;polygon&amp;quot;,&lt;br /&gt;
    points = {&lt;br /&gt;
        { x = 10.0, y = 10.0 },&lt;br /&gt;
        { x = 14.0, y = 10.0 },&lt;br /&gt;
        { x = 14.0, y = 13.0 },&lt;br /&gt;
        { x = 10.0, y = 13.0 },&lt;br /&gt;
    },&lt;br /&gt;
    minZ = -1.0,&lt;br /&gt;
    maxZ = 5.0,&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shape names are case-sensitive. Dimensions must be finite and between 0.01 and 10,000 metres. Polygon definitions accept 3-16 finite vertices and must be simple and convex. World coordinates are bounded to +/-100,000 metres.&lt;br /&gt;
&lt;br /&gt;
Getters return canonical polygon data even when the input shape was a box or cylinder. &amp;lt;code&amp;gt;getAiNavigationBlockers()&amp;lt;/code&amp;gt; is sorted deterministically by ID and includes disabled blockers. Omitting &amp;lt;code&amp;gt;enabled&amp;lt;/code&amp;gt; from an update preserves the current state.&lt;br /&gt;
&lt;br /&gt;
== Runtime limits and intended use ==&lt;br /&gt;
&lt;br /&gt;
The default hard limits are:&lt;br /&gt;
&lt;br /&gt;
* 1,024 blockers per resource;&lt;br /&gt;
* 4,096 custom blockers across the server;&lt;br /&gt;
* 4,096 broad-phase cells per blocker;&lt;br /&gt;
* 1,000,000 combined custom spatial-index entries.&lt;br /&gt;
&lt;br /&gt;
Invalid or over-limit creates and updates return &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; without partially changing geometry.&lt;br /&gt;
&lt;br /&gt;
Custom blockers affect AI navigation only. They do not create visible meshes, Unreal physics objects, player collision, or client-side world geometry. They are intended for static geometry and occasional changes such as opening or closing a gate. Do not move or toggle them every server tick; use the mandatory dynamic capsule layer for moving players, NPCs and monsters.&lt;br /&gt;
&lt;br /&gt;
== Related functions ==&lt;br /&gt;
&lt;br /&gt;
* [[spawnMonster]], [[getMonsterData]], [[setMonsterNavigationMode]], [[setMonsterNavigationCollisionMode]], [[setMonsterMoveGoal]], [[walkMonsterTo]], [[testMonsterMove]]&lt;br /&gt;
* [[spawnNpc]], [[getNpcData]], [[setNpcNavigationMode]], [[setNpcNavigationCollisionMode]], [[setNpcMoveGoal]], [[setNpcRoute]], [[testNpcMove]]&lt;br /&gt;
* [[createAiNavigationBlocker]], [[updateAiNavigationBlocker]], [[setAiNavigationBlockerEnabled]], [[destroyAiNavigationBlocker]], [[getAiNavigationBlockerData]], [[getAiNavigationBlockers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua API]]&lt;br /&gt;
[[Category:Navigation Functions]]&lt;/div&gt;</summary>
		<author><name>QCherry</name></author>
	</entry>
</feed>