Scripting - DLL/C/C++ vs tradional scripting language

Started by
7 comments, last by Shaarigan 6 years, 5 months ago

Hi!

I'm toying with different ideas about how to script game logic. I'm well aware of different scripting languages, and note that most games use these to define game logic.

But what about using C/C++ in DLLs to script a game?

For simplicities sake, lets assume I'm just writing quest logic. Why not just create a metafile that lists all quests. The main .exe loads this list (and creates a bunch of function pointers) and then programmatically queries a bunch of DLLs for the game logic. My idea is to create a bunch of DLLs (for example DLL1.dll, DLL2.dll, DLL3.dll etc.) and resolve the function pointers from last to first (DLL3.dll to DLL1.dll), which allows code in higher numbered DLLs to supersede existing code in lower numbered DLLs. New code would be entered into higher numbered empty/nearly empty DLLs until finalised, and then be moved into DLL1.dll. This allows for very short compilation times, with the advantage of fully compiled logic.

This seems so simple I'm sure I must be overlooking something!

Does anyone have any views on my approach, especially it's short fallings?

 

Advertisement

There's nothing wrong with using DLLs and writing it in C++. In fact, this is the method that is used in HL and HL2 for modding purposes.

 

Some things to be aware of: Hot reloading gets harder, you still have to deal with all those DLLs, you have to have a mechanism to detect when a new DLL is ready to be loaded, and then do the "swapping." You also have to figure out what you're going to do with all of the existing loaded objects from the DLL you desire to replace. All of these are solvable problems, they just require some level of effort to implement.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Thanks for your reply!

My idea is to have a single function to resolve all DLL entry points (say for each quest in the metafile an OnStartup, OnGameTick, OnShutdown, for example) and another function to release them, allowing real time (ish) editing. For example, F11 could trigger game->pause/UnloadDLLs and F12 could trigger LoadDLLs/game->resume. This seems to provide all the benefits of a traditional scripting language with the performance of a compiled DLL. By having multiple DLLs each may only contain a few hundred lines of code meaning recompilation would be very fast.

Unless your DLLs contain nothing but pure logic code, that's not really going to help much, honestly.

Unloading then reloading everything isn't really going to improve your iteration times. Plus for any decent amount of code, you'll eventually find that linking will simply be more expensive (and your DLLs are going to have dependencies, you'll end up with dependencies all over).

If you really want to break things up for this purpose, it would be better to break it down into different modules that you can reload at runtime. You still have problems though, such as tracking all the different objects from a DLL that have been allocated, and then releasing those. Persisting their state in some manner, perhaps by breaking apart data and code or using some sort of fixup mechanism. Even with a fixup mechanism you have to deal with data versioning, as the changes applied to a DLL might very well be to add a new field.

Breaking up each individual bit of gameplay into a bunch of different DLLs will be hell to maintain, you'll end up with versions all over the place, you'll have to manage tracking of the different pieces and ensure that you don't end up with compatibility conflicts when dependencies change. Honestly, for something like gameplay logic... putting it all into one DLL would be fine. Alternatively, scripting solutions work just fine, and there's really no reason to not use them.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

I have read about this topic (not scripting but hot swapping) of code when researched for my meta system in the game engine. As meta types (RTTI) opens capabilities to get every time every information about objects, you are capable to query those from a DLL implementing your meta system and so get information about the consistency of those objects contained. Could help in development of large games to reduce compile time but I wouldnt suggest this for scripting-

Scripting differs from compiled code in the less strict binding that assemblies have offering a lot of flexibility. A game designer does not want to work in a Visual Studio project to get his gameplay made but wants to immeadtly test it without huge compile time just by fireing into the engine and see what happens. Design tools like Articy:Draft are used these days and visual scripting replaces traditional LUA in some development teams.

At least a scripting runtime is no more than a VM these days making calls into your code by previously defined functions that are dynamically bound to it (what is another benefit over fixed code) and running nearly as fast as an emulated OS (using Virtual Box or similar)

As someone deploying runtime dll reloading in my game, I just use a single dll for the more 'data' oriented parts of my code (ie. Ability logic code), and store them as 'definition' structures. I avoid using classes in my dll, and whatever memory I need is done on the main executable. 

You might think that having multiple dlls may help compilation, but you'll more likely be slowed down trying to maintain code across dll boundaries. Keep it simple, stick to 1 dll until you have a valid reason to move to another dll.

7 hours ago, Mk_ said:

Does anyone have any views on my approach, especially it's short fallings?

 

You might want to look into the Runtime Compiled C++ project...

I personally have not used this, but it looks really interesting and I'm thinking of using it for my current project when I get to the stage of trying to integrate scripting with my editor.  I dont want to use a "scripting" language, but it'd be nice to avoid the long compile/link times of writing the game code in the IDE along with everything else.

This seems promising.

@0r0d Seen this already on GitHub

May be usefull but I do not think it will get into the bigger engines except for editing something during development while you can trigger a compile on PC you cant on console systems so this is against the one-for-all-platforms philosophy the big player engines go for. Maybe there will be support in the future :)

Another option would be to go the Unity 3D way and embedd a mono runtime into your project additionally to the mono compiler

This topic is closed to new replies.

Advertisement