$PATHSYSTEM

From HEWIKI
Jump to: navigation, search



Contents


The System Node $PATHSYSTEM implements the MMO Foundation Framework's pathfinding interface to the HeroPath system.

Overview

Whether used by creature AI to navigate the game levels or in cheat detection for player movement the ability to for game systems to query a "navmesh" to figure out if it is possible to get from one point to another is a critical component in todays MMOs. In HeroEngine, the pathfinding solution is comprised of a variety of components collectively known as the HeroPath system. Unique to HeroEngine is the ability to, in near real-time, build a "navmesh" for a game level and perform micro edits as changes are made.

HeroEngine's $PATHSYSTEM system node serves as the HSL interface to the C++ API for querying the Physics Server for pathing information.

What problem(s) does this solve?

What problem(s) does this not solve?

Concepts

HSL Interface C++ Pathfinding API

The $PATHSYSTEM system node serves as the HSL interface to the C++ pathfinding API, wrapping the external functions. While it is possible to call the pathfinding external functions directly, it is recommended you use $PATHSYSTEM's HSL wrappers instead as the system implements a number of useful behaviors (such as "garbage collection" of the path solutions).

Parameter Sets

The C++ API uses a parameter set syntax to control the type of points on the NavMesh that are considered valid when the physics server constructs the results of a path query. A special API is used to construct these parameter sets which are called "Key Value Specs". The $PATHSYSTEM implements a default parameter set for generating paths in the "walkable" area of a navmesh which can be retrieved by calling $PATHSYSTEM._pathSystem_GetWalkableParameterSetHandle().

Related Components

The MMO Foundation Framework for Pathfinding is called the HeroPath system and is comprised of multiple elements.

Usage

Adding game-specific functionality

As a required class/script, it is not permissible to make changes to the _PathSystemClassMethods script. Instead, extension/overriding the script is accomplished by the creation of a game-specific class (and class methods script) that is GLOMmed onto the PATHSYSTEM prototype.

Create a game-specific class

Using the DOM Editor create a new (server|client) class. Our recommendation is that you use a class name that incorporates the _PathSystem as a suffix to the name (ex. HJ_PathSystem), this makes it easier to locate the pair of classes (the required script prefixed in _PathSystem and your game-specific class).

Once you have created the game-specific class, create a new client class methods script for that class.

Adding a game-specific class

Adding your game-specific class to the PATHSYSTEM prototype is achieved using the System Node Configuration GUI or the CLI server command \mpac or client |mpac in the Console Panel. The System Node Configuration GUI is the preferred method because it handles the communication to update any instantiations of a system node to reflect the changes you have made.

Using the System Node Configuration GUI

UtilitiesInterfaceConfigureSystemNodes.jpg

Opening the System Node Configuration GUI requires you to access the hidden Utilities Interface toolbox, located in the top left corner of the render window with ctrl-shift-click (or press F5), which will open the Interface. On the Tools tab within the menu, is an option to open the System Nodes Configuration GUI.

See also: Adapting Clean Engine



Using the CLI

It is important to recognize that modification of the prototype from which a system node is instantiated will not update any instantiations that have already been made in various local GOMs. That means your changes will not take effect until the area (in the case of server system nodes) restarts, or the client (in the case of client system nodes), restarts.

Adding a class to a prototype is done via the CLI command Modify Prototype Add Class(MPAC).

Server: \mpac PATHSYSTEM, hj_PathSystem;
Client: |mpac PATHSYSTEM, hj_PathSystem;



Creating a Path System Response Handler

AbstractPathSystemHandler.gif

The HeroPath system is asynchronous in nature, with responses to path queries being sent to methods on a specified callback node.

The callback node must implement the appropriate methods to receive the response for the type of query made. The HeroPath system includes an abstract class _abstractPathSystemHandler with its corresponding class methods script _abstractPathSystemHandlerClassMethods from which you may inherit and then override its methods as you need.

While it is not required that your callback node inherit from _abstractPathSystemHandler (though we recommend you do so), it is required that you implement the expected HSL callback methods.

Request a Path From Point A to Point B

PathFromPointAtoPointB.png
CautionSign.gif The response to this query passes a reference to an instantiation in the local GOM, care must be taken not to leak memory keeping the node around after it is no longer needed. Read the section on Avoiding Memory Leaks.


Requesting a path from point A to point B is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetPath method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the completed path.

handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()
 
// Request a path from PointA to PointB using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetPath( handler, defaultGroundedHandle, pointA, pointB )


Your callback node (handler) must implement the following methods:

_PathSystem_PathMerge() Callback

This callback is made to the callback node (handler) immediately prior to the _PathSystem_PathComplete() method call. It provides the opportunity to "merge" a character's current position with the resulting path request. A merge is performed taking a specified point (vector3) and finding the closest point in the path's list of points and dropping all points prior to that.

// The C++ HeroPath system raises this event prior to pathComplete on the $PATHSYSTEM system node which fowards the event to
//   the callback node, allowing the handler the opportunity to merge the calculated path with the current position
//   of the entity for whom the path is intended.  Merging the path will drop points that would make the character go backwards
//   from their current position, ensuring they continue to move towards their goal.
method _PathSystem_PathMerge(pathRequestID as ID, position references Vector3, rotation references Vector3, maxDistance references Float) as Boolean
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
// Returns:
//   position - current position of the enty for whom the path was calculated
//   rotation - current rotation of the entity for whom the path was calculated
//   maxDistance - maximum distance allowed between merge point and nearest point on the path, exceeding the
//                 maximum distance results in no merge and path complete will get the full calculated path
  return false
.

_PathSystem_PathComplete() Callback

The _PathSystem_PathComplete() method is called following the _PathSystem_PathMerge() callback when the physics server has returned a list of points that make up the requested path from A to B. Now you do whatever you want with the list of points, such as tell an NPC to move along the path.

// The C++ HeroPath system raises this event upon the completion of a path on the system node $PATHSYSTEM.
//   The system node then fowards the event to the callback node specified at the time the request was made.
//   The event is the result of a request for a path using $PATHSYSTEM's method _PathSystemGetPath()
method _PathSystem_PathComplete(path as NodeRef of Class _PathSystemResponse)
// Parameters:
//   path - class _PathSystemResponse containing the calculated path
.

Avoiding Memory Leaks via _PathSystemResponse Nodes

It is important to note that the method callback provides a reference to a node instantiated in the local GOM. If your handler does not inherit from the _abstractPathSystemHandler, or if you choose to override the "garbage collection" mechanic of the abstract class then you are responsible for keeping a reference to and destroying the node when you are done with it. You might choose to keep a path system response for some period of time if for example the NPC is navigating along it, or the path from pointA to pointB is frequently requested.

If your handler inherits from _abstractPathSystemHandler and you use the $PATHSYSTEM system node wrapper methods to make path queries a callback is made to the handler's _PathSystem_GarbageCollectPathSystemResponse() method following the _PathSystem_PathComplete() method call. By default, the method returns true (i.e. garbage collect the response node) and the path system response node will be destroyed.

// Callback made by the $PATHSYSTEM after it has notified the path system handler of a completed path to determine
//   whether or not the system should clean up the node automatically (IE after callback is complete) or allow
//   the path system response node to remain in memory for subsequent use.
method _PathSystem_GarbageCollectPathSystemResponse( path as NodeRef of Class _PathSystemResponse ) as Boolean
  return true
.

Request a Random Point

RandomPointOnNavMesh.gif

Requesting a random point on the navmesh is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRandomPoint method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRandomPoint( handler, defaultGroundedHandle  )


Your callback node (handler) must implement the following method:

_PathSystem_GotRandomPoint() Callback

The _PathSystem_GotRandomPoint() is called (asynchronously) on the callback node passed to the HeroPath system at the time of the request. As needed, you may use the requestID of the incoming point to match the point with the reason a point was requested.

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotRandomPoint(pathRequestID as ID, point as Vector3)
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the random point selected by the C++
.

Request the Nearest Point

NearestPointOnNavMesh.gif

Requesting a nearest point on the navmesh to a specified point is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetNearestPoint method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the nearest point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetNearestPoint( handler, defaultGroundedHandle, nearPoint )

Your callback node (handler) must implement the following method:

_PathSystem_GotNearestPoint() Callback

The _PathSystem_GotNearestPoint() is called (asynchronously) on the callback node passed to the HeroPath system at the time of the request. As needed, you may use the requestID of the incoming point to match the point with a reason the point was requested.

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotNearestPoint(pathRequestID as ID, point as Vector3)
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the nearest point to the point specified when the request was made.
.

Request Random Point in Pathfinding Node

RandomPointInPathfindingNode.gif

Requesting a random point on the navmesh constrainted to the volume of a pathfinding node is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRandomPointInPathFindingNode method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()  
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRandomPointInPathFindingNode( handler, defaultGroundedHandle, pathfindingNode )

