||[Sep. 3rd, 2008|03:14 am]
Spectre Gruedorf Challenge Blog
No development update here, but rather a straw poll. (Today's feature, adding a fucking .INI file, is pretty boring.)|
First off, note that egometry has now bet me $250 that his game will be in a better state at the end of the year than mine. He was foolishly drunk. I was foolishly sober. Note that he is actually building a game with Spectre and has yet to crack the engine open, and also that he has no 3D guy yet. Poor bastard. Easiest $250 I ever made. Friends, don't play Gruedorf Challenge for money. Why? Because NOBODY WINS.
That said: I want a sanity check on how we're implementing scripting in Spectre. Here's how it works now. Certain scripts are loaded:
- on game initialization
- when you open a new level (always)
- when you open a new level (this is defined in the level header)
- when you have an object embedded in SLED that is a Ruby object (namely, it runs the script containing the object definition, and then creates an object, does the Spectre<->Ruby tie song and dance and the Spectre<->Networking song and dance, and calls various functions on the Ruby object to set it up)
And kaput, you're done.
During the loading business, you have the option to request hooks on certain event signals. A non-definitive list of these is as follows:
- finished 3D rendering
- finished post-processing pass
- finished 2D rendering (i.e. you have rendered everything except the console, and this needs a flip)
- mouse click down event received
- mouse click up event received
- focus leaves app
- focus returns to app
- (one of) a (selection of) user configurable timer(s) just ticked
- physics collision (this one is a bit finicky; you call it on the Ruby object with an attached physics object associated with it, and takes some dancing.)
- some networking stuff
and basically, other general events. This seems like a reasonably balanced approach: the game events, whatever they may be, end up decoupled from the engine logic very forcefully, and fuck-ups tend to be localized to one thing and don't bring the engine down.
There are two other candidate models, which I will call the Ben model and the Nick model, after their instigators.
Ben Model: we sent all events to the user in one place, in one big lump, and let him puzzle it all out.
Nick Model: rather than the engine pumping scripts, the scripts should pump the engine. Then, possibly, make the script-running layer more complicated.
I reject the Ben model out of hand, because by explicitly not allowing the creation of specialized game object types, it makes it very hard for a scripter to add something new and interesting to a level without the intervention of a programmer. If I have a computer terminal object, however, my idiot level designer (no offense, Jesse) can just drop in a new computer terminal and it works. I think both models make it harder to do that. This also has some problems with the Nick model, namely that you're never really sure what happened and you have to do something very much like pumping the engine to figure out what actually happened. It's much nicer, IMO, that I do all this bookkeeping for you, especially when it's much easier for me to tell you, "Oh, hey, go render your 2D stuff now" rather than throwing "Something happened" and letting you puzzle out what.
Nick's model is more interesting, because of where it comes from. Nick is a fellow I have programmed with for many years, and who recently got a bee in his bonnet to download Spectre, in all its glory, and embed it into Squeak, a Smalltalk environment written by insane people. Now my decision to not let the engine get pumped by the scripting language has made things very difficult here for him, and he ended up splitting my main loop in Spectre into two pump calls. Okay, so it's not so bad right now, but it could conceivably get worse. However, I don't know if I like this as much. For Squeak, this isn't so bad. Squeak is, AFAICT, pumping Smalltalk scripts and the engine, so all we've done is hidden the problem behind a layer of abstraction. Possibly a net benefit to the user. In general, though, I dislike having everything - again, including code possibly written by blind monkeys - being responsible for engine pumping.
Anybody have any thoughts on the right way to embed a scripting language into a game?
(Part of this is not due to Nick and Ben, but is due to a conversation with a Noted Game Luminary, to whom I am much indebted and who really made me realize that I should be more nitpicky about detail.)