🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Implementation of Entities / Game Objects in AS

Started by
3 comments, last by WitchLord 7 years, 3 months ago
I can't figure out how to implement entities in Angelscript. Like can I make a special class such as "Entity" in C++ and expose it to the API, and then let that be inherited from?
Then can I run the update() and draw() methods on anything that inherits from "Entity" and exists? Or if I can't do that, can I have some sort of function to register a class as an entity?
I'm trying to make my script API as simple and compact as possible, moving away from the structure of software like LOVE (framework and not engine, reinvent parts of the wheel every time you want to make a game) and be able to get a game object on the screen ASAP with minimal or **no** script code that handles any actual management or collections of entities; I want to manage all of that via C++ and manage entity creation through level loading.
(originally posted in /r/gamedev, I was pointed h ere)
Advertisement

You register an interface and then scan all the types declared by script and check if they inherit from a certain interface. And for those that do inherit from an interface, you scan them for various functions associated with that interface (update() and draw() in this case). There's a decent example in the samples/game directory that describes this.

Although it would be cool if we could register a callback in the engine that gets called whenever a type inherits from an interface. Even better if we could register individual callbacks for certain interfaces. But even just a global callback would be enough to take away the burden of scanning every time a module gets created.

But then you need to be aware of what instances were created in order to call them you. I'm not exactly sure how to do this either. For example, you have this code:


class MyEntity : IEntity
{
    MyEntity()
    {
    }
}

How do I know when someone created an instance of MyEntity? So I can store it somewhere to forward events.

You replace their constructors with an application defined one that simply forwards the call. Or manually ask the user to register that entity with a function like TrackEntityInstance(your_object_instance). But that looks ugly. Not really sure how to do this either. Again, something that could be made easier with callbacks. Dunno.

So I checked the game example. It contains:


@self = obj;

And other code appears to use "self" for every single internal variable reference. Must I do this, as in there's no prettier, briefer, simpler alternative? E.g. do I always have to refer to my x position as self.x? That'd be a sad dealbreaker as this would destroy ease of use...

Unfortunately, a scripting language that is supposed to cover a more broad range of uses, can only do so much for special cases. You have to understand that there are certain limits to how much a scripting language can behave or interact with C++. Try comparing more scripting languages if one does not meet your requirements. And if you still have doubts, try rolling your own to see if you can do better.

Eventually, if you still can't achieve your initial goal. You might have to take into consideration that your initial design has some flaws.

So I checked the game example. It contains:


@self = obj;

And other code appears to use "self" for every single internal variable reference. Must I do this, as in there's no prettier, briefer, simpler alternative? E.g. do I always have to refer to my x position as self.x? That'd be a sad dealbreaker as this would destroy ease of use...

Alternative 1: You can hide this from the end user by providing a base class that the end user's classes can inherit from.

Example:

// Provided by application developer
class CBaseEntity : IEntity
{
  // virtual property
  vector2 pos { get { return self.pos; } set { self.pos = value; }
  CEntity @self;
}
// Provided by end user
class CUserEntity : CBaseEntity
{
  void onUpdate() { pos += velocity; }
  vector2 velocity;
}

Alternative 2: You can write a pre-processor to change scripts by replacing 'pos' with 'self.pos', or provide other types of macros that hide the fact that part of the entity is stored in the application and other in the script. You can use the CScriptBuilder add-on as the base for this pre-processor and add your own logic.

Alternative 3: You can define that the script class must have a minimal set of properties, and then have the application use those directly instead of storing them in the application class. The application can easily enumerate the properties of a script class to read/change the values.

I'm sure there are many other options available. The game sample is just one way to integrate scripting in a game engine. You don't have to do it that way. Some people prefer not to use script classes at all, and instead just allow the scripts to write a set up global functions that will be executed by the application on specific events.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement