
YOU SEE AN LLM HERE: Integrating Language Fashions Into Your Textual content Journey Video games
Picture by Writer | Midjourney
Introduction
Textual content-based journey video games have a timeless enchantment. They permit gamers to think about complete worlds, from shadowy dungeons and towering castles to futuristic spacecraft and mystic realms, all by the ability of language. Right this moment, integrating giant language fashions (LLMs), like ChatGPT, into these video games takes this idea to new heights by offering dynamically generated descriptions, character dialogue, and extra — all on the fly.
Textual content adventures thrive on creativeness. Historically, recreation builders hard-code all of the descriptions of rooms, gadgets, and NPC (non-player character) interactions into the sport, which means that every doable path or situation have to be crafted by hand. This works tremendous for smaller or extra static video games, however as soon as your challenge begins to develop, it turns into more and more cumbersome. Then again, utilizing an LLM can provide you recent, diversified, and dynamic textual content with out your having to script each element.
Moreover, fashionable LLMs can do extra than simply generate textual content; they will carry context from one interplay to the following, enabling them to construct coherent narratives, adapt to participant decisions, or mirror the progress within the story. Whereas we should stay conscious of token and context limitations, the probabilities for synergy between textual content adventures and language fashions are huge.
On this tutorial, we’ll stroll by the method of constructing a easy Python-based textual content journey recreation after which elevating it utilizing an LLM. We’ll give attention to the next most important steps:
- Establishing a easy textual content journey framework
- Representing recreation information with JSON
- Integrating ChatGPT for dynamic room descriptions
- Producing NPC dialogues with ChatGPT
- Placing all of it collectively
After we are completed, we’ll find yourself with an entire, working prototype that you would be able to broaden upon and tailor to your individual inventive imaginative and prescient.
This information assumes some familiarity with fundamental Python, utilizing APIs, and coping with JSON formatted information. By the tip of this text, you’ll see how easy (and highly effective) it’s so as to add LLM-driven narrative to even the best text-based interactive fiction.
Making a Easy Textual content Journey Framework
Earlier than incorporating any AI magic, let’s construct a skeletal textual content journey recreation in Python. We’ll first create a minimal engine that hundreds recreation information (rooms, NPCs, gadgets, and so forth.) from a JSON file and lets gamers navigate. In subsequent steps, we’ll layer on LLM-driven enhancements.
Primary Venture Construction
A typical file construction may appear like this:
text_adventure/
├── game_data.json
├── text_adventure.py
└── README.md
The game_data.json file will retailer our fundamental recreation information—room names, descriptions, obtainable exits, gadgets, and so forth. The text_adventure.py file will load this JSON file, parse the info, and supply the sport loop (consumer enter, responses, state administration).
Creating game_data.json
Under is a straightforward instance JSON file to exhibit how we’d construction our information, and provides us one thing to make use of transferring ahead. Later, we’ll broaden or modify it for LLM integration.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
“rooms”: {
“room_entrance”: {
“identify”: “Citadel Entrance”,
“description”: “You’re standing on the grand entrance to an historical stone fort. Torches line the partitions.”,
“exits”: {
“north”: “room_hallway”
}
},
“room_hallway”: {
“identify”: “Nice Hallway”,
“description”: “An expansive hallway stretches earlier than you with doorways resulting in unknown chambers.”,
“exits”: {
“south”: “room_entrance”,
“east”: “room_armory”
}
},
“room_armory”: {
“identify”: “Armory”,
“description”: “Shields, swords, and arcane artifacts line the partitions of this dimly lit armory.”,
“exits”: {
“west”: “room_hallway”
}
}
},
“participant”: {
“start_room”: “room_entrance”,
“stock”: []
}
}
This JSON declares three rooms for our recreation — room_entrance, room_hallway, and room_armory — every with a reputation, an outline, and a dictionary of exits pointing to different rooms. The participant object defines a beginning room and an empty stock. There are quite a few alernative methods we may implement this, however this simplistic method works for our functions.
Python Framework in text_adventure.py
Let’s write the code for our base textual content journey engine. This model excludes any LLM integration — simply the naked necessities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import json
class TextAdventureGame:
def __init__(self, game_data_path):
with open(game_data_path, ‘r’) as f:
self.game_data = json.load(f)
self.rooms = self.game_data.get(“rooms”, {})
self.player_data = self.game_data.get(“participant”, {})
self.current_room = self.player_data.get(“start_room”, “”)
self.stock = self.player_data.get(“stock”, [])
def describe_current_room(self):
room = self.rooms[self.current_room]
print(f“n{room[‘name’]}”)
print(room[‘description’])
def get_user_input(self):
return enter(“n> “).strip().decrease()
def move_player(self, path):
room = self.rooms[self.current_room]
exits = room.get(“exits”, {})
if path in exits:
self.current_room = exits[direction]
print(f“You progress {path} to the {self.rooms[self.current_room][‘name’]}.”)
else:
print(“You’ll be able to’t go that means.”)
def play(self):
print(“Welcome to the Textual content Journey!”)
self.describe_current_room()
whereas True:
command = self.get_user_input()
if command in [“quit”, “exit”]:
print(“Thanks for enjoying!”)
break
elif command in [“north”, “south”, “east”, “west”]:
self.move_player(command)
self.describe_current_room()
elif command in [“look”, “examine”]:
self.describe_current_room()
else:
print(“I do not perceive that command.”)
if __name__ == “__main__”:
recreation = TextAdventureGame(“game_data.json”)
recreation.play()
Here’s a breakdown of the code:
- Initialization: We load game_data.json and parse it into Python objects
- Recreation state: We retailer the obtainable rooms, monitor the present room, and maintain a listing
- describe_current_room: Prints a brief textual description of the present room
- move_player: Permits the participant to maneuver between rooms, if a legitimate exit exists within the recreation information
- The sport loop:
- prompts the participant for enter
- interprets instructions like “north”, “south”, “east”, “west”, or “give up”
- on motion instructions, updates the present room and describes it
- if “look” or “study” is typed, describe_current_room known as
With this construction in place, we now have a easy text-based recreation. Subsequent, we’ll broaden our JSON information to carry “meta descriptions” for rooms, combine an LLM to generate closing textual descriptions, and use it for NPC dialogue.
Then run the sport by typing:
Right here’s what our recreation seems like at this level:


