Modules
A module is a particular object that Daneel works with when it is loaded and during runtime.
Modules are mostly used to provide user configuration and create custom components.
Registering a module
Registering a module is no difficult than adding the module name and object to the Daneel.modules
global object :
ModuleObject = {}
Daneel.modules.ModuleName = ModuleObject
Configuration
The first point of a module is to expose some configuration that can be overridden by the user.
The module object may provide a ModuleObject.DefaultConfig()
function that returns a table (the default config).
In a similar way, users may setup a ModuleObject.UserConfig()
function that returns a table (the user config), containing only the configuration key/values they want to override (or add).
Upon loading, Daneel will merge the user config into the default config and put the resulting object in the Config
property on the module object.
Daneel's config is set before the module's config, so the Daneel.Config
property is accessible.
function ModuleObject.DefaultConfig()
return {
key = value,
key2 = {
key = "value",
otherKey = "module value"
}
}
end
-- you may set the default value for the Config property, it will be overridden when Daneel loads
ModuleObject.Config = ModuleObject.DefaultConfig()
function ModuleObject.UserConfig()
return {
key2 = {
key = "user value" -- this value will override the default value set in the default config
},
userKey = "user value",
}
end
-- Upon loading, the ModuleObject.Config object has this content :
{
key = value,
userKey = "user value",
key2 = {
key = "user value",
otherKey = "module value"
}
}
Loading
Daneel may call a Load()
function if it exists on the module object whenever it loads.
It is only called once, after all of the config have been set and before Daneel.Awake()
(and all the module's Awake()
functions) gets called.
Runtime
During runtime, Daneel may call the functions Awake()
, Start()
and Update()
if any of them are found on the module object.
As with regular scripts, Awake()
and Start()
are called in sequence at the beginning of a scene, while Update()
is called every frames.
Creating custom components
A component is a specialized object that works closely with a game object (game object are said to be composed of components), modifying its properties and purpose.
Daneel provide these properties to components (built-in and custom ones) :
- Can be created via
gameObject:AddComponent( componentType[, params] )
. - Can be created/mass-set via
gameObject:Set( { componentType = {} } )
. - Getters and setters of the component can be accessed dynamically.
- Extend the
Component
object : you can callcomponent:GetId()
,component:Set(params)
andcomponent:Destroy()
. Daneel.Debug.GetType()
returns the component type whenever passed a component instance.
But component also have these requirement :
- Component objects must provide a
New()
function that accept the game object as first argument, accept a second optionalparams
argument of type table and returns the component instance. - Component objects must be the metatable of the component instances.
- The component instances must be accessible on the game object through a property named after the component's type with the first letter lowercase. Ie :
gameObject.modelRenderer
,gameObject.progressBar
. - The game object should be accessible on the component instance through a
gameObject
property.
A typical (and minimal) component constructor looks like this :
MyComponent = {}
--- Create a new MyComponent component.
-- @param gameObject (GameObject) The game object.
-- @param params (table) [optional] A table of parameters.
-- @return (MyComponent) The new component.
function MyComponent.New( gameObject, params )
local component = setmetatable( {}, MyComponent )
component.gameObject = gameObject
gameObject.myComponent = component
if params ~= nil then
component:Set( params )
end
return component
end
You register a component by setting a componentObjects
property in a module default config.
Note that the component object may also be the module object itself.
function ModuleObject.DefaultConfig()
return {
-- register the object as a component
componentObjects = {
MyComponent = MyComponent,
}
-- the component type will also be added to Daneel.Config.componentTypes
-- the component object will also be added to Daneel.Config.objects
}
end