[Scummvm-devel] Tony Tough: developer here
giovannibajo at gmail.com
Fri Oct 26 04:27:12 CEST 2012
Il giorno 26/ott/2012, alle ore 02:17, Dreammaster <dreammaster at scummvm.org> ha scritto:
> On Fri, Oct 26, 2012 at 4:12 AM, Giovanni Bajo <giovannibajo at gmail.com> wrote:
> I'm the original developer of the Tony Tough game engine. I was not aware that you were integrating it into ScummVm until I stumbled upon it today. It looks like most of the effort has been already done, but if you need any explanation, you have curiosities or whatever I can answer by email, please feel free to ask me, I would be really glad to help you.
> Thanks for your amazing work
> As the developer responsible for the bulk of converting the game to run under the ScummVM framework, let me say welcome and salutations
> As you say, re-development of the engine has been pretty much completed. It's certainly a pity we weren't in communication earlier, though; your experience would have been greatly appreciated. The engine was pretty sophisticated compared to some of the other game engines we've worked on in the past. Particularly the threading/messaging mechanisms. Although it did give me some grief.. most of the work of re-implementing the game came from having to refactor it all to use a single threaded co-routine mechanism that simulates threading, so that the engine will work cleanly on all the various platforms ScummVM supports.
Yup, in fact I wouldn't have thought it to be possible to refactor existing code from threads to coroutines :) How long did it take you?
> One thing that would be very nice was if you had time to write any postings about your experiences with the original development. Anything that comes to mind.. methodologies you used, why you designed it the way you did, how game requirements affected the implementation of the engine, anything. ScummVM is as much about the community of active developers as the game players, and it's rare for us to have a direct line with original developers. I'm sure everyone else would be as interested in anything you had to say as I would. You either post them to the list, or pass them onto me, and I could make a blog posting of them.
I went though the pull review code and of course lots of memories sprang to mind, so I'm happy to post a few things.
The game originated in 1996, I was 17 back at the time. Luca Giusti and I wrote the first version of the game engine, and it was based on DOS and 8-bit (palette) graphics, with the venerable Mode X for achieving smooth scrolling and higher resolution (320x240), and compiled sprites (!!!). IIRC Luca wrote the game engine and I wrote the MPAL preprocessor (yuk!), compiler, linker and interpreter. We were a distributed team of 5-6 people working across Italy, and we were using Fidonet and BBS files areas to share files. I live in Florence and one of the artist (Sergio) was in Naples; I still remember that we used a direct modem connection on the phone line (so basically he dialed my home phone number with his modem, to setup a 14.4 kbit connection) and then send me the first 4 room background arts through it; they were an early 8-bit version, but I was in love with them :) I also remember our lead artist (Valerio) sent me the first version of the park map (hand drawn wireframe) by fax; the original thermal paper is now a picture hanging on my home wall :)
At some point, in 1997, it became clear that we need to gather together to get to a decent point, so we organized a one-week crunch session in a alpine hut in northern italy; we worked 18-20hrs a day for a week, ate lots of pasta, and completed an early version of the first 4 rooms. I remember the game engine was using dirty-rectangles at that time to optimize drawing.
In 1998 we got a deal with a local publisher (Prograph/Protonic), and part of the team got paid to finish the game. That included myself, but Luca declined (for personal reasons); that meant that I was able to work on the game full-time, while Luca only in his spare time. The publisher insisted on reworking the game with 16-bit graphics, and porting it from DOS to Windows; it wasn't trivial to port the existing code (Mode X stuff!), plus Luca couldn't handle it in his spare time, so I had to take over the game engine. I wasn't familiar with it at all (Luca had written it up until then), and thus decided to rewrite it from scratch. One of the few things that I brought over was the pathfinding code, and in fact I think it's quite obvious from its look that it's been written by a different hand.
The game engine is quite easy, as you have seen. I think it's been the first real world C++ object-oriented program I have ever written, so it's obviously very stretched towards using inheritance everywhere (new toy!). I still remember the joy of finally *understanding* polymorphism, and that's when the RMTask base class was born, and the idea of having a list of RMTasks that could be anything by simply reimplementing the draw() call. I saw in the code that the list was called "OTList" and, while the name obviously rings a bell to me, I don't recall what it means. BTW, "RM" stands for Roasted Moths of course; some classes in the source code begins with "FP" instead; that's "Falling Pumpkins" which was the original title of the game.
When I reimplemented the game, I went for full screen drawing, without dirty rectangles. I think i was positive that computers were fast enough for it, and in fact it did work quite well. I remember I quite optimized sprite drawing routines; for instance, most sprites are RLE-encoded as a way to quickly skip transparent pixels, and to avoid compiled sprites because there was simply too many sprites to compile them all without having memory issues. The game was running 60 fps on a Pentium 2, so that was good enough for us. The '30s (sepia) mode was a nice touch, but I remember it was noticeably slower at the time as it was an additional pass over the screen, so the framerate was dropping quite noticeably.
To build the rooms, setup background animations, decide rectangles of interactions with objects, etc. we built a so-called "location editor" (we actually used the word "location" for what is usually called "room" in adventures), whose source code I think has been lost. It was able to load a .loc file, modify it, and save it back. So both the game and the editor was using the same file format. At some point, we realized that it was better to separate the two formats, because the editor needed more information in basic format, while the game engine might use, for instance, sprites that were already rle-compressed instead of rle-compressing on the fly at load time; so the "lox" format was born. I think the game engine still opens the original loc files, but the final game assets only contains lox files.
One guy in the team (Marco) was one of those magic resources in game teams that is both an artist and a programmer; I think it's mostly impossible nowadays, and used to be just rare at the time. So he was in charge of both maintaining the editor *and* drawing the background animations *and* using the editor to insert them into the locations. So that's one hell of "eating multiple levels of dogfood" :) In fact, he was the one that prodded me to add support for "slot positions" to the game engine; with "slot positions", we meant having an optional x,y offset associated to a graphic frame within a animation; I remember we discussed whether this was worth it, but at the end of the day, he was in a better position to know, since he was using the editor after all. Later in the game, it proved *extremely* useful in one specific animation: to animate the beast walking out of its cage. In fact, the game engine has no concept of actors (the only "actor" is Tony), so every other actor in the game is just an animated background object; in fact, they just don't walk around. So, when the designer required the beast to walk out, Marco faked it through manually settings x,y offsets in the editor within the whole animation, making it scroll away. It took him a while of course, and won the title of "slot position master" for this achievement :)
Stuffing all files in a single compressed "resource" file was very common at the time. I don't think there was a rationale for doing it, it was just the standard way of doing it. Lucas was doing it, so why shouldn't we? :) I think it just looked cool, in a way. We were using LZO as a compressor because it was very fast at decompression; you might have noticed also that LZO is GPL, which means that the game was in blatant violation. I don't think I have *knew* what free software was and what a free software license was. I don't recall the details, but I wouldn't be surprised if I simply altavista'd for "fast compression", found that source code, downloaded it at 64 kbit/s, and dumped it into the game. I'm now deep into free software at many levels, I even give talks and do trainings about free software licenses from time to time, so I hope Markus of LZO can forgive the young me for not even realizing what I was doing.
Speeches gave me quite a few headaches. For a start, I realized that simply exporting all texts from MPAL to a txt/html file wasn't enough, because actors need context to meaningfully act. So I ended up writing a program that exported HTML file divided by rooms, with some contexts added, and even manually adding comments to explain them. This has been helpful and was important to get good speeches from them. I remember it was really fun when the actors director called us and played us over the phone the first recordings of character voice tests made by the actors. I think we actually voted between a few options to decide which voice sounded best for Tony. When I got the first speeches files back from them, I had some latency issues, especially when running off CDs. I think I ended up caching the main index in RAM and maybe precaching something (don't remember the details). I think I also changed the code so to delay display of subtitles to the moment I could effectively start playing the speech, because it was very unfriendly to first see the text on screen, and the hear the speech 1 second later.
MPAL was very very basic. I actually didn't have a clue how to properly code a VM with bytecode and stuff, and I didn't have *any* proper compiler theory training, so in retrospect it's amazing I even managed to parse and compile files. So basically MPAL can only assign to variables (which are all globals, plus a weird namespace thingie for locality), call "custom functions" (aka C++ code stored in a pointer table) and do basic arithmetic. That's it. Not even a proper language, isn't it? :) No loop constructors, no ifs, no jumps, nothing. So MPAL was a collection of flat routines, each one associated to a specific verb (action), specific object (eg. door), under a specific condition (eg: when open, that is when global variable room1_door_open==1). Since you couldn't have conditions *within* a MPAL routine but only to select *which* routine to run, you can see that cut & paste was a useful tool for scripters :)
In fact, we didn't evolve MPAL much during the main game development. We basically went with what we had on the DOS version, and we were using the same compiler/linker binary for months/years like we had no source code for it. In fact, having written most of it in 1996 (2 yrs before), with zero experience on writing compilers, it was kind of "magical" in my eyes that it was somehow working, and I was almost scared to touch it, let alone refactoring. I remember that, near the end of development, the scripts hit some internal hard-coded limit of the compiler (say, too many total variables), and I was terrified to simply open the project in Visual Studio, bump that limit, and recompile everything. In retrospect, I think it was more of a psychological thing, since the compiler worked wonderfully for the whole development and did its job.
There were no actors in MPAL simply because the game didn't really require them, so at some point we decided to simply avoid implementing it and tweak the storyboard accordingly. The game designer, Stefano, wasn't very happy about it but we eventually found a deal and I simply added a way to run background tasks in MPAL (actually, through a custom verb "Idle", so not to modify the compiler!), to let actors at least chat and animate in background, but without ever walking. In fact, the game engine had already been designed for multiple actors in mind (this is why you have the RMCharacter class separated from RMTony), but there was nothing in MPAL, and of course development time is limited.
Given my ignorance of "advanced" programming techniques, I think I simply couldn't think of how one could execute a linear (blocking) piece of script code without recurring to multi-threading. So I think I didn't even explore alternatives to multithreading. Obviously multithreading programming isn't easy, so custom C++ functions, called from MPAL, were full of locking issues wrt to the main thread that redraws the screen. The game was developed under Windows 95 and in fact was released before Windows 2000 was out; on the NT kernel, the game didn't work too well and crashed often because of race conditions. I see that you debugged and fixed at least few those bugs, well done! Those simply weren't triggering on a 9x kernel.
Another issue with MPAL is that there's no way to skip cutscenes; I don't remember whether I couldn't think of a good way of doing it, or whether all methods I devised would require too much workload on scripters that were already quite full. I think it's my #1 technical regret when I see the game, and in fact I would quite love if you found a way to implement it now.
I think this ends my braindump of today. Feel free to ask questions of course.
Thanks again for your work!
My Blog: http://giovanni.bajo.it
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Scummvm-devel