Integrating ChatGPT for Dynamic Room Descriptions
The core concept is to retailer a meta description of every room in our JSON, fairly than a completely written description. Then, we’ll go this meta description into ChatGPT together with some directions, and ask ChatGPT to provide a extra detailed or thematically wealthy closing textual content. This enables your recreation to have constant high quality and elegance throughout all rooms with out manually writing paragraphs of textual content.
Including Meta Descriptions in JSON
Let’s modify our rooms entries to incorporate a meta_description subject. We’ll take away the hand-written description for demonstration, and rely solely on the LLM to provide textual content.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
“rooms”: {
“room_entrance”: {
“identify”: “Citadel Entrance”,
“meta_description”: “fort entrance, lined with torches, stone partitions, imposing wood doorways, doable presence of guards”,
“exits”: {
“north”: “room_hallway”
}
},
“room_hallway”: {
“identify”: “Nice Hallway”,
“meta_description”: “lengthy hallway, stained glass home windows, tapestries on the partitions, echoes of footsteps, excessive vaulted ceiling”,
“exits”: {
“south”: “room_entrance”,
“east”: “room_armory”
}
},
“room_armory”: {
“identify”: “Armory”,
“meta_description”: “room crammed with weapons and armor, a faint odor of metallic and oil, doable magical artifacts”,
“exits”: {
“west”: “room_hallway”
}
}
},
“participant”: {
“start_room”: “room_entrance”,
“stock”: []
}
}
Setting Up ChatGPT API
To combine ChatGPT, we’ll want:
- An OpenAI API key
- The openai Python package deal (pip set up openai)
As soon as put in, we will use the API to ship ChatGPT prompts. Let’s illustrate a brand new methodology in our TextAdventureGame class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import json
import os
from openai import OpenAI
class TextAdventureGame:
def __init__(self, game_data_path):
with open(game_data_path, ‘r’) as f:
self.game_data = json.load(f)
self.rooms = self.game_data.get(“rooms”, {})
self.player_data = self.game_data.get(“participant”, {})
self.current_room = self.player_data.get(“start_room”, “”)
self.stock = self.player_data.get(“stock”, [])
# Initialize OpenAI consumer
self.consumer = OpenAI(api_key=os.getenv(“OPENAI_API_KEY”))
def describe_current_room(self):
room = self.rooms[self.current_room]
# We’ll name our LLM perform right here to get the ultimate description
description = self.generate_room_description(room)
print(f“n{room[‘name’]}”)
print(description)
def generate_room_description(self, room):
# Construct a immediate with the meta_description
immediate = (
“You’re a recreation narrative engine. Given a meta description, produce a vivid, “
“immersive, and thematically constant room description for gamers. “
“Don’t break character, maintain it quick (2-3 sentences). “
f“Meta description: {room[‘meta_description’]}”
)
strive:
response = self.consumer.chat.completions.create(
mannequin=“gpt-3.5-turbo”,
messages=[
{“role”: “system”, “content”: “You are a game narrative engine.”},
{“role”: “user”, “content”: prompt}
],
max_tokens=100,
temperature=0.7,
n=1,
cease=None
)
return response.decisions[0].message.content material.strip()
besides Exception as e:
print(“Error calling OpenAI API:”, e)
# Fallback: return the meta_description straight
return room[‘meta_description’]
def get_user_input(self):
return enter(“n> “).strip().decrease()
def move_player(self, path):
room = self.rooms[self.current_room]
exits = room.get(“exits”, {})
if path in exits:
self.current_room = exits[direction]
print(f“You progress {path} to the {self.rooms[self.current_room][‘name’]}.”)
else:
print(“You’ll be able to’t go that means.”)
def play(self):
print(“Welcome to the Textual content Journey!”)
self.describe_current_room()
whereas True:
command = self.get_user_input()
if command in [“quit”, “exit”]:
print(“Thanks for enjoying!”)
break
elif command in [“north”, “south”, “east”, “west”]:
self.move_player(command)
self.describe_current_room()
elif command in [“look”, “examine”]:
self.describe_current_room()
else:
print(“I do not perceive that command.”)
if __name__ == “__main__”:
recreation = TextAdventureGame(“game_data.json”)
recreation.play()
Right here is how this works:
- We’ve created a brand new perform referred to as generate_room_description that:
- Takes a room dictionary as enter
- Constructs a immediate for ChatGPT, referencing the room’s meta_description
- Calls the ChatGPT API to generate a closing, fleshed-out description
- Returns that textual content, which is then printed to the participant
- For manufacturing, contemplate customizing the immediate additional. For instance, you may wish to embody directions about recreation fashion (e.g., comedic, darkish fantasy, excessive fantasy, sci-fi, and so forth.), or specify formatting constraints.
- We set a fallback to the meta_description in case of API failures. This ensures your recreation can nonetheless run in an offline situation or if one thing goes improper. Crafting a greater default description would seemingly be a choice.
- mannequin=”gpt-3.5-turbo” is used because it performs slightly faster than gpt-4-turbo, and reduces recreation latency.
With that performed, your textual content journey recreation now makes use of ChatGPT to dynamically produce room descriptions. Each time your participant enters a brand new room, they’ll see recent textual content that may be simply modified by adjusting the meta descriptions or the immediate template.
To check the mixing, guarantee you’ve an setting variable OPENAI_API_KEY set to your API key by typing this at a command immediate:
export OPENAI_API_KEY=“sk-xxxx”
Run the sport once more with the LLM integrations:


