Skip to main content
GameDev.net gamedev.net
🔒 Locked

Prototype vs class-based OO for game scripting?

Started by cypherx Dec 21, 2005 at 5:49 PM 6 replies 1.3k views
Original Post
cypherx
cypherx
Does anyone here have opinions on whether prototype-based object orientation has advantages for game scripting? Prototype-based: Objects don't belong to predefined categories, but gain certain functionality at run time. (more exotic, used in &#106avascript and io) <!--STARTSCRIPT--><!--source lang="cpp"--><div class="source"><pre> someobj = Object.clone() someobj.f(x) = { <span class="cpp-keyword">return</span> x+<span class="cpp-number">1</span> } </pre></div><!--ENDSCRIPT--> Class-based: This is the more familiar type of OO, used in Java, C++, etc. Objects have certain functionality determined by which class they belong to. <!--STARTSCRIPT--><!--source lang="cpp"--><div class="source"><pre> <span class="cpp-keyword">class</span> SomeClass { f(x) { <span class="cpp-keyword">return</span> x + <span class="cpp-number">1</span> } } someobj = <span class="cpp-keyword">new</span> SomeClass </pre></div><!--ENDSCRIPT--> I don't have much experience with prototype-based coding and it seems very unnatural to me. But I'm thinking that maybe the lack of structure might be somehow beneficial for game scripting (where you might want to add capabilites to an NPC at an arbitrary point in the game) Any ideas? -Alex
darookie
darookie
The ideal way would be to support both (like emulated OO in Lua). Just let the users decide what they like better and enjoy the best of both worlds [smile]
umbrae
umbrae
I really like static methods and classes. It doesn't detract that much (you just have to declare things beforehand) but the benefits are quite good: errors at compile time not run-time, ability to use rigid linking because the whole structure is known and you can use other static methods to make sure it's all going to work. You can be sure that objects won't change and it's more structured so it's (arguably) easier to read and figure out what's happening.

I don't think it's a good idea to support both, choose a paradigm and stick to it, less confusion.

I guess this question is similar to dynamic typing vs static typing, so similar solutions will be relevant.

Addendum: I don't think games need a great amount of self modifying code and dynamic additions. Yes scripts should be loaded and unloaded during the course of the game world, but they can just be subclasses of already defined types. Functionality can be added through subclassing and delegates.
evolutional
evolutional
I quite like the prototype based system myself. In my scripting language of choice, I find myself making my own 'virtual' types as a return from a function. I also find it useful to be able to attach extra properties at runtime (a feature I severly miss in C++) and be able to iteratively clone the object and take all these new properties with you.

Having said all that, an up-front and static definition of a class really helps the developer - it forces you to plan your classes up front but removes a lot of the flexibility of the prototype method.
umbrae
umbrae
Quote:
Original post by evolutional
I quite like the prototype based system myself. In my scripting language of choice, I find myself making my own 'virtual' types as a return from a function. I also find it useful to be able to attach extra properties at runtime (a feature I severly miss in C++) and be able to iteratively clone the object and take all these new properties with you.

Having said all that, an up-front and static definition of a class really helps the developer - it forces you to plan your classes up front but removes a lot of the flexibility of the prototype method.

So you like the prototype based method for development, not necessarily deployment?

If so then fair enough. My current design for my engine revolves around dynamic coding, where you have an instance of the engine and tweak and add code while it's running. For animation, triggers etc. You can reset, play back, tweak values while it's running. Once you finish all this you can export the classes and code into files that are 'linked' to certain objects. These files are then loaded whenever the scripted object is used.

Also in my scripting language (which is static typed) in any file you can 'drop into' any class and add properties and methods. So in a way it (I hope) takes the best of both worlds.

File1:
class Actor    integer health    void hurt(integer amount)        health -= damage        if health < 0            health = 0


File2:
class Actor    void heal(integer amount)        health += amount


Edit: Oh yeah, it's a tab-blocked language
umbrae
umbrae
Quote:
Original post by cypherx
... where you might want to add capabilites to an NPC at an arbitrary point in the game ...

I glossed over this when I read the post the first time. This seems like an absolutely ideal reason to use a prototype based approach. I can't think of a better way to do it really, apart from using states which isn't a complete solution.

I think I would still like to plan out the classes and states beforehand, even if it takes longer, but I can really see the attraction to a prototype based approach. But I can't help wondering if it would introduce errors that would be hard to track down.
evolutional
evolutional
Another way would be to have a 'ExtendedProperties' container on each object, so that most of the stuff remains statis as it was declared on the original class, but you can then add custom properties to NPCs and other objects at runtime. That said, I don't really see how you'll get this to work simply in a statically typed language unless you provide some form of variant type.
umbrae
umbrae
Quote:
Original post by evolutional
Another way would be to have a 'ExtendedProperties' container on each object, so that most of the stuff remains statis as it was declared on the original class, but you can then add custom properties to NPCs and other objects at runtime. That said, I don't really see how you'll get this to work simply in a statically typed language unless you provide some form of variant type.

Well actually I'm more towards making it as data driven as possible, so everything that's possible (up to a point) would be in a xml or another data format. Properties can be accessed through a hashed dictionary (that can potentially contain other dictionaries, they contain primitive data - integers, booleans, strings, etc). It's only really when you come to new functionality that it gets interesting. I think that it's not that difficult to just declare whatever you want in the class instead of adding on the functionality at runtime.

I'm guessing that any function that you are adding to an object wouldn't be called before it exists, so there isn't that much difference between if it existed from the start or was added at runtime. The use that I see with a more dynamic system is modifying objects at runtime because of runtime conditions. But this can be done with states to a lesser or greater degree (depends on how flexable your state implementation is). I think that the other advantages in a prototype system can be replaced with similar behaviour in a static system and that in doing so you aren't loosing time (or if you are it isn't much) and actually probably gaining time by having a concrete definition of your objects.

To be honest, in my opinion, I think that the prototype method is lazier. Now I'm a LazyProgrammer but that's slightly different. I think that starting with a good definition and not changing and modifying things in code is a good idea. After a while wouldn't the prototype system get unwieldy? You may forget what was added to what, when and where in the code.

There are good reasons to use both, but because of the way I like coding I would choose class based oo over prototype (given equally well designed and nice languages).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.