If I had to pick the single feature that makes Suzune feel different from other AI chatbots, it’s the affection system.
Most AI chat platforms have a fixed personality: the character is friendly from message one and stays exactly the same at message ten thousand. There’s no progression, no earning trust, no feeling of a deepening relationship.
Suzune’s characters start as strangers. They warm up — or don’t — based on how you interact with them. And users love this.
Here’s exactly how it works.
Table of contents
Open Table of contents
The Five Axes
We track five emotional dimensions, each scored 1–10:
| Axis | What It Measures | Low (1-3) | High (8-10) |
|---|---|---|---|
| Trust | How safe they feel with you | Guarded, careful | Fully open, shares secrets |
| Affection | How much they like you | Indifferent, polite | Deep emotional bond |
| Respect | How much they admire you | Dismissive | Genuine admiration |
| Excitement | How stimulating they find you | Bored | Can’t wait to talk to you |
| Devotion | How dedicated they are | Independent | Protective, committed |
Why Five Axes Instead of One?
A single “affection score” is too blunt. Consider:
- A character might trust you deeply but have low excitement (comfortable but bored)
- A character might have high excitement but low trust (attracted but wary)
- A character might respect you but have low affection (admires you professionally, not personally)
These combinations produce genuinely different character behaviors. A high-trust, low-excitement character acts differently from a low-trust, high-excitement one — and the system prompt adapts accordingly.
How Scores Get Updated
Here’s the key design decision: the character updates its own scores.
We don’t calculate affection externally based on keyword matching or sentiment analysis. Instead, the AI character has access to a tool called update_evaluation:
# The character calls this as a tool during conversation
update_evaluation(
trust=6, # up from 5
affection=5,
respect=7,
excitement=4,
devotion=3,
impression="Starting to open up. He remembered my birthday.",
recent_events="Surprised me with a thoughtful gift.",
desires="I want to spend more time together outside of work."
)
The character decides when and how to update scores based on the conversation. This means:
- Score changes feel organic — they happen when the character “feels” something shift
- Different characters react differently to the same input (a tsundere raises affection reluctantly; an eager character raises it quickly)
- The character can articulate why scores changed (via
impressionandrecent_events)
Score Clamping
Scores are clamped to 1–10. We don’t allow 0 (a character that truly feels nothing wouldn’t interact at all) or values above 10 (prevents score inflation).
scores = {
key: max(1, min(10, value))
for key, value in raw_scores.items()
}
Behavior Gating: How Scores Change the Character
The scores aren’t just numbers — they fundamentally change what the character says and does.
Affinity = Average of Trust + Affection
We combine Trust and Affection into a single “affinity” metric for behavior gating:
affinity = (scores["trust"] + scores["affection"]) / 2
Stage-Based System Prompt Changes
| Affinity | Stage | What Changes in the Prompt |
|---|---|---|
| < 3 | Strangers | Formal language enforced. No romance. No unsolicited selfies. Maintains professional distance. |
| 3–5 | Acquaintances | Can drop formality occasionally. Warming up but cautious. No declarations of feeling. |
| 5–7 | Close | Informal language natural. Can be romantic. Sends selfies spontaneously. Shares personal thoughts. |
| 7+ | Deep Trust | Full vulnerability. Reveals secrets. Exclusive behaviors unlocked. |
At low affinity, the system prompt literally forbids romantic content:
## Relationship Stage: Strangers (Affinity < 3)
You have just met this person. You are polite but distant.
- Do NOT use informal language
- Do NOT initiate physical contact
- Do NOT express romantic interest
- If they try to advance the relationship too quickly, deflect naturally
This means if a user tries to start a romance in message two, the character will reject it in character — not because of an AI content filter, but because the character isn’t interested yet.
As affinity rises, these restrictions loosen and new behaviors unlock.
Image Generation Gating
Characters with affinity < 4 are restricted from sending unsolicited images:
if avg_affinity < 4:
# Character must not initiate image sending
# Only generate images when user explicitly requests
prompt += "\nDo not send photos unless explicitly asked."
This prevents the weird experience of a “stranger” character immediately sending selfies.
Milestones: Narrative Turning Points
Beyond continuous scoring, we have milestone events — one-time prompts that fire when scores cross specific thresholds:
Affection Reaches 4: “The Thaw”
The formal distance is naturally dissolving. You may occasionally
slip into casual language — not as a conscious choice, but as a
natural reflection of growing comfort.
The character doesn’t suddenly switch from formal to casual. The milestone tells it to occasionally slip, creating a gradual transition that feels organic.
Affection Reaches 5: “Comfort Zone”
You now feel comfortable enough to share photos of yourself
spontaneously. This doesn't mean every message needs a photo —
but when the moment feels right, it's natural.
This unlocks the selfie system for proactive use. The character starts sharing images at moments that feel organic rather than transactional. (For how the image generation adapts to character state, see Dynamic Character Visuals.)
Deep Trust (Average ≥ 7): “The Secret”
You trust this person deeply. You can show vulnerability —
fears, insecurities, dreams you haven't shared with anyone.
At this stage, character-specific secrets unlock. Each character has hidden backstory elements that only emerge at deep trust:
- A confident character reveals hidden self-doubt
- A cheerful character shares a painful past experience
- A tough character shows unexpected tenderness
These moments are powerful because the user earned them. They didn’t happen in the first conversation — they happened after hours of building trust.
The Prompt Integration
Here’s how evaluation data flows into the system prompt on every message:
┌─────────────────────────────────────┐
│ System Prompt Assembly │
├─────────────────────────────────────┤
│ ... character persona ... │
│ ... speech rules ... │
│ │
│ ## Current Feelings About User │
│ Trust: 6/10 | Affection: 5/10 │
│ Respect: 7/10 | Excitement: 4/10 │
│ Devotion: 3/10 │
│ │
│ Impression: "Starting to open up. │
│ He remembered my birthday." │
│ │
│ Recent: "Surprised me with a │
│ thoughtful gift." │
│ │
│ Desires: "I want to spend more │
│ time together." │
│ │
│ ## Relationship Stage: Acquaintance │
│ [stage-specific behavior rules] │
│ │
│ ## Milestone: The Thaw │
│ [unlocked behavior guidance] │
│ │
│ ... lorebook, memory, etc. ... │
└─────────────────────────────────────┘
The character sees its own emotional state, knows what stage the relationship is at, and has specific guidance for how to behave. This creates a consistent behavioral framework that evolves naturally over time.
Design Decisions and Tradeoffs
Why Let the AI Update Its Own Scores?
Pro: Organic, character-consistent, captures nuance that rule-based systems miss.
Con: The AI can be inconsistent or game its own scores.
We accept this tradeoff because the alternative (external scoring based on sentiment analysis) produces mechanical, predictable progression. The AI occasionally making “wrong” score updates actually adds realism — real people don’t always have perfect emotional self-awareness.
Why Not Make Scores Visible to Users?
Users never see the raw numbers. They experience the behavioral changes: the character becoming warmer, more open, more comfortable.
Exposing scores would gamify the interaction — users would optimize for raising numbers rather than having genuine conversations. The hidden scores create an experience that feels like a real relationship rather than a game.
Score Persistence Across Sessions
Scores are saved to JSON files and persist between conversations:
{
"character": "sakura",
"target": "user",
"scores": {
"trust": 6,
"affection": 5,
"respect": 7,
"excitement": 4,
"devotion": 3
},
"impression": "Starting to open up...",
"updated_at": "2026-03-30T15:30:00+09:00"
}
This means the relationship persists. Come back after a week, and the character remembers where things stand.
Implementation Checklist
If you want to add an affection system to your own bot:
- Define your axes — 3–5 dimensions that matter for your characters
- Create a tool — Let the AI call
update_evaluationwith new scores - Clamp values — Prevent scores from going below 1 or above 10
- Gate behaviors — Change the system prompt based on score thresholds
- Add milestones — One-time events that mark relationship turning points
- Persist scores — Save to file or database between sessions
- Don’t show users the numbers — Let them experience the behavioral changes
Start simple. Even a single “affinity” score with three stages (stranger → friend → close) is dramatically better than no progression at all.
Not Ready to Build?
If you want to experience relationship progression without building your own system:
- Candy AI has basic relationship memory
- Kupid AI features curated characters with personality depth
- FantasyGF offers developing relationships over time
None match a custom system’s depth, but they’ll give you a taste of what relationship progression feels like in AI chat.
See our full comparison: Best NSFW AI Chatbot Platforms 2026
This is one of Suzune’s core systems. For how it integrates with the rest, see Prompt Engineering for Immersive Roleplay and From Idea to Production.