Producing NPC Dialogues with ChatGPT
One other compelling characteristic of utilizing an LLM is producing interactive dialog with characters. You’ll be able to design a “character” or “NPC” by storing a meta description of their persona, position, or data. Then you definitely immediate ChatGPT with these particulars plus the current dialog to provide their traces of dialogue.
Extending the JSON
Let’s add an NPC to our game_data.json. We’ll place the NPC within the hallway with a meta description of its persona and performance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
“rooms”: {
“room_entrance”: {
“identify”: “Citadel Entrance”,
“meta_description”: “fort entrance, lined with torches, stone partitions, imposing wood doorways, doable presence of guards”,
“exits”: {
“north”: “room_hallway”
}
},
“room_hallway”: {
“identify”: “Nice Hallway”,
“meta_description”: “lengthy hallway, stained glass home windows, tapestries on the partitions, echoes of footsteps, excessive vaulted ceiling”,
“exits”: {
“south”: “room_entrance”,
“east”: “room_armory”
},
“npc”: “npc_guard”
},
“room_armory”: {
“identify”: “Armory”,
“meta_description”: “room crammed with weapons and armor, a faint odor of metallic and oil, doable magical artifacts”,
“exits”: {
“west”: “room_hallway”
}
}
},
“npcs”: {
“npc_guard”: {
“identify”: “Citadel Guard”,
“meta_description”: “stern, loyal, short-tempered guard. Has data of the fort’s secrets and techniques however hardly ever shares.”
}
},
“participant”: {
“start_room”: “room_entrance”,
“stock”: []
}
}
Notice the brand new npcs part with npc_guard. The room_hallway features a “npc”: “npc_guard” subject to point that the guard is current in that room.
Producing NPC Speech
We’ll add performance to deal with NPC interactions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import os
import json
import openai
class TextAdventureGame:
def __init__(self, game_data_path):
with open(game_data_path, ‘r’) as f:
self.game_data = json.load(f)
self.rooms = self.game_data.get(“rooms”, {})
self.npcs = self.game_data.get(“npcs”, {})
self.player_data = self.game_data.get(“participant”, {})
self.current_room = self.player_data.get(“start_room”, “”)
self.stock = self.player_data.get(“stock”, [])
openai.api_key = os.getenv(“OPENAI_API_KEY”)
def generate_room_description(self, room):
immediate = (
“You’re a recreation narrative engine. Given a meta description, produce a vivid, immersive, “
“and thematically constant room description for gamers. Preserve it to 2-3 sentences. “
f“Meta description: {room[‘meta_description’]}”
)
strive:
response = openai.Completion.create(
engine=“text-davinci-003”,
immediate=immediate,
max_tokens=100,
temperature=0.7
)
return response.decisions[0].textual content.strip()
besides Exception as e:
print(“Error calling OpenAI API:”, e)
return room[‘meta_description’]
def generate_npc_dialogue(self, npc_id, player_input=None):
npc_data = self.npcs.get(npc_id, {})
immediate = (
f“You’re a character in a textual content journey recreation. Your persona: {npc_data[‘meta_description’]}. “
“The participant has requested you one thing or approached you. Please reply in a single or two sentences. “
)
if player_input:
immediate += f“nPlayer enter: {player_input}n”
strive:
response = openai.Completion.create(
engine=“text-davinci-003”,
immediate=immediate,
max_tokens=100,
temperature=0.7
)
return response.decisions[0].textual content.strip()
besides Exception as e:
print(“Error calling OpenAI API:”, e)
return “The NPC stares silently, unable to reply.”
def describe_current_room(self):
room = self.rooms[self.current_room]
description = self.generate_room_description(room)
print(f“n{room[‘name’]}”)
print(description)
# Verify if there’s an NPC
npc_id = room.get(“npc”, None)
if npc_id:
dialogue = self.generate_npc_dialogue(npc_id)
npc_name = self.npcs[npc_id][‘name’]
print(f“n{npc_name} says: “{dialogue}””)
def get_user_input(self):
return enter(“n> “).strip().decrease()
def move_player(self, path):
room = self.rooms[self.current_room]
exits = room.get(“exits”, {})
if path in exits:
self.current_room = exits[direction]
print(f“You progress {path} to the {self.rooms[self.current_room][‘name’]}.”)
else:
print(“You’ll be able to’t go that means.”)
def talk_to_npc(self):
room = self.rooms[self.current_room]
npc_id = room.get(“npc”, None)
if npc_id:
player_input = enter(“What do you say? “)
response = self.generate_npc_dialogue(npc_id, player_input)
print(f“{self.npcs[npc_id][‘name’]} replies: “{response}””)
else:
print(“There isn’t any one right here to speak to.”)
def play(self):
print(“Welcome to the Textual content Journey!”)
self.describe_current_room()
whereas True:
command = self.get_user_input()
if command in [“quit”, “exit”]:
print(“Thanks for enjoying!”)
break
elif command in [“north”, “south”, “east”, “west”]:
self.move_player(command)
self.describe_current_room()
elif command.startswith(“discuss”):
self.talk_to_npc()
elif command in [“look”, “examine”]:
self.describe_current_room()
else:
print(“I do not perceive that command.”)
if __name__ == “__main__”:
recreation = TextAdventureGame(“game_data.json”)
recreation.play()
Right here’s an evidence of our newest recreation engine iteration:
- We added an npcs dictionary loaded from JSON
- Inside describe_current_room, if the present room has an NPC, we generate a greeting or preliminary line of dialogue
- A brand new methodology, talk_to_npc, reads what the participant says and sends it to the ChatGPT immediate, returning the NPC’s response
- The talk_to_npc methodology is triggered when the participant sorts one thing like “discuss” or “discuss guard”
Then, once more, run the sport by typing:
It’s best to now be capable of transfer about between rooms with command like “north”, “east”, “west”, or “south”. You’ll be able to kind “discuss” or “discuss guard” when within the hallway with the guard to have a dialog. If you find yourself performed, kind “give up” or “exit” to finish the sport.
If all goes effectively, it’s best to see dynamically generated descriptions in every room, and the guard ought to reply with traces reflecting their short-tempered, loyal demeanor.


