Quasar
Moderator

Posts: 2178
Registered: 08-00 |
I'm here to talk about scripting, and why it remains such a problem for Doom ports in general, what the specific needs for Doom scripting are, and how they could be solved.
Scripting is widely recognized as an absolute necessity in modern game engines, where the programmers' time is not best spent attempting to anticipate every need of the map designers and reorganizing internal workings for level-specific hacks, as was a frequent practice in the old days.
Doom has been plagued since day one with the search for a suitable scripting language - one that would be capable of not just providing a toy interface to a small set of line specials and built-in functions, but one that could be used to actually replace parts of the native game code. We have seen many attempts, including ACS, FraggleScript, RTS, et al. But none have reached this goal so far, and all have been developed or maintained in isolation with no goal of generating reusable components.
In order to achieve this goal, the language and its runtime environment would need at minimum to meet the following requirements:
1. Its representation should be textual, and therefore widely portable. Compilation should be done at load time, or just-in-time. Including bytecode in WAD files should not be required. This in turn requires the compiler to be relatively compact and self-contained, so that it may be easily embedded in the host program.
2. It should be capable of compiling code fragments, allowing a "code-anywhere" approach. This would enable embedding of scripts inside other established input languages (ex: EDF). The compiler and virtual machine must both be capable of functioning on data buffers, and not be built to specifically use disk files or certain types of archives (wads, zips, etc.).
3. It should have a simple and efficient binding to the C language. Calling a C function from the scripting language should involve the provision of a name/function-pointer pair to the interpreter. Calling a script from C should involve passing a name or numeric index along with argument data to the interpreter. It should not involve low-level bothers such as stack manipulation through dozens of function calls, which is both difficult to use and extremely slow.
4. The virtual machine must be capable of saving and restoring state, both by sleeping scripts and by providing access to all internal registers and memory segments for purposes of serialization to disk file.
These four basic tenets of functionality are amazingly met by virtually no extant scripting languages, Doom-specific or otherwise. ACS fails two out of four. Lua fails two out of four. Small fails three out of four.
A large majority of modern scripting languages have evolved into application-domain languages, meaning they are no longer suitable for embedding at all. Their compilers are huge, they require installation of a runtime package on the user's system in order to function, and their standard libraries are incapable of being sandboxed in order to prevent users from doing damage to the system (malicious wad files, anyone?).
On the other end, we have "garage" languages designed by hobbyists because they felt like testing their mettle at language design. These are typically easily embedded (like Small), but are plagued by deep design issues and severe compiler bugs. The lack of people actually using these languages means that they have scant been tested. Stability is a foremost requirement, so these languages fail to contend.
From where I stand, I cannot see a solution to this issue. Even if we as a community were to work together, there is little guarantee that would produce a language meeting these criteria which would be well-designed and stable. Compiler writing is one of the more difficult tasks in programming, typically tackled only in graduate classes and even then at a largely useless theoretical level - finding actual practical, reusable ideas for implementation without simply examining the source of an already-existing compiler is almost impossible.
I myself have done extensive research, and my best effort to date has only produced a very basic recursive descent parser for expression evaluation. My knowledge of the process of code generation is nearly non-existent, and remains the primary roadblock for the Eternity Engine.
I'd like to see ideas getting thrown around just the same, however. I think we all stand to benefit from an open process of discussion on the matter, rather than a lot of independent efforts all trying to do the same thing behind closed doors.
|