Implementing stateless game NPC chat scripting using DLR
How would one implement stateless game NPC chat using the DLR - i.e IronPython?
Stateless means something like this:
npc.AddText("Are you dead?")
playerIsDead = npc.GetYesNo()
if playerIsDead:
npc.AddText("You can't be dead!")
npc.SendOk()
else:
npc.AddText("Okay.")
npc.SendOk()
npc.End()
Instead of:
def Talk(state, action, input):
if action == -1:
npc.End()
elif state == 0:
开发者_JS百科 npc.AddText("Are you dead?")
npc.GetYesNo()
elif state == 1:
if input:
npc.AddText("You can't be dead!")
npc.SendOk()
else:
npc.AddText("Okay.")
npc.SendOk()
npc.End()
See the difference?
I've thought of one solution: Use one thread per NPC conversation, and AutoResetEvents or something like that. Not feasible because in a real life situation, there can be many NPC conversations (hundreds, if not thousands) going on simuntaneously. Do not want a few thousand threads.
Another way is to have the GetYesNo() and other methods not return anything, and instead simply send the dialog packet to the client, and somehow pause/block/suspend the script. Then, when input is received, it is put in a constantly named variable "input" or so in the ScriptScope.
The only problem is, in this case, how does one block the script, without having a dedicated thread per script?
I know it is doable in C++ with Lua, by having e.g GetYesNo simply send the script, and call lua_yield. When input is received, one of the lua_push (e.g. lua_pushinteger) methods are called, followed by a call to lua_resume.
Also, does anyone have any better solutions?
Thanks.
If IronPython has support fpr PEP342 (coroutines via enhanced generators) you could use those for your scenario: http://docs.python.org/whatsnew/2.5.html#pep-342 (e.g. yield on npc.GetYesNo()
and send the value back into the generator and continue from there).
精彩评论