DEV Community

shashank ms
shashank ms

Posted on

LLMs in Entertainment: A Guide to Getting Started

We are going to build a command-line interactive fiction engine that generates branching story scenes and presents the player with three choices each turn. This is a practical starting point for game writers, solo devs, or anyone prototyping narrative experiences without managing a game engine. We will run the whole thing on Oxlo.ai using the OpenAI-compatible SDK.

What you'll need

  • Python 3.10 or newer
  • The OpenAI Python SDK: pip install openai
  • An Oxlo.ai API key from https://portal.oxlo.ai

Step 1: Connect to Oxlo.ai

I always start by verifying the endpoint and credentials before adding logic. Create a file named story_engine.py and initialize the client.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "user", "content": "Reply with exactly: Oxlo.ai connection ready"}
    ]
)
print(response.choices[0].message.content)

Step 2: Define the system prompt

The system prompt is the only creative director the model gets. I keep it strict so the output format stays consistent and easy to parse later.

SYSTEM_PROMPT = """You are an interactive fiction engine. Your job is to write a short scene of 2 to 3 paragraphs and then offer the player exactly three choices labeled A, B, and C.

Rules:
- Write in second person, present tense.
- End every response with the three choices on separate lines starting with A), B), and C).
- Maintain continuity with all previous scenes.
- Do not end the story unless the player reaches a fatal or resolved outcome.
- Default genre is sci-fi noir. Adapt if the player requests otherwise."""

Step 3: Generate the opening scene

Now we wrap the API call in a small function. I pass the system prompt and a user message asking for a new story. The assistant's reply becomes the first scene.

def generate_scene(client, history, user_input):
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    messages.extend(history)
    messages.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=messages,
        temperature=0.9,
        max_tokens=800
    )
    return response.choices[0].message.content

history = []
scene = generate_scene(client, history, "Start a new story.")
print(scene)
history.append({"role": "assistant", "content": scene})

Step 4: Handle player choices

After the player reads the scene, they reply with A, B, or C. We append that choice to the history and generate the next scene. This single turn is one request to Oxlo.ai.

player_choice = "B"  # In a real session this comes from input()
user_input = f"The player chooses option {player_choice}."

next_scene = generate_scene(client, history, user_input)
print(next_scene)

history.append({"role": "user", "content": user_input})
history.append({"role": "assistant", "content": next_scene})

Step 5: Build the play loop

For a real session we need a loop. I also cap the history so the context window does not grow forever. Because Oxlo.ai uses flat per-request pricing, sending a longer transcript does not make each turn more expensive. You can keep the full narrative in context without watching token meters tick up. See https://oxlo.ai/pricing for plan details.

class StoryEngine:
    def __init__(self, client):
        self.client = client
        self.history = []

    def act(self, user_input):
        messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        messages.extend(self.history)
        messages.append({"role": "user", "content": user_input})

        response = self.client.chat.completions.create(
            model="llama-3.3-70b",
            messages=messages,
            temperature=0.9,
            max_tokens=1000
        )
        text = response.choices[0].message.content

        self.history.append({"role": "user", "content": user_input})
        self.history.append({"role": "assistant", "content": text})

        # Keep last 12 turns (24 messages) to limit context growth
        if len(self.history) > 24:
            self.history = self.history[-24:]

        return text

engine = StoryEngine(client)
print(engine.act("Start a new story."))

while True:
    choice = input("\nChoose A, B, C, or type 'quit': ").strip()
    if choice.lower() == "quit":
        break
    print(engine.act(f"The player chooses option {choice}."))

Run it

Here is what a session looks like after running python story_engine.py.

Start a new story.

The neon rain hisses against the cracked window of your apartment on Level 9. You are staring at a holographic note that arrived unsigned: "The cargo bay. Midnight. Bring the keycard." Your reflection in the glass looks tired, but the gun on your desk is clean.

A) Grab the gun and head to the cargo bay early to scout.
B) Leave the gun, take the keycard, and arrive exactly at midnight.
C) Ignore the message and try to trace who sent it.

Choose A, B, C, or type 'quit': B

The cargo bay doors slide open with a rusted groan. The air smells of ozone and old grease. A figure in a hooded coat stands beside a sealed crate, but they do not turn around. "You are late," they say, though you arrived at 00:00 exactly.

A) Approach and demand to know what is in the crate.
B) Hang back near the door and ask who they are.
C) Toss the keycard to their feet and keep your hands visible.

Choose A, B, C, or type 'quit': quit

Wrap-up and next steps

The engine now works as a minimal prototype. Two concrete next steps: swap the model to kimi-k2.6 or qwen-3-32b to test how different reasoning styles change the narrative voice, or add a JSON schema response format so the UI can split scene text from choices automatically and render them in a web frontend.

Top comments (0)