玩得乐此不疲 成功了个ChatGPT趋动的游戏

当天给大家带来一篇《便捷成功一个ChatGPT驱动的游戏》文章,来自知乎@九号(已授权)。

往年四月份读了斯坦福Generative Agent的论文,觉得特意好玩,花几天时间成功了这个demo。起初拿着这个demo去参与hackathon,居然拿了二等奖还帮我赢了1300多刀。

最近提到这个demo,共事示意很有兴味,于是细心整顿了一下,分享给大家。

知乎::

0.让LLM驱动游戏能够处置什么疑问?

游戏界有一种说法:过去20年的游戏在外围玩法上的翻新是缓慢的,绝大少数的翻新出当初技术上。

开发者在游戏内提供更大的地图,更粗劣的画面,庞大的细节。其中的关键目的之一是为玩家提供 「沉迷感」 。当玩家在游戏环球里失掉自己所希冀的反应时,会取得庞大的满足感。

但是,因为技术的限度,过去的翻新并没有涉足游戏的一个外围方面:环球与NPC的运转逻辑。

当玩家与环球和NPC的互动超出了规定设定的领域时,玩家将不可取得反应,从而发生渺小的落差。游戏界成这种体验为Breaking Immersion。

过去的开发者使出了想方设法来防止玩家发生违和感。

以荒野大镖客2为例,因为R星将immersive作为其开发的首要准则,造成其破费了8年期间,为游戏环球减少了有数的逻辑与细节,整个开发破费近5.4亿刀,可见其难度与老本。

「大模型的遍及或者扭转这一现状」

大模型可认为游戏环球的运转与NPC的行为提供逻辑,协助游戏了解玩家的行为,让游戏环球在可信的形态下稳固运转。由此从基本上优化玩家的沉迷感。

1.详细点,将LLM用在游戏里须要几步?

咱们把LLM在游戏中的运行分为两局部:

World中蕴含:

Agent则包括:

2. 让LLM了解游戏环球与环境

为了让ChatGPT了解咱们游戏的环球观,咱们引入一段Prompt:

export const worldHistory =`你所在的大陆名为“大唐王朝”。这是一个神话与事实交织的环球。主岛上有五个关键的地点。最大的是“长安城”,是国度的政治、经济和文明中心,城墙之内有各种店铺和庙宇。接着是“五指山”,孙悟空曾被压在此山下。此外还有“草庙村”,“高老庄”和“女儿村”,这些中央都是唐僧和他的徒弟们在旅程中遇到的应战和冒险。东边的小岛上则是一个保密的佛教圣地,称为“灵山”,这是四人取经的终点。两个岛屿间有一座长长的桥梁,名为“通天河”,是由沙僧的金箍棒变动而成。`;export const worldKnowledge = "";

为了让NPC和玩家得以与地图上的地点/东西互动,咱们须要提供一切东西与地点的形容:

222: {description: `位于主岛的西北方缘。西面是汪洋大海,东面则是高原的悬崖。周围有几棵树和一片怪物出没的长草地。往南则是长安城的方向。`,mapId: 222,},254: {description: `位于主岛的西北方缘。东面是陆地,西面是高原的悬崖。左近有几棵树和常有妖怪出没的长草地。长安城就在北方。`,mapId: 254,},188: {description: `是高原上的森林区。森林里树木茂密,有几片怪物常出没的长草地。长安城就在北方。`,mapId: 188,},190: {description: `位于高原的一片森林中。你正站在一个保养得相当好的小木屋前。周围是茂密的树木和怪物常出没的草地。长安城就在北方。`,mapId: 190,},220: {description: `长安城,主岛上的城镇。`,mapId: 220,},.......

上述Prompts为地图的每个块都提供了文字形容,从而得以让ChatGPT了解地图上的每个地点:

完整地图

详细的成功里,咱们实践上须要为 「一切的游戏贴图」 都提供一段文字形容!

3. 让LLM驱动NPC

首先,咱们要让LLM知道他如今正在表演一个NPC:

export const npcSharedPrompt = `你正在表演“西游记”中的一个角色。这是一个2D的神话环球,玩家和你都可以在这片大陆上启动探求。你可以与其余的角色交换,如唐僧、孙悟空、猪八戒和沙僧,并与妖怪动员战役、观赏村庄或神庙、购置法宝或草药。在这个环球里,与妖怪的战役是旅程的一局部,但指标是取得真经,使环球充溢敌对。妖怪只管凶狠,但并不是相对的恶,与他们战役既是为了包全自己,也是宿愿能够教化他们。你的角色不知道事实环球的存在,只知道他在这神话的旅程中的使命。`;

接上去,咱们设计一系列NPC:

