I'm asking about a very small domain. One-off extension scripts. IE, defining a new weapon for scorched earth.
When providing and API for small extension I've seen two approaches.
The API exposes classes that the extender then subclasses, overriding the needed methods.
--# weapons/flame_missile.lua --#extender pulls in a predefined weapon base class require "weapon.missile" --# luabind syntax for classes class "flame_missile" (missile) function flame_missile:__init() self.hotness = 10 self:set_cost(42) end function flame_missile:on_hit( who ) who:take_damage(self.hotness) who:ignite() end
In the other approach the api just exposes accessors and sandboxes the script, re-executing the file with each new missile and using the globals as the instance's state.
--# weapons/flame_missile.lua hotness = 10 cost = 42 --# extender just knows that an on_hit function will be called --# when the missile hits something. function on_hit( who ) who:take_damage(hotness) who:ignite() end
NOTE: in my example
who's api is OO. I'm not interested in whether OO should be used in the extension API. I'm more interested if OO should be used to incorporate user extensions into the game.
The first one feels more C++-y. So I'm a little more comfortable with from a software engineering standpoint. However, one-off scripts don't need to fit together into a larger architecture. Further, they could be written by less proficient coders, so all the fancy OO might be lost on them.
I really like how concise the sandbox approach is. But it's a little limiting (only one missile per file, inheriting behavior from another weapon is no longer possible. I'd really like to define my extension api like this but I'm a little wary as it's a radical departure from classic C++ programming style.
Which method do you prefer?
Have you had any bad experiences with one or the other?
Is there an even better way to elegantly incorporate extensions into the game?