What Makes an AI Story Game Feel Real?
Most AI chatbots just respond. But an interactive story game needs secrets — things the player doesn't know that the AI works around. That's the technical challenge I want to share today.
I built BiasSecret, an AI-powered interactive romance story game. The twist? Every playthrough randomly generates hidden parameters that the AI narrator knows about but the player has to discover through gameplay.
Here's how the architecture works under the hood.
The Hidden State Architecture
The core insight: an LLM can simulate hidden game mechanics, but it needs to know the secrets while understanding it must never reveal them.
Generation of Hidden Parameters
AFFECTION_TYPES = [
"True love: he genuinely loves you, feelings are deep and real",
"Mutual need: you both need this relationship for some comfort or benefit",
"Transactional: this relationship helps both your careers or social standing",
"Emotional dependence: he depends on your emotional support",
"Impulse: it started as a rash decision, he's unsure whether to continue",
]
HIDDEN_PERSONALITIES = [
"Player: he's seeing multiple people simultaneously",
"Commitment-phobe: not serious about relationships",
"Avoidant attachment: pulls away when relationship deepens",
"Workaholic: career always comes before your relationship",
"People-pleaser: too nice to everyone",
"Controlling: wants to control every aspect of your life",
"Emotional: mood swings are unpredictable",
]
Each new game gets a random combination — that's over 245 unique game states from just 3 parameter groups. The AI then weaves a narrative around these constraints without stating them directly.
Injecting Secrets Into the System Prompt
def build_system_prompt(session):
prompt = get_prompt(session.language or "zh")
prompt = prompt.replace("[IDENTITY]", session.user_identity)
prompt = prompt.replace("[STAR_NAME]", session.star_name)
prompt = prompt.replace("[NICKNAME]", session.nickname)
# Add hidden parameters as invisible instructions
hidden = (
f"\n\n## Hidden Settings (AI only — NEVER reveal to user)\n"
f"Hidden feelings: {session.hidden_affection}\n"
f"Hidden personality: {session.hidden_personality}\n"
f"Reason for secrecy: {session.secret_reason}\n"
f"Note: Start subtly hinting at hidden personality through story clues after Round 20."
)
prompt += hidden
return prompt
The ## Hidden Settings block tells the AI the full truth about this playthrough. The LLM's inherent instruction-following prevents it from spilling secrets — but its narrative generation naturally leaks clues through dialogue and events.
Enforcing Turn-by-Turn Progression
One challenge with LLM-driven games: the AI wants to be a passive storyteller. You have to force it to maintain forward momentum. The system prompt includes explicit time/place progression rules:
Each turn advances time by 2-6 hours. Every 3-5 turns moves to the next day. Location must change each turn.
This prevents the "stuck in the same coffee shop" problem that kills immersion.
API Integration Pattern: DeepSeek
The game uses DeepSeek's API for generation. The integration pattern is straightforward:
async def call_deepseek(system_prompt, history_text, current_turn=0, language="zh"):
messages = [
{"role": "system", "content": system_prompt},
]
if not history_text or "not started yet" in history_text:
# First turn needs extra context
user_content = (
f"Game starts! The user's identity is {identity}, "
f"the idol is {star}. This is Round {next_turn}, "
f"time is a weekday morning. Generate narration and choices."
)
else:
user_content = history_text
messages.append({"role": "user", "content": user_content})
async with httpx.AsyncClient(timeout=60) as client:
response = await client.post(
f"{BASE_URL}/v1/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "deepseek-chat",
"messages": messages,
"temperature": 0.9,
"max_tokens": 2000,
},
)
data = response.json()
return data["choices"][0]["message"]["content"]
Key parameters for narrative games:
- temperature: 0.9 — High creativity for variety
- max_tokens: 2000 — Room for rich narration + player choices
- 60s timeout — DeepSeek can be slower on long histories
The Viral Growth Loop: Invite-to-Unlock
Instead of a pure paywall, the game uses a viral invite system:
FREE_TURN_LIMIT = 30 # Free users get 30 rounds of gameplay
BONUS_AT_1 = 10 # +10 rounds for 1 invite
BONUS_AT_3 = 30 # +30 rounds for 3 invites
BONUS_AT_5 = 999 # 5 invites = unlimited play
This creates a natural funnel:
- Player gets invested in the story (first 30 rounds = ~15-20 minutes of gameplay)
- To continue, they share a unique invite link
- Each invited player who signs up unlocks more rounds
- At 5 invites, the game is fully unlocked
For a niche audience (K-pop fans who are highly engaged on social media), this is far more effective than a paywall. The invite-to-unlock model leverages existing community dynamics — fans naturally share with fellow fans on Twitter, Discord, and Weverse.
Tech Stack Summary
| Layer | Technology |
|---|---|
| Backend | FastAPI + SQLAlchemy |
| AI Model | DeepSeek API |
| Frontend | Next.js 15 + React 19 |
| Styling | Tailwind CSS v4 |
| Database | SQLite (PostgreSQL-ready schema) |
| Deployment | systemd + Nginx |
| Growth | Invite-to-unlock viral loop |
What I Learned
1. Hidden state is more engaging than fixed stories.
Every playthrough feels unique because the hidden parameters create different dynamics. Players compare notes about what "type" of story they got.
2. LLMs are surprisingly good at hinting.
Without explicit "sneak in a clue" instructions, the AI naturally writes dialogue and events that reflect the hidden state. A workaholic cancels dates. A player has a suspicious phone message.
3. Turn-based progression rules are non-negotiable.
Without forced time/location advancement in the system prompt, the AI will happily narrate the same scene forever. Explicit rules are essential for game-like pacing.
4. The invite loop works for niche communities.
K-pop fans are naturally networked. An invite-to-unlock mechanic that leverages existing social graphs beats paid acquisition for this demographic.
Try It Yourself
If you're curious about AI-powered interactive storytelling, check out BiasSecret — an AI K-pop secret dating simulator built with this architecture.
And if you're building something similar — especially hidden-state LLM games — I'd love to hear about your approach in the comments!
Top comments (0)