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

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Teto
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

------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

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

David Wolfe
> ... I get the error "Attempt to yield across metamethod". Do I
> absolutely need to create a thread ? (I would like to keep things
> simple).

I've had been wondering myself whether lua-coco
(http://coco.luajit.org/) can be used with luabind to circumvent such
restrictions?  Anyone have any experience with this?

------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

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

Jason McKesson
In reply to this post by Teto
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

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

Teto
I usually try not to call lua code from C++ so I think I will stick
with my way.I agree with the use of 2 distinct functions "showMessage"
and "getUserReply" embedded into a single lua function : I had seen a
similar answer during my researches on the internet.

> However, in order for this to work, your Lua script needs to be in a
> coroutine. That's what they're for.
My question would be how to create the coroutine (I am not that
familiar with scripting) ?
I would like to yield/resume from C++ so do I need to use
lua_newthread()  + lua_resume() / lua_yield ? is it equivalent to
creating a coroutine from lua ( thread = coroutine.create( fn) ).

What bothers me in both cases is that I need to embed the script into
a function (well I could do it) to start the coroutine. Isn't there
some kind of a global coroutine ? I mean when one does luaL_dofile(),
it executes many lua instructions sequentially like a coroutine would,
so why the need to give an initial function ?

Thx for your answer, it does clarify things for a beginner like me.



On Mon, Jan 17, 2011 at 9:59 PM, Jason McKesson <[hidden email]> wrote:

>
> 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
> _______________________________________________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user

------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

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

Nigel Atkinson-2
"coroutine.wrap" makes things quite easy, if you do most of it from the
Lua side.  There are some good examples in the Programming in Lua book,
which you can read the first revision at http://www.lua.org/pil/  Chapter
9 is the one your after. :-)  At any rate good stuff to know.

As far as whether Lua or C++ is in charge, regardless of being embedded or
not, I think it's more important to be consistent.  Either approach works
well.

Nigel

On Tue, January 18, 2011 8:50 am, Teto wrote:

> I usually try not to call lua code from C++ so I think I will stick
> with my way.I agree with the use of 2 distinct functions "showMessage"
> and "getUserReply" embedded into a single lua function : I had seen a
> similar answer during my researches on the internet.
>
>> However, in order for this to work, your Lua script needs to be in a
>> coroutine. That's what they're for.
> My question would be how to create the coroutine (I am not that
> familiar with scripting) ?
> I would like to yield/resume from C++ so do I need to use
> lua_newthread()  + lua_resume() / lua_yield ? is it equivalent to
> creating a coroutine from lua ( thread = coroutine.create( fn) ).
>
> What bothers me in both cases is that I need to embed the script into
> a function (well I could do it) to start the coroutine. Isn't there
> some kind of a global coroutine ? I mean when one does luaL_dofile(),
> it executes many lua instructions sequentially like a coroutine would,
> so why the need to give an initial function ?
>
> Thx for your answer, it does clarify things for a beginner like me.
>
>
>
> On Mon, Jan 17, 2011 at 9:59 PM, Jason McKesson <[hidden email]> wrote:
>>
>> 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
>> _______________________________________________
>> luabind-user mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/luabind-user
>
> ------------------------------------------------------------------------------
> 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
> _______________________________________________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user
>



------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

tostring() operator outside class?

Kristoffer Danielsson
Consider this:
 
,
luabind::class_<Test>("Test")
.def(luabind::tostring(luabind::const_self))
 
ostream& operator << (ostream &os, const Test &test)
{
    os << test.value;
    return os;
}
 
Is it possible to NOT have this friend operator of class Test and map it in another way? Something like this:
 
,luabind::class_<Test>("Test")
.def(luabind::tostring(test_tostring_operator))
 
void test_tostring_operator() { blah }
 
 
Thanks

------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: tostring() operator outside class?

Nigel Atkinson-2
I sometimes do this.

....
.def( "__tostring", &testToString )
....

std::string testToString( const Test* t )
{
    return std::string( 'An instance of test.' );
}

Returning a "const char*" instead works too I think, but I'm not 100% on
that.

HTH

Nigel

On Tue, January 18, 2011 10:49 pm, Kristoffer Danielsson wrote:

>
>
> Consider this:
>
> ,luabind::class_<Test>("Test")
> .def(luabind::tostring(luabind::const_self))
>
> ostream& operator << (ostream &os, const Test &test)
> {
>     os << test.value;
>     return os;
> }
>
> Is it possible to NOT have this friend operator of class Test and map it
> in another way? Something like this:
>
> ,luabind::class_<Test>("Test")
> .def(luabind::tostring(test_tostring_operator))
>
> void test_tostring_operator() { blah }
>
>
> Thanks
> ------------------------------------------------------------------------------
> 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_______________________________________________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user
>



------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: tostring() operator outside class?

Kristoffer Danielsson
Ah, thanks a lot! :)
 
> Date: Wed, 19 Jan 2011 09:57:51 +1100

> From: [hidden email]
> To: [hidden email]
> Subject: Re: [luabind] tostring() operator outside class?
>
> I sometimes do this.
>
> ....
> .def( "__tostring", &testToString )
> ....
>
> std::string testToString( const Test* t )
> {
> return std::string( 'An instance of test.' );
> }
>
> Returning a "const char*" instead works too I think, but I'm not 100% on
> that.
>
> HTH
>
> Nigel
>
> On Tue, January 18, 2011 10:49 pm, Kristoffer Danielsson wrote:
> >
> >
> > Consider this:
> >
> > ,luabind::class_<Test>("Test")
> > .def(luabind::tostring(luabind::const_self))
> >
> > ostream& operator << (ostream &os, const Test &test)
> > {
> > os << test.value;
> > return os;
> > }
> >
> > Is it possible to NOT have this friend operator of class Test and map it
> > in another way? Something like this:
> >
> > ,luabind::class_<Test>("Test")
> > .def(luabind::tostring(test_tostring_operator))
> >
> > void test_tostring_operator() { blah }
> >
> >
> > Thanks
> > ------------------------------------------------------------------------------
> > 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_______________________________________________
> > luabind-user mailing list
> > [hidden email]
> > https://lists.sourceforge.net/lists/listinfo/luabind-user
> >
>
>
>
> ------------------------------------------------------------------------------
> 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
> _______________________________________________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user

------------------------------------------------------------------------------
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
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user