Prop System
(→Manipulating the Prop) |
(→For Developers) |
||
Line 53: | Line 53: | ||
===For Developers=== | ===For Developers=== | ||
− | Props are - at base - dynamic server objects which respond to spatial awareness events by performing some action; usually, this is simply introduction or removal from a player's awareness (e.g. you've moved within range of a resource node or dynamic object which you should now be able to see). Props can also be used, though, to drive custom game logic which uses spatial awareness (e.g. king-of-the-hill or capture-the-flag logic for a dynamic object). There are several moving parts that are required to work together in order to facilitate this behavior, and - as such - changing the logic for a type of prop (or defining your own) often requires touching multiple classes and multiple scripts. | + | Props are - at base - dynamic server objects which respond to spatial awareness events by performing some action; usually, this is simply introduction or removal from a player's awareness (e.g. you've moved within range of a resource node or dynamic object which you should now be able to see). Props can also be used, though, to drive custom game logic which uses spatial awareness (e.g. king-of-the-hill or capture-the-flag logic for a dynamic object; or determining proximity to objects to determine whether interactions are valid). There are several moving parts that are required to work together in order to facilitate this behavior, and - as such - changing the logic for a type of prop (or defining your own) often requires touching multiple classes and multiple scripts. |
The pieces involved in creating a new prop from scratch (all of which have both server and client components): | The pieces involved in creating a new prop from scratch (all of which have both server and client components): | ||
Line 66: | Line 66: | ||
The process for instantiating a prop in script is as follows: | The process for instantiating a prop in script is as follows: | ||
<hsl> | <hsl> | ||
− | specKey as ID = 1 //use any valid specKey | + | specKey as ID = 1 //use any valid specKey for a spec within the _PropSpecOracle |
− | propSpecOracle as NodeRef of Class _PropSpecOracle = $_PROPS._getPropSpecOracle() | + | propSpecOracle as NodeRef of Class _PropSpecOracle = $_PROPS._getPropSpecOracle() //get our prop spec oracle |
− | propSpec as NodeRef of Class _PropSpec = propSpecOracle.GetSpecByKey(specKey) | + | propSpec as NodeRef of Class _PropSpec = propSpecOracle.GetSpecByKey(specKey) //get the spec we're interested in creating a prop from |
− | prop as NodeRef of Class _Prop = propSpec.CreateFromSpec() | + | prop as NodeRef of Class _Prop = propSpec.CreateFromSpec() //create our prop |
</hsl> | </hsl> | ||
− | After the call to 'CreateFromSpec', the following will be true: | + | After the call to 'propSpec.CreateFromSpec()', the following will be true: |
* The prop object will have been created from the spec and default values will have been populated | * The prop object will have been created from the spec and default values will have been populated | ||
* The prop object will have notified all decorators of its creation, allowing those decorators to perform their own synchronous initialization | * The prop object will have notified all decorators of its creation, allowing those decorators to perform their own synchronous initialization | ||
Line 88: | Line 88: | ||
At this point, the prop will have been removed from the area and any spatial awareness tracking or replication will have ceased for it. | At this point, the prop will have been removed from the area and any spatial awareness tracking or replication will have ceased for it. | ||
+ | |||
+ | ====Querying For Props==== | ||
+ | To query for props (perhaps because they were created during a previous session or because you don't store references to them elsewhere), simply make a call to one of the following methods on the $PROPS system node: | ||
+ | <hsl> | ||
+ | method _FindPropsBySpec(propSpec as NodeRef of Class _PropSpec) as List of NodeRef of Class _Prop | ||
+ | method _GetAllProps() as List of NodeRef of Class _Prop | ||
+ | method _GetAllProxyProps() as List of NodeRef of Class _Prop | ||
+ | </hsl> | ||
====Understanding Client/Server Props==== | ====Understanding Client/Server Props==== |
Revision as of 22:51, 6 February 2012
This page documents an upcoming feature and is not currently deployed to any customer world.
Overview
The Prop System, a part of the Foundation Framework, provides a set of tools which may be used to manage interactive and non-interactive objects. These objects may be introduced to players for the purposes of visualization and interaction, and this introduction may be restricted such that only players who meet certain criteria will be included (e.g. only players with the 'collect acorns' quest will be allowed to see and interact with acorn objects). From the perspective of the world-builder, these objects - once added to a scene - are seamlessly integrated with an area's geometry and may be manipulated with the standard HeroBlade translation tools. Unlike standard area geometry, however, these prop objects may have additional functionality attached to them to restrict visibility, provide interactivity, or to provide any other game-specific behavior required.
The Prop System utilizes the Spec System to store prop type definitions. These definitions are used during construction of prop objects to define their behavior, and each can be overridden, extended or decorated in order to provide game-specific functionality for props. Overriding default functionality and providing restrictions or augmentations to visibility, interactivity, etc, is accomplished either by extending a spec via inheritance or by glomming decorator classes onto the prop spec which offer the desired functionality. An example of a decorator that might extend the default prop functionality is the 'MouseInteractionDecorator' which responds to mouse input events. Additional game-specific decorators may be created, and the base prop spec may be overridden or extended as desired.
By default, the MMO Foundation Framework offers the following functionality for props:
- Visualization
- Mouse interaction
- Activation (not yet implemented)
- Spatial perception
- (more) (pending further FF work)
What problem(s) does this solve?
- Selectively introduce and visualize objects for players based on an arbitrary set of criteria
- Provide interactions between props and other objects (not necessarily restricted to just players)
- Provide a framework for extending the default prop behavior with game-specific code
- Provide an intuitive interface for editing prop objects (namely, the HeroBlade translation tools and prop context menus)
What problem(s) does this not solve?
- Implementing visualization- and selection- restriction logic (e.g. due to quest possession, faction standing, etc)
- Implementing the game logic to respond to interactions between props and players (or other entities)
- Providing an all-encompassing set of non-standard behavior that may be specific to your game's systems
Usage
For World Builders
From the perspective of the world-builder, the prop system is fairly seamlessly integrated into the tools they are already familiar with using. Prop type definitions are established in the prop spec editor, individual prop objects are instantiated by adding them to the asset library, and these objects are manipulated in the world using the standard HeroBlade translation tools and prop context menus.
The process of setting up a prop to be instantiated in the world and manipulating it involves the following steps:
- Choose a pre-existing prop spec from which you want to instantiate props
- Create an entry in the Asset Library which will be used to add a prop to an area
- Add a prop to an area using the Asset Library entry
- Manipulate the prop using the HeroBlade translation tools as well as the right-click context menu
Choosing a Prop Spec
image All prop objects are instantiated from prop specs, each of which may extend or override the base behavior. These specs can also be decorated with prop spec decorators to provide additional functionality on a per-spec basis. (example: A sign that can be clicked on in order to be read may be instantiated from one spec; while a an ancient relic that must be discovered, approached and then clicked on to collect may be instantiated from a different one)
In order to determine which spec you want to use for your prop (or to edit an existing spec), you'll first want to open the Prop Spec Selector from the Utilities Interface's "Tools" menu. There, you'll see a list of all prop specs currently defined. Many, such as the "Visible Prop" and "Interactive Prop" specs, are pre-defined and offered as part of the base MMOFF implementation. Others, which your team may implement, will also be listed here.
To use a pre-existing prop spec, simply note the ID of the spec and write it down for use in later steps. To add, edit, or decorate a spec, click either the 'Add', 'Edit' or 'Glom' buttons, respectively.
Adding the Library Command
image Once you know the spec from which you want to instantiate your prop, create a Library entry with an /heprops command similar to the one below:
/heprops library #spec='1' #fqn='\engine\cleangame\resources\common\utility_box_white01.gr2' #position='$POSITION' #lod='10'
Instantiating and Manipulating Props
image Once the prop has been added to the library, props may be instantiated by selecting the prop in the library and clicking 'Add'. The prop - once instantiated in the world - may be treated like any other asset and repositioned, rotated, scaled or interacted with via the HeroBlade translation tool widgets.
For Developers
Props are - at base - dynamic server objects which respond to spatial awareness events by performing some action; usually, this is simply introduction or removal from a player's awareness (e.g. you've moved within range of a resource node or dynamic object which you should now be able to see). Props can also be used, though, to drive custom game logic which uses spatial awareness (e.g. king-of-the-hill or capture-the-flag logic for a dynamic object; or determining proximity to objects to determine whether interactions are valid). There are several moving parts that are required to work together in order to facilitate this behavior, and - as such - changing the logic for a type of prop (or defining your own) often requires touching multiple classes and multiple scripts.
The pieces involved in creating a new prop from scratch (all of which have both server and client components):
- The Prop Spec
- The Prop Spec-derived Object
- The Prop Spec Decorators
- The Prop Spec-derived Object Decorators
Understanding Prop Instantiation
Props may be instantiated on the server either in the Edit instance of an area or a Play instance. Props instantiated in the Edit instance persist with the area, whereas props instantiated in a play instance are destroyed the moment the area spins down.
The process for instantiating a prop in script is as follows:
specKey as ID = 1 //use any valid specKey for a spec within the _PropSpecOracle propSpecOracle as NodeRef of Class _PropSpecOracle = $_PROPS._getPropSpecOracle() //get our prop spec oracle propSpec as NodeRef of Class _PropSpec = propSpecOracle.GetSpecByKey(specKey) //get the spec we're interested in creating a prop from prop as NodeRef of Class _Prop = propSpec.CreateFromSpec() //create our prop
After the call to 'propSpec.CreateFromSpec()', the following will be true:
- The prop object will have been created from the spec and default values will have been populated
- The prop object will have notified all decorators of its creation, allowing those decorators to perform their own synchronous initialization
- The prop object will have been registered with the area and either linked with the area root node (if we're in an Edit instance) or stored in a temporary collection (if we're in a Play instance)
- In the case of the standard 'spatially aware' prop, the process for replication to clients within the prop's awareness range will have begun
That's it! You can now access, modify and use the prop at will.
Understanding Prop Instance Destruction
The process for destroying a prop in script is as follows:
myProp as NodeRef of Class _Prop $_PROPS._RemoveProp(myProp)
At this point, the prop will have been removed from the area and any spatial awareness tracking or replication will have ceased for it.
Querying For Props
To query for props (perhaps because they were created during a previous session or because you don't store references to them elsewhere), simply make a call to one of the following methods on the $PROPS system node:
method _FindPropsBySpec(propSpec as NodeRef of Class _PropSpec) as List of NodeRef of Class _Prop method _GetAllProps() as List of NodeRef of Class _Prop method _GetAllProxyProps() as List of NodeRef of Class _Prop
Understanding Client/Server Props
The default prop spec is designed to provide an example of creating objects that will only become visible to the player when s/he approaches an object. This is accomplished through clever use of spatial awareness, replication and local client visualizations to give the illusion of permanence for temporary, dynamic objects.
Understanding The Prop Spec
Creating a New Spec Decorator
image
Extending the Base Prop Spec
image
Creating (and Manipulating) Props From Script
image