17
\$\begingroup\$

I am developing a simple game engine (in C#, if it matters), and I can't think of a decent enough way to implement scripting in terms of architecture.

It's a simple turn-based strategy with custom, logic-independent animations for battles. It has a global architecture layer for system/low-level stuff and, most importantly, two main modules - logic and game-view thingy - that communicate using an event manager.

And the thing is, I would really like to have the scripts influence both stuff related to the game logic (changing unit parameters, etc) and stuff related to the game-view, such as special animations/dialogues for battles that might depend on a certain scripted trigger.

(To be honest, ideally I want the script to control the game flow, leaving only the core mechanics/graphics to the logic/view, but I'm new to this, so I'm not sure I can do it right now)

I've been thinking of three options:

  • Just let the scripting live in the logic, but let it know about the graphical side of the game. But this would make the logic/view division very vague, won't it...

  • Make the scripting a separate module that will exchange events with the others using the same event manager. But this would require to be very careful about event synchronization, I guess... and also add a whopping lot of event types to the manager. (Still, personal favorite)

  • Make the scripting a module above all, so it can directly influence/call functions of the logic/view. This allows for an inherently wider functionality at the cost of sort of screwing the entire event exchange scheme and being afraid that the script can break stuff even when it really shouldn't.

So, I can neither decide on one of these nor think of a better way to insert the scripting module... Any suggestions or useful links?

Thank you!

P.s. thanks for migrating the question, didn't know there was a specialized section for gamedev

\$\endgroup\$
1
  • \$\begingroup\$ What problems do you have that introducing a scripting language will solve? \$\endgroup\$
    – munificent
    Commented Aug 2, 2011 at 0:50

4 Answers 4

3
\$\begingroup\$

I believe you want the third option but you will find that you are right in your thinking that having logical events happening in potentially two locations a bad thing. You will find that you want the logic module of the engine to end up being an update tick that asks two questions 'What do I do now?' and 'How do I do that?' which you can then bind scripts to for handling answering those questions.

Couple this with exposing the objects that contain the data and an API to access required Logic components (I mean you could script a the AI Path finding, but since that is a generic piece of code that is likely to be used and reused, why not embed it in the module and then add it to the API exposed to the scripting language?). This should give you the accessibility as well as the clearly defined locations where things are happening.

Again, I caveat this with the same statement I always do. A finished working product is always more valuable than a good theory in programming :)

Hope this helps!

\$\endgroup\$
2
\$\begingroup\$

Many tends to underestimate the powerful of dynamic languages thinking that such flexibility comes at cost of speed; This is true but often the cost is simply negligible.

Personally I tend to develop as much as possible using dynamic languages ​​exploiting the expressiveness and then I profile the prototype to understand where and if optimization are needed.

In your case this means that you should try to move toward the third option, developing the "higher" part using a suitable dynamic language that you can use as scripting language too.

A lot of patterns can be used after you place the dynamism at the right depth. Your custom scripts can be integrated in an event based system as a callback system, when the core calls back it can provide a suitable environment so the script can alter the global status or just the state of a subset of the whole system.

You can encapsulate the interface you script can interact by using the Façade pattern. In the façade methods you can put the logic that defines how, when, if the script can use a functionality and abstracting the script interaction from the core implementation.

Your script interface should provide the relevant factory methods so the script can generate elements without instantiate them directly; these instances can be wrappers over the real objects so further control access logic can be implemented.

\$\endgroup\$
1
\$\begingroup\$

The scripting object needs to have access to the other objects it will provide data for. Be careful not to pass those other objects directly into the scripting object. Do so creates a brittle interface. You might want to have something like a mediator class that manages those object references and provides data access to the scripting object.

\$\endgroup\$
1
\$\begingroup\$

Lua is a popular choice for a general purpose scripting language. You can create your own scripting language using Lex and Yacc (check out the article in Game Programming Gems 3) but I would say most of your needs could be taken care of with Lua no matter how big or small.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .