ゲーム開発の救世主:ChatGPTによるNPCセリフ自動生成システムを作ってみた

ゲーム開発のプランナーにとってNPCのセリフ作成は大変な仕事です。そこで、ChatGPTを活用して、NPCのセリフを自動生成する仕組みを開発しました。Google Spreadsheetと連携しデータ加工も簡単に行えます。
2023.03.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。ゲームソリューション部の出村です。 今回は、ChatGPTをゲーム開発で利用する例について紹介します。

セリフを考えるという仕事

ロールプレイングゲームを開発を開発している場合、ゲーム開発のプランナーにとって仕事の一つはゲームの世界観やストーリーを具現化するために、多くのNPC(ノンプレイヤーキャラクター)のセリフを考え出すことがあったりします。しかし、これは容易な仕事ではありません。例えば、一つのRPGゲームを作る際、町の住人が話すセリフをすべて考え出すことは、まるで海の底から一粒の砂を探し出すような大変さです。

そこで、この大変な仕事を助けるために、ChatGPTを使ってNPCのセリフを自動生成する仕組みを作りました。この仕組みでは、RPGのNPCである町の住人が話すセリフを自動生成できるようになります。生成する際に、人物像を指定できるようにしました。具体的には、性別、年齢、家族構成、性格、話すタイミングを組み合わせて出力できるように設定しました。その結果、組み合わせて大量のセリフが出力できるようになりました。

セリフを自動生成してみる

この仕組みは、Google Spreadsheetのデータを元にChatGPTを呼び出して作成しました。まず、スクリプトを用意し、データを用意しました。スクリプトからChatGPTのAPIを呼びだして生成しています。

今回使用したスクリプトは次の通りです。

const API_URL = 'https://api.openai.com/v1/chat/completions'
const API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const MODEL = "gpt-3.5-turbo"
const TEMPERATURE = 0.5
const MAX_TOKENS = 2048

const SYSTEM_CONTENT = "あなたはゲームに登場するキャラクターのセリフを考える人です。次の属性がある人と街の中で話すセリフを50文字以内で出力してください。"

function callChatGPT(prompt){

  const requestBody = {
    model: MODEL,
    messages: [
      {role: "system", content: SYSTEM_CONTENT},
      {role: "user", content: prompt},
    ],
    temperature: TEMPERATURE,
    max_tokens: MAX_TOKENS,
  }

  const request = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${API_KEY}`,
    },
    payload: JSON.stringify(requestBody),
  }

  const response = UrlFetchApp.fetch(API_URL, request)
  const responseText = response.getContentText()
  const json = JSON.parse(responseText)
  const generatedText = json['choices'][0]['message']['content']

  return generatedText
}

function generateDialogue() {
  const spreadsheet = SpreadsheetApp.getActive()
  const sheetByActive = spreadsheet.getActiveSheet()
  const outputSheet = spreadsheet.getSheetByName("output")

  let titleArray = new Array()  

  for (i = 0; i < 5; i++){
    titleArray[i] = sheetByActive.getRange(1,1+i).getValue()
  }

  let idx = 0
  let idxArray = new Array()  
  for (;idx < 0x3ff;){

    idxArray[0] = idx & 0x3
    idxArray[1] = (idx >> 2) & 0x3
    idxArray[2] = (idx >> 4) & 0x3
    idxArray[3] = (idx >> 6) & 0x3
    idxArray[4] = (idx >> 8) & 0x3

    var prompt = ""
    for (i = 0; i < 5; i++){
      prompt += titleArray[i] + sheetByActive.getRange(2+idxArray[i], 1+i).getValue() + " "  
    }

    Logger.log(prompt) 

    let answer = callChatGPT(prompt)
    idx += 1

    outputSheet.getRange(idx, 1).setValue(prompt)
    outputSheet.getRange(idx, 2).setValue(answer)
  }

}

今回はこのようなテーブルを用意しました。

データは1項目につき4つ、5項目を設定しました。これにより出力される総数は1024パターンとなります。Google Spreadsheetに出力されるので、その後のデータ加工も簡単になります。

実行の仕組みからすると、先ほどの項目から1項目づつ抽出し、それらを連結した文字列をプロンプトとして渡し、セリフを生成しています。生成されたセリフは、outputタグのシートに出力されます。

では、これを実行してみます。先ほどの項目を入力したシートをアクティブにした状態から、スクリプトでgenerateDialogueを指定して実行します。

出力結果としては次の通りとなります。

性別は男性 年齢は20代 家族は配偶者と10歳の男の子 性格はリーダー要素がある 話す場面は顔を合わせた時,「お前たちには今後の計画を話す。俺がリーダーとなり、必ずや成功させる。それが我々の家族の未来だ」
性別は男性 年齢は20代 家族は配偶者と10歳の男の子 性格はリーダー要素がある 話す場面は顔を合わせた時,「お前たち、元気か?俺たち家族は最近、一緒に過ごす時間が少なくなってきてるんだ。今度、一緒に何か楽しいことしようぜ!」
性別は女性 年齢は20代 家族は配偶者と10歳の男の子 性格はリーダー要素がある 話す場面は顔を合わせた時,「おはようございます。今日も一日頑張りましょう!」

このように、ChatGPTはゲーム開発のプランナーのちょっとした仕事を肩代わりしてくれます。これにより、プランナーはより創造的な仕事に集中し、ゲーム開発の品質向上につなげることができるでしょう。