{id: 1,name: "唐僧",description: "唐僧,本名唐三藏,是中国古典小说《西游记》中的关键人物之一。他是一个决计剧烈、智慧和决计的僧人,登程去西天取经。",age: 40,starSign: "pisces",money: 100,items: ["jingwulian"],personalHistory: `你是唐僧,一个被派来从印度取经的僧人。你的义务是失掉佛教经文,将它们带回中国。`,personalKnowledge: "你知道你的三个徒弟:孙悟空、猪八戒和沙和尚。他们各自都有共同的才干和历史。",conversation: new ConversationModel(),startingPos: new Vec2(32, 38),upSprites: TypedAssets.spriteSheets.momup,downSprites: TypedAssets.spriteSheets.momdown,leftSprites: TypedAssets.spriteSheets.momleft,rightSprites: TypedAssets.spriteSheets.momright,}{id: 2,name: "女儿国国王",description: "女儿国国王是《西游记》中的一个角色。她是女儿国的统治者,对唐僧发生了浓重的兴味。",age: 35,starSign: "virgo",money: 500,items: ["elixir of life"],personalHistory: `你是女儿国的国王,你的国度只要女性。当你据说了唐僧的来到,你选择要与他结婚。`,personalKnowledge: "你知道唐僧是一个鄙俗的和尚,他正在启动取经之旅。",conversation: new ConversationModel(),startingPos: new Vec2(23, 47),upSprites: TypedAssets.spriteSheets.carolup,downSprites: TypedAssets.spriteSheets.caroldown,leftSprites: TypedAssets.spriteSheets.carolleft,rightSprites: TypedAssets.spriteSheets.carolright,},{id: 3,name: "牛魔王",....

每个NPC的外围在于:

人格驱使角色提供定制的对话

有时刻的对话甚至会自带旁白

成功NPC与玩家的互动 - 对话:

为了让ChatGPT给出定制的对话,咱们须要提供的包括:

const fullPrompt = generalContent + personalContent + currentState;

也就是:general - 环球观,personal - NPC的人格和记忆,current - 的游戏进展。

const generalContent = npcSharedPrompt + worldHistory + worldKnowledge;`

告知ChatGPT本次调用的义务,环球观背景等。

const personalContent = ` Your name is ${npc.name}, ${npc.age} years old, you have the personality of a ${npc.starSign}.You have ${npc.money} fictional dollars. ${npc.personalHistory} ${npc.personalKnowledge}${storySoFar}`;

提供了NPC的团体消息和人格(例如年龄,历史,常识),与NPC的记忆(storySoFar)

const prompt = ` ${timeMsg} at ${envDescription}, What would ${npc.name} say to 悟空? (Keep the response short and just the words your character says)`

的游戏期间,角色所在的位置等。

成功NPC与玩家的互动 - 举措:

content: `悟空 replies "${replyText}". What would you like to do?1: 让悟空跟着你,2: 你向他告别,3: 继续对话,Pick an action from the list above. respond with just the number for the action`,}];

咱们为NPC提供一系列可选用的上班,ChatGPT将选择NPC的下一步执行。这里的prompt雷同蕴含了位置,期间,对话历史等消息,但为了繁复暂略去。

这里ChatGPT让牛魔王率领孙悟空返回下一地点

成功NPC的记忆 - 让NPC记住和玩家的一切互动对话:

// summarize conversationconst summary = await this.summarizeConversation(conversation, endConversationText);
const updatedConversation: IConversationModel = {isActive: false,history: [...conversation.history, { msg: `Conversation summary: ${summary}` }],messages: [],};

在之前出现剧情之后,牛魔王依据记忆选用用「真经」来动员对话

与NPC的道具互动

问八戒要点饼子吃

防止NPC/玩家搞花活造成发生危险内容

这里咱们让ChatGPT来判别玩家/NPC的回复能否特意离谱,假设特意离谱则应拒绝正派回答!

private async validateReply(replyText: string, conversation: IConversationModel): Promise<ChatNumberResponse> {const promptMsgs: GptMessage[] = [...this.mapToGptMessages(conversation), {role: "user",content: `悟空 replies "${replyText}". Does his response make sense. On this scale of 1 to 5,1: Response is non-sensical,2: Response is immersion breaking or meta and acknowledging this is a game,3. Reponse is bad, unnecessarily vulgar for no reason based on the past conversation4: Response is all right, and something someone might say but unlikely,5: Response is good and mostly in context of the game world,how would you rate the response, give a one sentence reason why`,}];

想打听公家消息,门都没有!

其余还有很多细节,很难在这里展现一切的feature,欢迎检查代码。

总结

自己对LLM在游戏中的经常使用十分失望,这么便捷的demo我乐此不疲的玩了很久。从技术过去说,这个demo全体的框架还算比拟完整,很适宜在此基础上删删改改,试验各种agent的方法和prompt等。此外因为demo是用react成功,这里介绍大家观看2小时的react入门视频,从而无缝上手。

本文转载自​​,作者:

您可能还会对下面的文章感兴趣: