2010-11-15 38 views
1

如何使用DLR实现无状态游戏NPC聊天 - 即IronPython?使用DLR实现无状态游戏NPC聊天脚本

无国籍意味着这样的事情:

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() 

相反的:

def Talk(state, action, input): 
    if action == -1: 
     npc.End() 
    elif state == 0: 
     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() 

看到区别?

我想过一种解决方案:每个NPC对话使用一个线程,以及AutoResetEvents或类似的东西。不可行,因为在现实生活中,可能会有许多NPC对话(数百个,如果不是数千个)同时进行。不想要几千个线程。

另一种方式是让GetYesNo()等方法不返回任何东西,而不是简单地发送对话框包到客户端,并以某种方式暂停/块/暂停脚本。然后,当接收到输入时,它将放入ScriptScope中的一个不断命名的变量“输入”中。

唯一的问题是,在这种情况下,如何阻止脚本,而不需要每个脚本都有专用线程?

我知道它是可行的在C++和Lua,具有e.g GetYesNo只需发送脚本,并调用lua_yield。当收到输入时,调用其中一个lua_push(例如lua_pushinteger)方法,然后调用lua_resume。

此外,有没有人有更好的解决方案?

谢谢。

回答

1

如果IronPython支持fpr PEP342(通过增强型生成器的协同程序),您可以将它们用于您的场景:http://docs.python.org/whatsnew/2.5.html#pep-342(例如npc.GetYesNo()的收益并将值发回生成器并从那里继续)。

+0

对不起,我unaccepting的答案,因为它并不完全回答这个问题得出结论; IPY可能支持PEP342,但它似乎没有通过其托管API公开它。 – angelsl 2011-12-30 15:23:13