Dialog and event programming

Started by
4 comments, last by elle_lawliet 12 years, 2 months ago
Hi!

I'm making a 2D game with C++/DirectX 9 (I decided not to use a Game Engine). It's similar to old RPG games.
I need to program the dialogs and events in the game. I've looking info and it says a good way to do this is using Script language Lua. I have a little knowledge about scripting, but my real question is: how do I implement this?

for example:
NPC 1 moves to NPC 2
NPC 1 says: "It's cold today"
NPC 2 answers: "Yes"
NPC 1 ....
....


It's like a cinematic, you only see the character chating and moving until they finish.

If you had an example of this, it would be great. If not, please explain to me how I can implement this in Lua.
Also show messages, move a character and load scenario are implemented in C++

Thanks for your time.
Advertisement
I can't show you details since they depend a lot on how you approach the scripting.

For the cinematic stuff you need a way to pause the script and resume it at a later time. The key here are coroutines. You need to run a Lua function with coroutine.start. Once the script want's to pause it calls coroutine.yield. With a call to coroutine.resume (and the handle of the function passed in) the script continues where it left off. You can even pass values back and forth (useful for timed waits).

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

In a cinematic the timing of occurrences is pre-defined. This can be modeled using a timeline (perhaps with several tracks) where occurrences are initiated when the time passes the occurrence's starting time. The duration an avatar needs to approach a position, the time a player has to read a text, the time a sound playback requires until its end, ... all is scheduled.

However, what happens if an obstacle has been rolled into the planned way the avatar has to move to position A? So it has to detour, resulting in a longer walk duration. How to balance the time a slow reader needs to read a text compared to a fast reader? Here I want to hint at some "press space to onward" for the reader in a hurry.

Using wait() for some time means to set occurrences not on absolute moments but relative to a previous one. This is a first step making things more flexible. But, as shown above, sometimes its better to have some kind of wait() besides the time based one, and to be able to wait() on several events in parallel. E.g. when the avatar reaches a trigger volume, the belonging event is used to let the NPC greet. If the player hits space OR the maximum wait time has elapsed then the NPC starts to talk. Even better, when the avatar reaches position A in time then the NPC greets, otherwise it gets impatient.

I usually prefer a data driven approach instead of hardcode things, but scripting with co-routines is probably a task which costs less programming effort. However, as can be seen from the description above, the logic that drives the co-routine invocations then perhaps has to be more elaborate.
Thanks for your answers.

I understood I need a function to stop the scrip until the player press a button. I was thinking not to stop the game, to make the player pay attention. However, I'll keep that in mind.
I have other questions, maybe because I don't know much about scripting:
For example, I have a C++ class called Character. If I want a new Character, I call the constructor.
If I want the Character to move, I call char->move();.
If I want to draw the character, I call char->draw();
Do I need to access this Character class from the script, or do I need to create an object of this class inside the script (don't know if it's possible). Is this done in some other way that I don't know?

I've looking information about scripting, but it's too general or incomplete.

I understood I need a function to stop the scrip until the player press a button. I was thinking not to stop the game, to make the player pay attention. ...


This is the truth, but only the half of it. In fact the game runs at some frames per second. Any action (especially of a cinematic kind) shown by avatars on the screen lasts significantly longer than the duration of a single frame is. So a script that controls the action needs to run longer than the time slot is it is allowed to run during the current frame. This means that you need a way to pause the script again and again each time after its task for the current frame is done, until the script terminates in the end.

Endurion mentioned co-routines above. Co-routines are a way that allow you to do exactly that: Pausing the script at defined points in their execution, giving control back to its invoker, and to continue the script where it has paused the previous time. So co-routines are fine for what you want to do. (Think of the other way: A small script for each frame of the action would be a mess.)

However, co-routines don't unburden you from having a logic to just continue the script. And this logic is required to handle several situations like
* continue the script unconditionally,
* wait for a given time (event) before continue,
* wait for a trigger (event) before continue,
* wait for more than a single event,
* ...
and all this depends on the action script that is executed.

If the scripting language is able to return multiple values when pausing, then the data to tell the invoker what / when to do next can be given directly from the inside of the action script. That would obviously be a closed solution.


I have other questions, maybe because I don't know much about scripting:
For example, I have a C++ class called Character. If I want a new Character, I call the constructor.
If I want the Character to move, I call char->move();.
If I want to draw the character, I call char->draw();
Do I need to access this Character class from the script, or do I need to create an object of this class inside the script (don't know if it's possible). Is this done in some other way that I don't know?
...

This depends on the scripting language in use. AFAIK Lua is able to bind to C++ objects and routines, so that you can invoke them from inside a script.
I have just found a short tutorial that explains the basics about making c++ objects inside a Lua script. I will use that and the advices you gave me. I think I will wait for a short moment with a function and then continue the script execution. However, I think I will not wait until the player press a button becouse I want to make the dialog more dynamic.

Thanks for your help =)

This topic is closed to new replies.

Advertisement