Creatures and NPCs
How do I add a creature to HeroEngine?
Quick and dirty instructions for adding a creature to the engine are located here. If you need the more technical overview, continue reading this page.
Creatures and NPCs and Mobs, Oh My
Creatures and NPCs is a HeroEngine Required System which provides the fundamental HSL building blocks for the introduction of non-player characters (NPCs) to your game. Each subsystem of Creatures and NPCs is extendable and overridable such that you may use the systems or not, as the needs of your game dictate; however, it is nearly certain that your game will eventually extend the pre-existing functionality.
What problem(s) does this solve?
- Plug-n-play NPCs for your game, without requiring extensive upfront development
- Provides a framework which may be extended, overridden or flat out replaced as you codify your game's needs
What problems(s) does this not solve?
- The Creatures and NPCs System does not eliminate the need for your developers to eventually flesh out a full system for how characters are "spawned", how they behave (AI), combat systems, navigation and more. It does, however, let artists check out their work in-engine without further work from the game system developers.
There are several fundamental structural requirements for classes and node hierarchy that must be used, unless you have opted to rewrite large sections of the Clean HeroEngine HSL code and modify components of HeroEngine itself (something we strongly advise against). Assuming you are using the system as supplied, the structural requirements are already handled for you, requiring no extra effort on your part.
- The NPC character node ultimately derives from
- The Character Appearance node (describes how the character node appears) ultimately derives from
- The node to which NPCs are anchored ultimately derives from
- (option from HeroEngine's perspective)
The character node for a non-player character must ultimately derive from the HeroEngine class
_nonPlayerCharacter and is of the archetype CREATURE. Attached to the character node, HeroEngine expects a character appearance node to be associated via the
base_hard_association, with the character node as the source, and the appearance node as the target. If the Creatures and NPCs system is used, an additional soft association
_npcRootToNpcAssoc is also expected between the
_npcAnchor node and the NPC.
The character appearance node is attached to the character node(source) as the target of a
base_hard_association and the class of the character appearance node must ultimately derive from the HeroEngine class
_characterAppearance and is of the archetype CHARACTER.
Each NPC is ultimately associated to some root node so that they are not orphaned in the database. If a node is orphaned, HSL is unable to reference it. For persisted NPCs, the root node is then anchored to the area root node with a
base_hard_association. The Creatures and NPCs system uses an anchor node of the HeroEngine class
_npcAnchor, which is associated to the AreaRoot. When using the Creatures and NPCs system, or the /HENPC command, these associations are created automatically by HeroEngine. However, if you create your own system, different association types may be used. Ultimately though, all NPCs will need to be associated to something, both in order to be referenced later, and to be properly connected to the area so the NPC can be saved to the database, and read from the database on area spinup.
Components of the System
/HENPCchat command, which provides command line access to the components (details)
- $NPC System Node, which provides an access point to many of the components as well as handles the required functionality required by the engine for NPCs to exist. (details)
HE_NpcDataprototype, which is a dynamically created prototype for the storage of game-specific data populated by the components of Creatures and NPCs (details)
- Character Driver, which supports the server commanding a character to move (details)
/HENPC chat command (an abbreviation of HeroEngine Non-Player Character), provides command line access to the components of the Creatures and NPCs system. This is an HSL command so it must be entered in HeroBlade's Chat Panel, not the Console Panel.
See also: /HENPC
NPC System Node
The $NPC System Node implements support for the fundamental requirements of simply having NPCs show up in the engine, and provides utilities for working with their nodes. As with all system nodes implemented for Clean Engine, $NPC follows the system node pattern for extension/overriding of its behaviors.
See also: $NPC
The HE_NpcData prototype is dynamically created from a required class during world spinup. This produces a prototype whose existence is required, but is capable of storing editable game specific information. The prototype is used to store information edited using the /HENPC command related to character specifications and other specification related data. It is unlikely you will need to work with the prototype directly because the $NPC system node exposes an interface to using this prototype.
The Character Driver system is the base implementation of telling characters (NPCs for now, and in the future players when their movement must be taken over by the server) to move from one point to another. The driver’s main purpose is simulating the speed of movement for a character on the server, given that character’s walk and run speeds.
This system does not do path finding; it does not tell a character how to get from one point to another. It is expected that NPCs use a separate path finding system to determine the best course from point A to point B (which will consist of many shorter paths), and then for each set of points it traverses, it uses the driver to move. In other words, the driver only moves in straight lines from where the character currently is to its destination.
The driver tells all clients that know about the character where it is traveling to and what the time of arrival should be. The client then animates the character to achieve the destination in the given time. If the client finds itself with extra time, it will make the character walk slower; conversely it will make it run faster if it is short on time. If the character can’t get to the spot in a reasonable time, it will simply “pop” and appear in the correct location.
The first, most important, thing is that each character specification must have its animation data on the server for correct rates of movement to be calculated. This is extremely simple: control a character (via /HENPC POSSESS, for example) and run a very short distance. Running will cause the movement animations to be loaded on your client. Then, use /HENPC SPEEDUPDATE, which will ask you to confirm your action. Once confirmed, the client will send animation data needed to the server. This needs to be done whenever the walk or run animations for the character change so that the server has the correct data.
Actually using the driver in script is simple. There are five main methods to understand.
method _DriverSetDestination(char as NodeRef, style as Enum MovementStyle, pos as Vector3)
The char is obviously the NPC you wish to move, style is either WALK or RUN, and pos is the destination the NPC must reach. The character will begin to move towards the position at the specified speed.
method _DriverSetDestinationMoving(char as NodeRef, style as Enum MovementStyle, pos as Vector3, isMoving copies Boolean, stopAtEnd as Boolean)
This method should be used if you know that the character is already moving (which will change acceleration calculations, for example). Setting stopAtEnd will allow for deceleration time.
method _DriverSetDestinationAndOrientation(char as NodeRef, style as Enum MovementStyle, pos as Vector3, orientation as Vector3)
This is just like _DriverSetDestination, except you also specify an orientation for the character, which will be used once the destination is reached.
method _DriverSetDestinationAndOrientationMoving(char as NodeRef, style as Enum MovementStyle, pos as Vector3, orientation as Vector3, isMoving copies Boolean)
This is just like _DriverSetDestinationMoving with the added orientation after reaching the destination (like _DriverSetDestinationAndOrientation).
method _DriverComeToStop(char as NodeRef)
The character will stop where it is on the server, though this may cause it to appear to continue on or backtrack for some clients, depending on how far along the character was in the movement simulation before being told to stop.
Whenever a character reaches its destination, a “_driverreacheddestination” is sent out via the EVENTS system node.
|This page may require an update due to changes in HeroEngine 2008 Volume 2 (v1.21).|
All of the methods listed in the Usage section can be overridden. This means you can do all of the simulation calculations yourself, which may need to be done if you alter client code to handle movement differently or you need to support different types of movement calculations based on the character type.
There are a few additional methods that can be overridden.
This is called whenever the driver is told to drive a character. It ensures the timer it uses to constantly simulate movement positions is on and has the appropriate script attached. You can alter the fire rate and other properties of the timer here if necessary.
method _simulateCharMovement(char as NodeRef, info as Class _CharDriverInfo, notify as Boolean)
Here is the actual method used to update driver data for the character being driven. It is unlikely you’d need to override this, since it’s fairly straightforward and based on the calculated start and end times for the movement. This also updates the character’s associated _CharacterAppearance position and rotation fields. If the character reaches its destination and notify is true, it sends out the “_driverreacheddestination” event to any listeners.
method _DriverCommandClient(char as NodeRef, info as Class _CharDriverInfo)
This is the method most likely to change in the near future as we expand and improve on our movement handling. It uses the external function SendNPCMovement to tell all clients that care the appropriate movement data about the character.
Tutorial: Adding a creature to the Engine (for artists)
See also: Adding a creature to the engine