The immediate construction contains the NPC’s meta description, guaranteeing ChatGPT can craft a line per the NPC’s persona. Optionally, we will additionally keep a dialog historical past to construct deeper, context-based NPC interactions. For brevity, this instance retains it easy with simply the one immediate.
Placing It All Collectively
At this level, our textual content journey framework combines:
- JSON-based recreation information: Storing rooms, merchandise references, NPC data, and meta descriptions
- Python recreation loop: Dealing with consumer enter for motion, interplay, and dialog
- ChatGPT integration:
- Room descriptions: Generated from meta descriptions to provide immersive textual content
- NPC Dialog: Used to create dynamic, personality-driven exchanges with characters
Issues for Deployment and Scaling
- API Prices: Every name to the ChatGPT API has an related value. For closely trafficked video games or persistent worlds, contemplate what number of tokens you’re utilizing. You may use shorter prompts or a specialised, smaller mannequin for fast responses.
- Caching: For repeated room visits, you might wish to cache the generated descriptions to keep away from re-generating them (and thus incurring extra value) each time a participant steps again right into a room.
- Context Administration: If you need NPCs to recollect particulars over a number of conversations, you’ll must retailer dialog historical past or related state. Bigger reminiscence will be costly by way of tokens, so contemplate summarizing or limiting context home windows.
- Immediate Tuning: The standard and elegance of LLM output is closely depending on the way you craft the immediate. By tweaking directions, you possibly can management size, fashion, tone, or spoiler content material on your recreation.
Remaining Ideas
LLMs resembling ChatGPT open up new frontiers for text-based interactive fiction. As an alternative of tediously writing each line of prose, you possibly can retailer minimal meta descriptions for rooms, gadgets, or characters, then let the mannequin fill within the particulars. The tactic outlined on this article showcases methods to seamlessly combine LLM-driven room descriptions, NPC dialogue, and extra, all utilizing Python, JSON, and the ChatGPT API.
To recap:
- We constructed a easy textual content journey framework in Python, loading static recreation information from JSON
- We added LLM performance to rework meta descriptions into wealthy, atmospheric textual content
- We prolonged our NPC system to interact briefly, personality-driven dialogues with gamers
With this basis, the probabilities are almost infinite. You’ll be able to improve merchandise descriptions, create dynamic puzzles that adapt to the participant’s progress, and even generate complete story arcs on the fly. Whereas warning is warranted—particularly regarding token utilization, value, and the unpredictability of generative fashions—the outcomes will be compelling, immersive, and astonishingly versatile.
So, go forth and experiment. Use LLM-based technology so as to add a component of shock and spontaneity to your textual content journey. Mix these strategies with your individual design creativity, and also you’ll end up constructing worlds that really feel alive and unbound by static traces of code. You now have the instruments to let an LLM form the tales your gamers discover. Completely happy journey constructing!
Source link