Version 16, last updated by nolver at May 10, 2010 11:57 UTC
ManualBasics LogicWorldObjects
Logic World and Objects
Logic Objects
What are logic objects?
Logic objects are small parts of your game that share a certain amount of useful functions, commonly used while developing games. By using Tomahawk's logic object, you can focus in what's really important, creating the logic of your game, and forget about everything else.
All logics objects will automatically provide you:
- Smart creation: when you create logic objects, they'll be instantiated an kept dormant until all their required assets have been loaded from disk. You can create a bunch of objects ahead of time, and then have a single "loading" to load all the assets required at runtime, or in the other hand, create objects on-the-fly and the engine will load the assets whenever is possible. In both cases, you are safe the object won't run before everything needed is in place.
- Parent Relationship: you logics objects can be child or parent of other logic objects.
- Smart destruction: when destroying a logic object, all its children will be destroyed as well. The destruction is deferred, and occurs whenever its safe.
- Indexing: All living logic objects are indexed by a string. You can retrieve objects of the world by its name. You can use a name of your choice (for relevant objects), or let the engine auto-generate one.
- Archetyping: Instances of logic objects can be created from different predefined value sets, called "archetypes". This powerful feature enables "property driven" logic, allows programmers delegate to game designers and enable and make it really easy to integrate custom tools (like map editors).
- Updating: Logic objects can be updated by custom logic. Have your animation logic called each frame with zero effort.
- Pausing: Logic objects are "pausable" by default, this means than when the game is paused all of your logic will be paused automatically. Forget about checking if the game is paused all over your game code. You should deactivate this behavior on the few objects that are required to run while the game is paused, like for instance, a "Pause Screen".
- Detailed life cycle: All the featured mentioned, and a few more, constitute the "object life cycle". This cycle is very detailed, and allow you to indicate what should happen at each of the relevants "moments" of the object's life.
Creating your own logic objects is easy, just inherit the class Tomahawk.Runtime.XObject.
All the relevant "events" of the object life cycle can be fullfilled with your own logic just by overriding the right method:
[example code of logic object]
Life cycle of logic objects
As described before, implementing logic object is just a matter to distribute the logic across the right moments of it's life cycle. Here comes a detailed description of the methods you can override, including an explanation of when exactly your code will be called:
- OnRegisterChildren: When a logic objects is created using an archetype, this method gets called. It gives you the opportunity to register the objects created by "archetype inlining" (that's when you want a collection of other objects to be included in the object's archetype). This is mandatory if you want all those, automatically created, children objects to be correctly registered in the game world.
- OnInitialize: Right after the objects is instantiated, occurs the first relevant moment of a logic object: initialization. The goal usually is to instantiate more logic objects (as children), create engine subsystem objects, and get everything prepared for the object execution. If your object requires content assets, they won't be loaded at this point, so please consider moving any logic that may require them to OnAfterInitialize, OnPreBeginPlay, or OnPostBeginPlay. Before OnInitialize finalizes, all engine objects that required contents being loaded from disk must have been created.
- OnAfterInitialize: This method gets called when OnInitialize has been called for all the new objects that were created during the current object initialization.
- OnPreBeginPlay: Occurs when all the required assets (content that needs to be loaded from disk) is already available for this object. Here is where you should place any initialization logic that require contents of any type. Imagine you need to know the size of a texture for some calculations, you are granted access to that resource at this point.
- OnPostBeginPlay: Occurs when all the assets (content that needs to be loaded from disk) required by the object's children are already available. This event occurs only when OnPreBeginPlay has finished on all children objects. After this point, the first Update is about to happen for the object, if required.
- OnUpdate: This event occurs at a certain rate (luckily, more than 30 times per second). You can use this event to implement the animation of the object. You will receive the amount of time elapsed since the last update. Remember to multiply all the incremental values you are using by the elapsed time, in order to achieve an constant-speed game experience, that doesn't depend on the amount of frames per second being drawn. Only objects that have its "UpdateRequired" property set to true get updated, so don't forget to the this flag to true during the OnInitialization of the object.
- OnBeforeDestroy: This event occurs when the objects is going to be destroyed, and removed from the logic world. Within this method you'll tipically have to destroy all objects that were created during the life of the object. You don't have to care about children logic objects, because these will be destroyed automatically by the engine. If you created non-logic objects, or logic objects that were not added as children of this one, remember to destroy them at this point.
- OnAfterDestroy: This method gets called when the object is no longer in use by the engine, and has been already removed from the logic world. Beyond this point, the object will be claimed by the garbage collector sooner or later.
- OnPause: This methods allows you to respond to a game logic pause.
- OnResume: This method allows you to respond to a game logic resume (when the game is no longer paused).
A common error while creating your own logic objects is forget about calling the base implementation of those methods. Remember: you should always call the base implementation when overriding this methods.
Logic World
The logic world is the collection off all living logic objects. It is managed by a special singleton class: Tomahawk.Engine.Runtime.Logic.XWorld.
XWorld provides the interface to a few interesting and commonly used features:
- Logic objects creation
- Logic objects indexation
To have access to those functions you use the XWorld's class singleton object, just like this: XWorld.Instance
Creating logic objects
Logic objects must be instanced through the XWorld object's factory mechanism. To create a new instance of a logic object, instead of the 'new' keyword, you must use: XWorld.Instance.CreateObject method. This method returns an instance of the newly created object, and supports several parameters:
- bool autoInitialize: Indicates if the object should be initialized right after creation. This parameter is optional, and its default value is true. Unless you specify "false" as the first parameter, the object created will be initialized before being returned.
- Type objectType: Indicates the type of object you want to create. You must enter a logic class name by type, ie: typeof(MyLogicClass)
- XObject parentObject: An optional parameter that can be used to indicate the new object must be a child object of the specified one. By doing so, we are creating a parental relation (the new object's Parent property will point to the specified object) and causing the object being automatically wiped out when its parent is destroyed.
- string Id: An optional name to be able to retrieve this object from anywhere in the game code. If you don't want to retrieve this object by its name, specify an empty string and it'll be assigned an automatically generated name.
- string Archetype: An optional archetype resource that you want to be used to assign initial value to object's properties. If you specify an empty string, the object will be instantiated with the default values you may have defined in the source code for each property.
Ejemplo de create object
Relaciones parentales
Creación en diferido, inicialización diferida, con y sin arquetipo
No usar new
Retrieving logic objects
Implementing logic objects initialization
detalles de RegisterChildren, OnInitialize, Onbefore/after initialize, on first update
Implementing logic objects animation
Require Update, y cliclo del primer update
Destruction of logic objects
Destrucción en diferido, destrucción de hijos automatica