Introduction

Some Definitions (for this talk)

dynamic

modified or generated at runtime

navmesh

set of polygons representing navigatable surface

geometry

the world the player can see

NPC

non-player-character (alias: agent, bot, character)

AI

all npcs, includes those without visual representation

Problem Description

what comes with it?

  • dynamic geometry means dynamic graphs

  • a change to the geometry need to be applied to the graph or the graph has to be partially re-generated

  • changing the graph potentially requires recalculation of all paths relying on it

viewpoint of "the industry"

  • big paying target group is more important than a good game

  • fun for the target player group is good

  • multiplayer is more fun than "bad" AI

  • multiplayer is cheaper than "good" AI

  • lots of time pressure for the release

Static Navmesh Approach

How do they work

  • the world is covered in connected convex polygons

  • each point inside a polygon is walkable space

  • the center points of the polygon edges are the nodes in the graph used by A*

  • each node is connected to all other nodes of both polygons

Example of how it doesn't work right

Dynamic Navmesh Updating

Dynamically Updating a Navigation Mesh via Efficient Polygon Subdivision

  • cells contain polygons representing static geometry (1:n)

  • cells keep track of overlapping dynamic geometry (m:n)

  • on moving geometry the cells it is overlapping are updated

    • reset cell to base state

    • project objects convex hull onto navmesh plane

    • clip object hull aginst cell hull to get part inside the hull

    • clip object hull inside the cell hull with the non-hull edges of the polygons within the cell

    • update the mesh

  • graph used by A* is updated for the cell

limitations

  • cannot introduce new walkable terrain

  • needs all polygon within a cell to be within one plane

  • no multi-floor geometry

Dynamic Navmesh Generation

Existing pre-render techniques

Movement-Based Expansion

  • start with the agent at a seed position

  • move the agent systematically through the world using all of his movement capabilies

  • let the game engine handle interaction with the geometry

  • graph edge costs are calculated base on the result returned by the game engine

  • supports almost any ability that can affect movement

  • complexity greatly increases with amount of capabilies

  • seed positions affect the quality

3D Rasterization (Voxellzation)

Points Of Visibility

  • no collision checks

  • connect verticies of the collision model with direct line of sight to each other

Real-Time Graph Generation from Raw 3D meshes

  • world is segmented so only parts changing are recalculated

  • walkable surfaces are determined using orthogonal projection on the collision model

  • movement-based expansion is used to stich walkable surfaces together

  • a self-building dictionary keeps track of movement-based expansion results to skip them for future calculations

Render-Generate

  1. get all non-small (one or more bounding box axis above a threshold) collision objects for rendering

  2. render a height map from above

  3. determine the highest "floor"

  4. render its "ceiling"

  5. set the maximum render height to just below the height of the "floor"

  6. repeat 2. to 5. until the bottom of the scene is reached

  7. additionally get the previously ignores small objects for further rendering

  8. for each "roof"-"floor" combination

    • render everything between "roof" and "floor" including the "floor" to get an obstacle heigt map

Graph Creation

  • Finding Graph Nodes

    • ignore pixels with a "roof"-"obstacle" difference smaller than the character size

    • extrude "floor" and "obstacle" height by half the characters size

    • generate nodes for pixels where the character size can fit between extruded "roof" and "obstacle" height for all pixels in his bounding shape

    • put the remaining places to a movement test to determine validity for a node

    • with multiple character sizes start with the highest and widest bounding shapes to save time

  • Connectivity and Cost Filling

    • adjacent nodes get connected according to the set of rules from the self-building dictionary

    • the rule with the lowest cost is used for creating the edge between the nodes

    • also connects "floors" connectable by existing rules

Filling Gaps

  • all positions undecidable by the prevoius methods are used as seed positions for movement-based expansion

Self-Building Dictionary

  • perfrom movement-based expasion for every agent type at design time

  • update at runtime whenever movement-based expasion is used to fill gaps

Additional Thoughts

  • path creation

  • lazy generation

  • graph separation

  • traps