user-defined types for components and events?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • user-defined types for components and events?

      I'm trying to apply data-driven design to my game engine to Get game-specific things like quest/mission systems, mpcs, skills and spells be implemented in script, with c++ used for performance-critical code.

      How do I define new components through e.g text/JSON files. The book (and numerous online tutorials) demonstrates how predefined components that are already in the engine like physics can be created from data files. What I couldn't figure out is how to allow files to define entirely new components. Would this involve the use of some scripting language, and if so, how would I go about notifying the c++ engine about these new components when they get constructed by an actor that needs them?
      The same thing for user-defined events/script processes as well.

      I was also looking for an alternative to Lua as the scripting language, something closer to c++. Angelscript looks like a promising candidate. An intriguing possibility is also runtime-compiled c++ (molecularmusings.wordpress.com…-language-under-the-hood/). Does anyone have experiences with either?

      The post was edited 1 time, last by Neurone ().

    • To define new components outside of the C++ side of your engine, you are going to be looking at a scripting language for sure. What I suggest is taking a look at Unity and its 'Script Component'. Essentially the script component would interface would a set of pre-defined functions, for instance in Unity you get;
      • Start
      • Awake
      • Update
      You can think of this as your own way to extend your component system, exactly the same way you would do so in C++. The only difference is that you would add the component with something like

      Source Code

      1. <ScriptComponent file="Character.lua"/>​


      In my own system I also allowed for passing the data variables into the scripting language, allowing you to configure the component similarly in script.

      Source Code

      1. <ScriptComponent file="Character.lua">
      2. <Vars>
      3. <Var name="m_name">Frodo</Var>
      4. </Vars>
      5. </ScriptComponent>


      At this point I manually parsed the var array on the C++ side and stuffed the values into the script (overriding any previous entries), this however could also be handled script side if you had a way to interface with the values in a 'Load' function, I have also done this in a different situation by parsing the XML/JSON variables into a Lua table, which can be passed into a function.

      Now, as for the method of how to handle inheritance, you can do 2 things that come to mind.
      1. Use the script as a module (Function environment in Lua), and have it perform a 'dofile' which will parse the contents of another script module into the namespace, at which point you would be free to override functions, while still holding onto the base functionality.
      2. Use a script 'Class' which if using Lua, Rez has a good example of which supports inheritance. You could have a base class that all scripts inherit from ie. MonoBehavior in Unity. Unity seems to handle the instancing of this object by using the file name as well ie. If you have a script file named 'Character.lua' it looks inside of that file for the table entry 'Character' and creates an instance of this.
      ​Namespace Example

      Source Code

      1. function Start()
      2. print(m_name);
      3. end
      4. function Update()
      5. print(m_name .. " is updating with deltaT of: " .. Time.deltaT);
      6. end
      7. -- Variables
      8. m_name = "Default Character Name";


      Class Example

      Source Code

      1. Character = Class(ScriptComponent,
      2. {
      3. Start = function()
      4. print(m_name);
      5. end,
      6. Update = function()
      7. print(m_name .. " is updating with deltaT of: " .. Time.deltaT);
      8. end,
      9. m_name = "Default Character Name"
      10. });
      11. -- Your C++ script loader would identify that you are loading 'Character.lua' and so look for the 'Character' class table, and instantiate this.
      Display All
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • Neurone wrote:

      I'm trying to apply data-driven design to my game engine to Get game-specific things like quest/mission systems, mpcs, skills and spells be implemented in script, with c++ used for performance-critical code.

      How do I define new components through e.g text/JSON files. The book (and numerous online tutorials) demonstrates how predefined components that are already in the engine like physics can be created from data files. What I couldn't figure out is how to allow files to define entirely new components. Would this involve the use of some scripting language, and if so, how would I go about notifying the c++ engine about these new components when they get constructed by an actor that needs them?
      The same thing for user-defined events/script processes as well.


      I'm not sure you need to define brand new types in a data language. That seems needlessly abstract; why not just define it in your scripting language? I don't think defining new components in a data language is going to buy you much, unless maybe you're building a tool so that designers can design their own components. That could be useful, but in reality, you're just building a single highly customizable component.

      Here's how my component system works:

      The engine defines C++ interfaces for the types of components that I allow. These are registered with the object system so that I can create what I call "component systems" (more on that later). The concrete components themselves are subclasses of these interfaces. Everything in the engine that needs to talk to a component will talk to it through its interface, which makes switching implementations really easy. For example, I have a Renderable component that deals with rendering the entity. It doesn't matter whether it's a simple static image or an animated sprite, the interface is the same.

      Component systems are how I can organize things by component. Registered systems get notified when a component of the registered type is created, allowing them to store the component or whatever they want. The ComponentSystem class inherits from Process, so it also allows them to tick the components (my components don't have an Update() function and aren't ticked). An example of a component system is my animation system, which stores weak refs to every animation component that gets registered. Every frame, it updates the animations for high LOD entities.

      Finally, there is the component factory that actually creates instances of the component. This factory is owned and used by the object system when creating entities. I have entity definition files that describe a particular entity and all of its components. This file is loaded with each component being handed its own chunk of that definition.

      All of that lives on the engine layer and it's 100% C++ (except the data file).

      Now, in the game layer (a totally separate project file; my engine has about a dozen separate project files), I have the ability to subclass and extend any of those systems. I can create new concrete components or even whole new component types with their own subclasses. The engine does care. The same goes with component systems. All I need to do is subclass the factory so that the correct instance is created.

      All of this is C++.

      One of the C++ components I have is the ScriptComponent and the engine defines a BaseScriptComponent implementation. Any entity that is visible to the scripting system must have a script component.

      On the script side, I somewhat mirror the C++ entity architecture. There's a ScriptEntity class in Lua along with a ScriptEntityComponent class. You can create script components by subclassing ScriptEntityComponent. In the entity definition file, you simply list the script-based components inside the ScriptComponent definition. When the C++ ScriptComponent is spun up, it will tell Lua to instantiate those components and attach them to the script entity. In reality, the Lua ScriptEntity class is a subclass of the C++ ScriptComponent class. This acts as the Lua/C++ glue for entities.

      This system is extremely flexible and works well for my purposes. Entities and their components are created with data definitions. I can create components that live 100% in script and are purely for gameplay. I can also create game-specific components in C++ if I need the extra performance. In fact, I can move components to and from C++ very easily. All I need to do is move some stuff in the data files. In a future revision, I might make it completely transparent so that data files don't even know the difference between C++ & Lua components. Only the factories would have to know, though it creates a bit of an order-of-operations annoyance since the C++ script component has to exist before any Lua components are created. In practice, it hasn't been an issue.

      I was also looking for an alternative to Lua as the scripting language, something closer to c++. Angelscript looks like a promising candidate. An intriguing possibility is also runtime-compiled c++ (molecularmusings.wordpress.com…-language-under-the-hood/). Does anyone have experiences with either?

      Why not use C#? We used it on The Sims Medieval and it worked really well, except for a few poor decisions made back when the engine was developed for The Sims 3. Mono is a pretty strong platform at this point:
      mono-project.com/

      -Rez
    • .NET will work on any Windows machine. I believe Mono can be packaged up with the executable, so you're not forcing the user to install it. The virtual machine is basically just a DLL. The Sims 3 (which also uses Mono) has been made for PC, Mac, Xbox 360, PS4, and the Wii.

      The same is true for pretty much any scripting language. Lua is the same; you have to link with the Lua libs.

      -Rez