Okay, so, every now and then I get a weird idea in my head and I sort of start testing the waters on a new project. This month’s crazy idea appears to be a JIT-ed scripting language similar to UnrealScript. The recent development on FE’s entity system has been fairly majorly influenced by Unreal; I’ve done a lot of reading of the Unreal Wiki. But it would be very nice to have a clean, fast, safe language with builtin persistence and network replication capabilities, rather than having to kind of ‘bend’ C++ and Python to work with me on those points. (Believe me, there is a lot of bending involved.)
Of course, the problem is that it would take freaking forever to actually make something like that, let alone test it properly and hook it up to any kind of game engine. Luckily for me there are some pretty good tools like ANTLR (which is basically similar in purpose to Flex and Bison all in one) and LLVM (a ‘compiler infrastructure’ that basically means I get JIT for nearly free.) So really I just need to write the “middle end” of the compiler — turning a syntax-tree-like structure into an intermediate representation to send to LLVM. Then, of course, there’s the need for a basic standard library for the thing, and some way of connecting it to existing C++ code… oh well, I don’t expect it to be finished anytime soon anyway.
As for the language itself, the current plan is to lean towards the static rather than the dynamic. This lets it make use of JIT fairly well and means scripts can be very fast; think along the lines of C# or Java for a basis. LLVM even supports SIMD code generation (although I haven’t tried it yet), so potentially vectors and quaternions and matrices and so on could be quite quick to compute with. Additionally, I would like to try to take a whack at solving some of the common issues with creating a game from the language-level. The list of potential candidates is pretty long, but it includes things like:
- Objects are persistable “by default” — e.g., you would mark a class member variable to NOT save it, rather than have to mark it for saving. Same goes for networking exposure. The language runtime would have builtin support for saving whole trees of objects to and from file or replicating over the network live (probably using enet.)
- Powerful concept of “defaults” for a class, so as to avoid needing to save or replicate most of the information in any class instance. Ideally, this includes “owned” class instances as well, so you could build fairly complex entities and only have to serialize a small amount of data to describe it. Additionally, a controller system for linking values to value-sources could be tied into this so values that are really generated anew each frame don’t need any kind of serialization.
- An event system that’s easy to use and interacts well with persistence & code modification. Basically, this means that the “normal way” of listening for an event is to create a block in the class body that specifies an event name and a member variable name. This means that you don’t have to explicitly add listeners for when you modify object references (it would do it for you), and you don’t have to serialize a list of listener objects like you would if the listener system was totally dynamic. You could change the code to listen for a totally different event from a member, and it would magically work when you reload a savegame.
- Sandboxing. Scripts should not only be isolated from causing any real damage, but they should also be instrumented to avoid code-bombs like infinite loops, huge memory use, malformed scripts that blow up the parser, etc. This means you’re safe to download code from a server for multiplayer, which is very useful.
- An API for reflecting script code from C++. This would allow map editors to display the list of properties some type of class has for when you’re placing entities, or overlaying editing or statistics screens in realtime while playing the game.
- A code reloading system. Currently the plan for this is to do an in-memory ‘save point’, dump the old code, load the new code, and restore the save point. If the load/save behavior is sane, then you could theoretically edit your code pretty close to on-the-fly as the game is running. Given that modern games usually have moderately annoying load-times, this could remove a big psychological barrier to debugging and testing.
- Ability to mark class member variables as “localizable” (like UnrealScript *whistle*.) Basically, this means that a certain variable would show up in a localization editor automatically. I would anticipate this would mostly get used for strings, but I suppose one could localize all sorts of things.
- Another UnrealScript copycat: config variables, which act like static class variables whose values are tied to configuration files.
- Unicode strings from the get-go. This is a giant pain in the ass to change if your code doesn’t start off with it.
- “First-class” vectors, quaternions, matrices, and a nice standard math library. This stuff is so common that there’s no reason for it to keep getting re-coded.
- A source-level debugger would be nice, but that is a big project in and of itself.
So, yeah, I’m pretty much insane. I’m planning on slowly attacking it in stages — such as getting basic classes / functions / expressions done, and then moving on to adding the more cushy features like persistence, replication, events, code reloading, etc. And of course the real trick is remembering to focus on the more immediate things like school and Fallen Elements in the meantime.