My role in the games industry is “supposed” to be an AI expert. But since the year 2000, I have built three scripting languages for three companies. This article looks at my experiences doing so.
In 2000, I wrote ICE for 3DO. It was a traditional game scripting language. Key virtues were its built-in support for game programming (events, timers, script multi-tasking, save & restore) and its ability to intermix compiled and hot-loaded interpreted scripts.
In 2005, I wrote HIPE for Radical Entertainment. It was a real-time Hierarchical Task Network planner language specifically for next-generation game AI.
In 2006, I wrote FLIRT for LimeLife. With cell-phones coming in various screen sizes and flawed operating systems and some using J2ME and others using BREW, porting applications is a nightmare. FLIRT allows you to write your application once and run it on all these platforms with almost no additional porting work.
The question really comes down to: do you make common library routines accessed via an API to your existing programming language, do you buy (or use free) existing software, or do you build it yourself?
An API is suitable when you are a programmer (no fear of coding), and when the library routines are relatively independent areas of code. It is NOT suitable for non-programmer scripters or for when you really need an entirely new runtime system model.
Scripting allows you to express what you want the game to do with less code and often with less-skilled personnel. Rapid development is usually the main reason for a scripting language which incorporates into the language those things most commonly done and usually has a simpler syntax requiring less typing.
Scripting lets you create a virtual machine within your game, where scripter’s code can be executed much more safely than real code. This reduces engine complexity and allows you to share significant debugged code across multiple projects. In particular you can normally control memory management automatically so that scripters need not concern themselves with that sinkhole.
Scripts can often be hot-loaded, speeding up the compile, load, debug cycle.
Existing languages allow you to ramp up faster, take less maintenance, have better documentation and often come with significant libraries of pre-existing code.
Writing a scripting language is a significant undertaking. Management should definitely try to make you NOT do it. You have to create a translator, a run-time system, documentation, regression test code and build scripts. You have to train people to use it. Then there are tools. Tools, tools, and more tools. If it takes you a lot longer to debug script code than normal code, you are losing your rapid coding advantage.
Here are the size comparisons (in code lines) of the three systems I built:
The runtime system of FLIRT is largest, because it encompasses both scripting and screen layout. Its translator is smallest because FLIRT started life entirely without a translator almost as an assembly language and so its translation needs are simple. (It performs a lot of validation at runtime when running on a phone emulator). To run under BREW, FLIRT requires a second runtime system (not shown).
I can’t really say if documentation turns out to be of a similar size because it makes sense that way or merely that I become exhausted after a certain point.
HIPE was a contract project, so I know it took five months of full-time work. ICE and FLIRT were both written as an employee and doing other tasks as well, so it’s hard to know how long they really took to build, but 4-5 months is a reasonable guess of how long it took to build the J2ME version of FLIRT.