Entity

by Kaiochao
Build game objects from components, like in Unity!
ID:2130101
 
Also check out the Standard Components! It's just a Camera for now, though!

For more examples, see Some Entity Components.

For anyone who downloaded the source:
* What do you think of it?
* Are you worried it might be too much overhead?
* Do you think inheritance is easier to work with?
* Do you have ideas for new components?
* Have you already made some components of your own?

Please provide feedback in the shoutbox or the forums, or on the GitHub Issues page.

Troubleshooting

If it's not compiling, you probably don't have the required libraries installed, or you should delete the BYOND/lib/kaiochao folder and reinstall everything:
* Kaiochao.Directions
* Kaiochao.Constants
* Kaiochao.Event
* Kaiochao.InputHandler

The demo components

I think one cool to note about this component-based entity system is that, once you have a bunch of components available, you can design entities by combining any number of components with whatever configuration you want, and you'll end up with something that might be useful.

For example, the blue circle is an entity (of type /entity) with the components:
* /component/player: required by the Player Controller, contains a reference to a client.
* /component/player_controller: moves the entity according to input given by the input handler.
* /component/camera: allows easy control of the viewport of the client, if any.

The red circle is an entity (also of type /entity) with the components:
* /component/move_ai: lets you "set a destination" for an entity, and the entity will continuously move towards it in a straight path. Required by the Wander AI component and is added automatically if it doesn't already exist.
* /component/wander_ai: while in view of a camera, the entity moves to a random nearby position, waits a bit, and repeats.

More components to come?

If I wanted to add something like weapons and guns and damage, I might create a component that allows equipping and using weapons; a component for the weapons themselves (or maybe they should be entities?); and a component that manages health, death, and taking damage. Projectiles (bullets) would also be entities with a component that enables constant velocity and/or drag.

Recycling the equipment component, I could create tools for mining and building, and put some killable entities on the map that drop crafting materials when they die. I'm just a few steps away from remaking Hazordhu with this system. (So why don't I? Good question.)

I think it would be pretty awesome if any of you programmers out there could take advantage of this system. Not necessarily by messing with the source, but by designing new components and sharing them for other game developers to take advantage of. Components are meant to be loosely-coupled; they should be designed in a way that minimizes dependencies on other components. This makes them very modular. They should be able to support design situations such as:
* Removing the Wander AI component from wanderers should make them stand still. (Check!)
* Removing or disabling the Player Controller component should make the entity ignore player controls. (Check!)
* Removing or disabling the Camera component should... well... you should probably include that.

What's this "Interfaces" folder?
In the "_Utilities" folder, there's a file, "Interface.dm". It defines a new datum, /interface, whose sole purpose is to crash when created.

This is because interfaces shouldn't be instantiated; prototypes that implement the interfaces are what gets instantiated. The interfaces themselves are just placeholder types; you can cast implementers as interfaces in order to call the interface procs, i.e.:
interface/updater
proc/Update()

clock
proc/Update()

component/controller
proc/Update()

mob/Login()
var interface/updater/updater

updater = new /clock
updater.Update()

updater = new /component/controller
updater.Update()


In this library, components can optionally implement the following interfaces simply by fulfilling the requirements:
/interface/updatable_component: The component has an Update() function defined. It is called once every frame for all enabled components.
/interface/late_updatable_component: The component has a LateUpdate() function defined. It is called once every frame for all enabled components, after all Update()s have been called.
/interface/startable_component: The component has a Start() function defined. It is called at the end of the frame a component is added, before any Update()s have been called.
/interface/destroyable_component: The component has a Destroy() function defined. It is called when the component is destroyed, whether it's directly, by calling Destroy(), or by the entity containing the component being destroyed. This happens before the next Update() is called. This should be used to clear references to other objects, which would prevent their garbage collection.

This is nice and efficient, because if a component does not have an Update() (or LateUpdate()) function defined, it won't be called, even if the component is enabled. This is why the demo can have 5000 entities on the map, each with the potential to be updating every frame, but use virtually no CPU usage while inactive.

You can easily check if a given datum implements a particular interface using datum.Implements(InterfaceType). The results are cached, so it should be very efficient.

I might move this whole interfaces part to a different library.