Re: Dialog system : pausing script and resume on player's answer

Jason McKesson <[email protected]>
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <[email protected]>
On 1/17/2011 7:45 AM, Teto wrote:
> Hi,
>
> I'm trying to create a dialog system for a game with the possibility
> of choosing between different answers (there might be more than 2
> answers)
>
> =========================
> local speech = createSpeech("Welcome to the tutorial ! Do you want to
> skip it ?");
> speech:addAnswer('Yes',1);
> speech:addAnswer('No',0);
>
> -- answerValue could be either 1 or 0
> local answerValue = MainState:showMessage(speech);
> if(answerValue == 1) then
>        -- Player wants to skip tutorial
> else
>        -- we create new dialogs ....
> end
> =========================
>
> showMessage() is a C++ function that changes my C++ state machine to
> the dialog system. I would like showMessage() to pause the script when
> called. I would like the script to resume when the player answers the
> question and return his answer (an integer, retrieved in the example
> in "answerValue") possibly from a different function than
> showMessage() (C++ function onAnswer() for example).
>
> Then on the lua side, I will create  matching dialogs.
>
> What is the best way to achieve this (if possible with luabind) ? I've
> tried using the yield policy:
>      luabind::class_<CSinglePlayerState>("CSinglePlayerState")
>          .def("showMessage",&CSinglePlayerState::showMessage, yield)
>          ,
>
> but I get the error "Attempt to yield across metamethod". Do I
> absolutely need to create a thread ? (I would like to keep things
> simple).
>
>
> Let me know if things are unclear or if this would be best asked on a lua forum.
>
> Matt
To me, it's all a matter of what your answer to this question is: who's 
supposed to be in charge?

When using Lua as an embedded scripting language, I generally prefer 
that C++ is in charge. So, if I were doing something like this, each 
line of text in the dialog would be a Lua script. C++ would call that 
Lua script, and the script would tell it what string to show, what the 
possible answers are, and what dialog script to show for each choice. If 
the Lua script needs to be called after the player answers, then there 
would be a place for such hooks.

So rather than the Lua script telling C++ to show some text, the C++ 
system ask Lua what the current text and such are. The Lua script would 
return an object containing the text to show, the options to display, 
and what to do for each option. It would be up to C++ to do the 
equivalent to "MainState::showMessage()" call.

This coding style makes it highly unlikely to ever need to yield in the 
fashion you're needing to.

However, if you're adamant about doing things this way, then you should 
have a two-phase version of "MainState::showMessage()" There should be 
two C++ functions: showMessage and getUserReply. When you use them in 
Lua, you yield between them, with the understanding that C++ will not 
resume the Lua thread until the reply is ready:

======
MainState:showMessage(...);
thread.yield();
local answerValue = MainState:getUserReply();
======

You can even encapsulate this into a single Lua function.

However, in order for this to work, your Lua script needs to be in a 
coroutine. That's what they're for.

------------------------------------------------------------------------------
Protect Your Site and Customers from Malware Attacks
Learn about various malware tactics and how to avoid them. Understand 
malware threats, the impact they can have on your business, and how you 
can protect your company and customers by using code signing.
http://p.sf.net/sfu/oracle-sfdevnl
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.