Using dlls as scripts?

Is it possible to write your game level/AI as dlls and then load/unload them as needed while your game is running? Someone told me it can be done, but I've never seen anyone teach it. So is it possible? Is it demoed in HMH?

Edited by Mór on
Mór
Is it possible to write your game level/AI as dlls and then load/unload them as needed while your game is running? Someone told me it can be done, but I've never seen anyone teach it. So is it possible? Is it demoed in HMH?

Well, yes, you *could*, but I don't think it would be a particularly good idea in most cases.

What HMH does is separate the entirety of the game-level code into a .dll. This gets you hot-loading with minimal effort. To do this for individual levels or AI scripts would involve some overhead, both during development and runtime, and wouldn't really earn you anything as the developer.

Where this *does* make sense is plugin support -- using separate dlls allows modders to link in new code without actually modifying your source. (Provided you detect and load them, of course.)
Here's a description of the implementation of a system like this in the Molecule Engine. It uses single file C++ code compiled into shared libraries as scripts instead of some scripting language like Lua.

Edited by Marc Costa on
That looks great.

Edited by Mór on
AFAIK in the Molecule engine small "scripts" are implemented as a small DLL to keep compile speeds for the script hotloading very low. In HMH the entire gameplay piece is compiled quickly, so pretty much the whole game can be thought of as a "script".

It would probably be a good idea to start using separate DLLs for separate "scripts" if compiling the rest of the game takes too long. This can be a good option if the rest of the game/engine was created in such a way that compile times are slow, but some kind of hotloaded-scripting wants to be added on after the fact. Some tools can also be made so that new scripts can be added or modified without a need to mess with the rest of the engine -- this can be good for designers or others not acquainted with the whole engine.

Edited by Randy Gaul on
As the developer of the Molecule Engine, I wanted to chime in to clarify things and make my intentions behind the scripting system clearer.

For me, long compile times were never the motivation for introducing the C++-based scripting system. I wanted to combine the advantages of interpreted script languages (hot-reloading, clear separation of gameplay and engine code) with the advantages of C++ (fast, native code, can link to and use the engine runtime without boilerplate/glue code, IDEs and good debugging tools).
That's why I came up with the system of using C++ as a scripting language directly, or build custom script tools on top of that.

As has been mentioned in this thread, every script is compiled into its own shared library (.dll on Windows). That makes compiling single scripts super-fast and allows for almost instant hot-reloading. In the retail build, all scripts are linked into the executable.
At the moment, a script is nothing more than an implementation of a base class with a few virtual functions. Scripts can use the engine runtime by either calling functions provided by interfaces (useful for designers/scripters), or linking to the engine runtime directly (useful for programmers).
How you want to use the system is up to you, and depends a bit on how the builds are set up.

A few numbers from the game we shipped last Thursday:
  • A single script takes 200ms to compile and hot-reload into the engine. This allows you to protoype stuff fast and change lines of text instantaneously, which was great for a narrative-driven game like this.
  • For The Lion's Song, I built a scripting system that mimics co-routines. Those additionally support rewind & fast-forward, which was great for development and testing. The co-routines were built on top of the basic scripting system.
  • Using this co-routine system, scripts do not look much like C++-code anymore. Scripts and dialogs are introduced using macros, and the script functions pretty much look like any other language. No references, pointers, templates, etc.
  • Scripts only ever access engine components and interfaces by ID, never by pointer.
  • There are 208 scripts in the final game. When compiled to .dlls, the script code takes about 2.5MB. In the final executable, the scripts add around 0.5MB to the executable.

Last but not least a few statistics regarding build times:
  • A fully optimized rebuild of the VS solution with 18 projects takes 65 seconds. That includes Core, Input, Audio, Video, 2D, 3D, all external libs such as LZMA, libogg, libvorbis, all tools such as the editor, content pipeline, and a localization tool, and the full game for Steam. Ever since I started working on the Molecule Engine, I paid close attention to build times.
  • The game itself builds in roughly 5 seconds, including Steam support, metrics, etc.

Hope that gives you a better idea of what my motivation was, and how things roughly work.
Shoot if you have more questions!