22 June, 2007

Testing New Waters

It's been a while since my last post. I've been quite busy with life and work, and haven't had much of a chance to do anything with the game engine. I also purchased a new MacBook Pro (15"), which I absolutely love, and do miss my time with Dolphin (but not Windows!).

I've gotten the latest Parellels Desktop application running with Windows Vista, Dolphin is installed on it, but something isn't working with OpenGL in it. I'm not sure if it's Parallels that's having problems or Vista. Needless to say, this is the biggest hold-up for continued work on the engine. Hopefully there isn't a lynch mob forming because of my switch to Mac.

In the mean time, since it's based on Smalltalk, I downloaded Xcode from Apple and have started programming in Objective-C. I thought I'd give porting the basics of the game engine to it and see how that went. There have definitely been ups and downs. Objective-C is a very nice language, and Cocoa is a wonderful set of classes to help ease development. But I seriously miss the class browsers of Smalltalk.

Continuing my lust for more things Smalltalk, enter F-Script... Since Objective-C is derived from Smalltalk, it has reflection. F-Script is a Smalltalk scripting language intended to leverage that.

I've taken the Objective-C version of the engine (in its rudimentary form) and instead of subclassing GameActors and GameScenes (and overriding methods like #advance:) to create gameplay, each one is just an instance with a script, and calls out to the script methods that make it unique. Consider this example of an actor:
sprite := nil.

"Called when the actor is initially added to the scene."
create := [
GameSprite fromTexture: 'media/ship.bmp'.
self transform setPosition: 10 <> 10.
].

"Called once per frame to advance gameplay."
advance := [
self transform rotate: 10 * engine deltaTime.
].

"Called once per frame to render the actor."
render := [
sprite renderAt: self transform.
].

The above script shows off many cool features of Objective-C and F-Script....
  • F-Script instantly has access to all of the game code (as witnessed by the use of GameSprite).
  • Before the script was compiled, the game can assign identifiers in the script to objects (as seen through the use of "engine" and "self").
  • Objective-C code can query identifiers in the script and call them (as seen by the assignments of create, advance, and render, which are then called at runtime from Objective-C).
What makes this all-the-better is that none of this required any fancy function hooks, as would be required with other scripting languages like Lua. With a little more effort, it will be extremely trivial for actors and the scenes to even make direct calls to OpenGL.

Now, with anything "new and cool" there will always be pros and cons.

The biggest pros in this case are that the game doesn't need recompiling, and that scripts drive most of the gameplay. That's great, especially for teams that separate programmer and designer. Smalltalk still has it beat since I can recompile functions at runtime to update gameplay, but separating gameplay scripts from actual game code is a very good thing.

As for cons, the biggest one is that using any scripting language can make all but trivial games very difficult to program. For example, try and use a scripting language to program Othello. The interaction with the game and objects may be simple, but rules, and even simple min/max AI aren't so obvious in their solutions (and performance will suffer tremendously). In the end, I'm sure this code would just be done in Objective-C, though, and F-Script would just access to it (board isMoveValid: 2 <> 2).

F-Script isn't an actual Smalltalk. It does have a wonderful class browser, though. And while I take some time off from Dolphin (and Windows), I must say that programming in Objective-C with F-Script at the helm is a delight, and I'm hoping to leverage both significantly on the Mac.

If any of you have a Mac, be sure to download F-Script, and send me an email so I can share some of the work I've done.