AI Powered NPC's With ChatGPT Assistants

Want to make your own NPC’s where you build their background and then respond as the person you want them to be? In this tutorial I’ll show you how!

  1. Go to https://platform.openai.com/playground/assistants make an account and create an assistant. To call this API it will cause an extremely small amount of money per the tokens you use so you’ll need to put money into your account.

  2. Select your model. I would recommend going with any 3.5 turbo model, it will be quick but it will be cheaper. The more advanced the version you pick, the better the responses are going to be to the bio you give.

  3. Give it a name. I gave it the name “Bob the medieval guy

  4. Give it a description under instructions, the more details you give the better. I said: You’re bob, a medieval peasant who doesn’t know much. You have the education of a kindergartener and all you do is farm your entire life. You have a hard time speaking good english and your speech is broken and barely understandable. You can ask it questions in the browser to see how it responds before you use it.

  5. Under your NPC name, copy the assistant id, will look something like asst_awwbdhwbibawdhbwaudwndwd and add it into the module script where it says local assistantId = ‘asst_’

  6. Click settings, click your profile, click user API keys, create an API key, and copy it and add it in where it says local apiKey = ‘’

  7. Put the module script where you want it and call is like this:

local gpt = require(game.ServerScriptService.AskGPT)
gpt.ask("what color is the sky?")

The response it gave me was: Sky blue! Sky always blue, sometimes grey. Sky pretty, like flowers!
(remember this particular peasant is a medieval npc)

Module script:

local apiKey = -- Replace with your API key
local assistantId = 

local HttpService = game:GetService("HttpService")
local function httpPost(url, data, headers)
	local response = HttpService:RequestAsync({
		Url = url,
		Method = "POST",
		Headers = headers,
		Body = HttpService:JSONEncode(data)
	})
	return response
end

-- Function to make HTTP GET request
local function httpGet(url, headers)
	local response = HttpService:RequestAsync({
		Url = url,
		Method = "GET",
		Headers = headers
	})
	return response
end

local function waitForRunCompletion(threadId, runId, apiKey, timeout)
	timeout = timeout or 50
	local startTime = tick()

	while tick() - startTime < timeout do
		local statusResponse = httpGet(
			"https://api.openai.com/v1/threads/" .. threadId .. "/runs/" .. runId,
			{["Authorization"] = "Bearer " .. apiKey,
				["Content-Type"] = "application/json",
				["OpenAI-Beta"] = "assistants=v1"}
		)
		local runStatus = HttpService:JSONDecode(statusResponse.Body).status

		print(runStatus)

		if runStatus == 'completed' then
			return statusResponse
		elseif runStatus == 'failed' then
			error("Run failed.")
			break
		end

		wait(1)  -- Delay before the next status check
	end

	error("Run did not complete within the specified timeout.")
end


local agpt = {}

function agpt.ask(question)
	local threadResponse = httpPost(
		"https://api.openai.com/v1/threads",
		{messages = {{["role"] = "user", ["content"] = question}}},
		{["Authorization"] = "Bearer " .. apiKey,
			["Content-Type"] = "application/json",
			["OpenAI-Beta"] = "assistants=v1"}
	)
	local thread = HttpService:JSONDecode(threadResponse.Body)
	print(thread)
	-- Create run
	local runResponse = httpPost(
		"https://api.openai.com/v1/threads/" .. thread.id .. "/runs",
		{assistant_id = assistantId},
		{["Authorization"] = "Bearer " .. apiKey,
			["Content-Type"] = "application/json",
			["OpenAI-Beta"] = "assistants=v1"}
	)
	local run = HttpService:JSONDecode(runResponse.Body)

	-- Wait for completion
	local completedRun = waitForRunCompletion(thread.id, run.id, apiKey, 60)

	-- Retrieve messages
	local messagesResponse = httpGet(
		"https://api.openai.com/v1/threads/" .. thread.id .. "/messages",
		{["Authorization"] = "Bearer " .. apiKey,
			["Content-Type"] = "application/json",
			["OpenAI-Beta"] = "assistants=v1"}
	)
	local messages = HttpService:JSONDecode(messagesResponse.Body)

	-- Log messages
	print(messages.data[1].content[1].text.value)
end
return agpt

That’s the tutorial, be careful with your usage, You don’t want to use it where it would be spammed, unless you make a lot of money from the game you use it in. Thanks for reading!

9 Likes

Honestly, It doesn’t have to be OpenAI, There are other services like OpenAI that let us use APIs to create our own agents or per sake bots.

If I do find any alternatives, I’ll be sure to list them here, so the OP can include if he wants to.

I’m only saying what I said because many people use other platforms such as Microsoft, Claude and so on. So it doesn’t have to be locked towards having to use ChatGPT for this.

2 Likes

Oh yeah there’s plenty. You can look into Claude, Llama, and there’s a lot of local models you can use as well that you can run on your own computer with LM Studio!

2 Likes