Your callback node (handler) must implement the following method:

_PathSystem_GotRandomPointInPathFindingNode() Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotRandomPointInPathFindingNode( requestID as ID, point as Vector3,found as Boolean)
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the nearest point to the point specified when the request was made.
//   found - boolean indicating whether or not a point was found  
.

Request Random Point in Region Node

RandomPointInRegionNode.gif

Requesting a random point on the navmesh constrainted to the volume of a region node is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRandomPointInRegionNode method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.

handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle() 
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRandomPointInRegionNode( handler, defaultGroundedHandle , regionNode )

Your callback node (handler) must implement the following method:

_PathSystem_GotRandomPointInRegionNode() Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotRandomPointInRegionNode( requestId as ID, point as Vector3,found as Boolean )
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the nearest point to the point specified when the request was made.
//   found - boolean indicating whether or not a point was found  
.

Request Random Point In Sphere

RandomPointInSphericalVolume.gif

Requesting a random point on the navmesh constrainted to the volume of a sphere is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks. Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRandomPointInSphere method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRandomPointInSphere( handler, defaultGroundedHandle , center, radius )

Your callback node (handler) must implement the following method:


_PathSystem_GotRandomPointInSphere Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotRandomPointInSphere( requestId as ID, point as Vector3,found as Boolean )
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the nearest point to the point specified when the request was made.
//   found - boolean indicating whether or not a point was found  
.

Request Random Point In Volume

RandomPointInVolume.gif

Requesting a random point on the navmesh constrainted to a volume is a simple matter of instantiating or reusing a callback node that implements the appropriate method callbacks.

Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRandomPointInVolume method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
defaultGroundedHandle as id = $PathSystem._pathSystem_GetWalkableParameterSetHandle()
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRandomPointInVolume( handler, defaultGroundedHandle, bmin, bmax )

Your callback node (handler) must implement the following method:

_PathSystem_GotRandomPointInVolume Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested point.
method _PathSystem_GotRandomPointInVolume( requestID as ID, point as Vector3,found as Boolean )
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   point - the nearest point to the point specified when the request was made.
//   found - boolean indicating whether or not a point was found
.

Request Region Nodes Containing a Point

RegionNodesContainingPoint.png

Some systems may need to retrieve the Region or Pathfinding nodes whose volumes contain a specified point. This information is also available on the physics server via the external function _PathSystem_GetRegionNodesContainingPoint, which like the other C++ API functions is wrapped by the $PATHSYSTEM system node.

Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetRegionNodesContainingPoint method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.


handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetRegionNodesContainingPoint( handler, point )


Your callback node (handler) must implement the following method:

_PathSystem_GotRegionNodesContainingPoint Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested nodes containing the specified point..
method _PathSystem_GotRegionNodesContainingPoint( requestID as ID, containingNodes as List of NodeRef )
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   containingNodes - list of region nodes that contain the specified point  
.

Request Pathfinding Nodes Containing a Point

PathfindingNodesContainingPoint.gif

Some systems may need to retrieve the Region or Pathfinding nodes whose volumes contain a specified point. This information is also available on the physics server via the external function _PathSystem_GetPathfindingNodesContainingPoint, which like the other C++ API functions is wrapped by the $PATHSYSTEM system node.

Assuming you have created a class "MyPathSystemHandler" that inherits from _abstractPathSystemHandler as detailed above, you will instantiate a handler from your class and pass it to the $PATHSYSTEM's _PathSystemGetPathfindingNodesContainingPoint method.

The HeroPath system returns a <RequestID> which your requesting system can use to map a particular request with some action to take upon receipt of the random point.

handler as NodeRef of Class _abstractPathSystemHandler = CreateNodeFromClass( "MyPathSystemHandler" )
 
// Request a random point using the default parameter set for "walkable" terrain
var requestID = $PathSystem._PathSystemGetPathfindingNodesContainingPoint( handler, point )

Your callback node (handler) must implement the following method:

_PathSystem_GotPathFindingNodesContainingPoint Callback

// The C++ HeroPath system raises this event on the $PATHSYSTEM system node which forwards the event to the callback
//   node, allowing the handler to make use of the requested nodes containing the specified point.
method _PathSystem_GotPathFindingNodesContainingPoint( requestID as ID, containingNodes as List of NodeRef )
// Parameters:
//   pathRequestID - Request ID for this request, used internally by the $PATHSYSTEM to map requests to callback nodes
//   containingNodes - list of pathfinding nodes that contain the specified point
.

Reference

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox