The $NPC System Node, accessed via script, implements support for the fundamental requirements of simply having NPCs show up in HeroEngine, 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 and/or overriding of its behaviors.
What problem(s) does this solve?
- Basic and extensible support for non-player characters that can be used out-of-the-box. Using this system, your developers do not have to immediately implement your game-specific non-player character mechanics.
- As part of the Creatures and NPCs system, supports Plug-n-Play NPC support, which enable your artists to immediately view their work in the game engine.
What problem(s) does this not solve?
- The Creatures and NPCs system does not remove the need for your developers to eventually implement game-specific NPC mechanics for your game, even if it is only by extension of the initially provided mechanics. Consider the provided systems a foundation upon which you would later build your own NPC and creature systems in order to meet your design goals.
$NPC is a System Node
System Nodes are the primary mechanism at the HSL script level enabling game-specific implementations of a licensee to extend/override the required functionality included in Clean Engine. As with all system nodes, this is accomplished by GLOMming a game-specific class onto the NPC prototype, from which a singleton node $NPC is instantiated for a particular local GOM.
Extending or overriding the basic behaviors of the NPC system node require the implementation of a game-specific class, GLOMmed onto the NPC prototype, in which you implement any of the
HE_ methods you might need. Our general recommendation is that you name this override class <game> + _Npc, so for Hero's Journey our game-specific override class is the class
Customizing the System Node
The Creatures and NPCs system has four major (and many minor) intersections, each of which may be changed. These allow you to alter the generic system to implement your own game-specific code, via a game-specific class on the NPC system node. Steps include:
- Game-specific overrides on the NPC system node
- Replacing the class used for the character node
- Compositing behaviors during instantiation
- Replacing the class used for the npc root node
Most of the methods implemented in script
_npcClassMethods make calls to
HE_ prefixed methods that may be implemented in your game-specific class methods script to extend or override the behaviors of the system node.
Adding game-specific functionality
As a required class/script, it is not permissible to make changes to the _npcClassMethods 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 NPC prototype.
- Create a new class
- Create a class method script for the class
- GLOM the class onto the 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 _npc as a suffix to the name (ex. HJ_npc), this makes it easier to locate the pair of classes (the required script prefixed in _npc 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 NPC 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
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.
\mpac NPC, hj_npc;
|mpac NPC, hj_npc;
Modify the Classes Used to Instantiate/Composite NPCs
|For Hero's Journey, our creatures are extremely complex so we decided to use the Spec System to handle the complex compositing we need to instantiate a functional creature. You may wish to use the spec system to create your own creature spec oracle and create your creatures from the spec rather than creating them using the basic support implemented in Creatures and NPCs system.|
Non-player characters created by the Creatures and NPCs system all have a character created from the class
_nonPlayerCharacter and a visible character created from the class
_characterAppearance. Once you create a game-specific override class and add it to the system node, you can easily change the classes used to instantiate npcs by implementing the methods detailed in this section.
For your game's implementation of npcs you may wish to instantiate the nodes from your own classes so that you can override and extend the functionality of those fundamental classes, optionally you might choose rather to composite (via glomming) behaviors following instantiation.
Whether you should replace the class from which the nodes are instantiated or using compositing is dependant upon your needs. If you need to override the behaviors found in
_nonPlayerCharacter then you wish to override the class from which the node is instantiated. If you merely want to add additional behaviors that are indepentant of the base functionality, then composition is likely more appropriate.
Please note, once the node is instantiated you may NOT change its base class, i.e. the class from which it was instantiated. Composited Classes, however, you may dynamically add and remove as needed.
Replacing the _nonPlayerCharacter class
|Your replacement class must inherit from
HeroEngine has the following requirements for NPCs and creatures to function properly:
- Your NPC character node class must ultimately inherit from
- Your class must be of the Archetype of CREATURE
You can override what class is used to create a creature by the NPC system this way:
method HE_NPCClassUsedForInstantiation( useClass references String ) as Boolean // Used by SYSTEM.NODE.NPC // // Allows a game-specific class to override the class used to instantiate npcs in the required system // please note the class must be a child of the required HeroEngine class _nonPlayerCharacter and it must be of the // CREATURE archetype. // // Return true to indicate you have set the class you wish to be used useClass = "HJNpc_class" return true .
Replacing the _characterAppearance class
|The class must inherit from _characterAppearance class and MUST be of archetype CHARACTER.|
HeroEngine has some requirements for an NPC's visible character node:
- The visible character node's class must ultimately inherit from the class
- The visibile character node's class must be of the archetype of CHARACTER.
You can override what class is used for the visible character node this way:
method HE_NPCVisibileClassUsedForInstantiation( useClass references String ) as Boolean // Used by SYSTEM.NODE.NPC // // Allows a game-specific class to override the class used to instantiate the visible character for an npc // in the required system // please note the class must be a child of the required HeroEngine class _characterAppearance and it MUST be // of the CHARACTER archetype // // Return true to indicate you have set the class you wish to be used useClass = "HJNPCVisible_Character" return true .
Compositing Behaviors on Instantiation
|The callback is one performed by the Creatures and NPCs system. If you instantiate a creature using a custom system, the callback will not happen unless your custom system adds code to perform the callback.|
Each of the classes on the NPC system node receives a callback at the shared function
_OnCharacterInstantiation, which receives the newly instantiated NPC node as well as the Character Type used in its creation. During this callback in your game-specific system node class, you could GLOM on additional classes based on the Character Type.
While this is a perfectly acceptable way to create NPCs, for Hero's Journey we opted to employ the Spec System to create creature specs and handle all of the composition required by the spec decorators for a particular creature. This is because we wanted to expose a high level of creature customization in GUIs for our GameMasters, and the Spec System provides a solid foundation for this.
shared function _OnCharacterInstantiation( npc as NodeRef of Class _nonPlayerCharacter, type as String ) // Called in all of the class method scripts of the $NPC system node // provides the opportunity to composite additional behaviors via GLOMming based on "type" // additionalBehaviors as list of string when tolower( type ) is "orc" add back "orcMovementBehaviors" to additionalBehaviors add back "orcCombatBehaviors" to additionalBehaviors . etc . foreach b in additionalBehaviors GlomClass( b, npc ) . .
Instantiating a Non-Player Character
Assuming you know the character type from which you wish to create the npc, simply call to the method
_CreateSimpleHECharacter and specify the character type from which you wish the npc to be instantiated and whether or not it should be a persisted node or not.
Lists of valid character types and specifications may be displayed using the
The Creatures and NPCs system automatically creates (regardless of what you specify) the npc as non-persisted in a non-edit instance since you can not persist nodes in non-edit instances.
var npc = $NPC._CreateSimpleHECharacter( "orc", false )