9.6 KiB
GumYum NPC Game Client for Godot
Bring NPCs to life in your Godot games with AI-powered dialogue and personality systems.
Features
- API Key Authentication: Simple setup with public/secret key pairs
- Character Spawning: Create NPCs from any GumYum universe
- Natural Dialogue: Chat with NPCs that remember context and have personalities
- Streaming Support: Real-time typewriter effect for dialogue
- Auto-Retry: Built-in error handling and request retry
- Lightweight: Minimal footprint, perfect for production builds
Installation
Method 1: Clone from GitLab (Recommended)
Since the client is stable & shouldn't be change, we recommend cloning & copying:
- Clone the public repository:
git clone https://git.unturf.com/engineering/gumyum/npc-clients.git - Copy the addon to your project:
cp -r npc-clients/godot/gumyum_npc_game_client /path/to/your/project/addons/ - Enable the plugin in Project Settings → Plugins → GumYum NPC Game Client
- The
GumyumClientsingleton will be available globally
If you ever need to you can git pull the latest clients and patch game files as needed.
Method 2: Direct Download Zip
-
Download the zip of all the client SDKs
-
Decompress & copy the
godot/gumyum_npc_game_clientdirectory into your project'saddons/directory -
Enable the plugin in Project Settings → Plugins → GumYum NPC Game Client
Method 3: Asset Library (Coming Soon)
The GumYum NPC addon will be available in the Godot Asset Library.
Quickstart
Create a working chat UI with NPCs in under 5 minutes:
# Quickstart: Chat UI with NPCs
# Save as ChatDemo.gd and attach to a Control node
extends Control
@onready var chat_display = RichTextLabel.new()
@onready var input_field = LineEdit.new()
@onready var send_button = Button.new()
var current_npc: GumYumNPC
func _ready():
# Setup UI
setup_ui()
# Configure API
GumyumClient.api_key = "gumyum-pk-your-public-key"
GumyumClient.api_secret = "gumyum-sk-your-secret-key"
GumyumClient.base_url = "https://npc.gumyum.com"
# Spawn a random NPC
add_system_message("Connecting to GumYum API...")
GumyumClient.npcs.spawn(
"kingdom", # universe
42, # seed
null, # npc_id (null = random)
_on_npc_spawned
)
func _on_npc_spawned(npc: GumYumNPC):
if npc == null:
add_system_message("[color=red]Failed to spawn NPC![/color]")
return
current_npc = npc
add_system_message(
"[color=green]Connected to " + npc.name + " the " + npc.profession + "[/color]"
)
func send_message(text: String):
if text.is_empty() or current_npc == null:
return
add_player_message(text)
# Use chat_with_history for easy conversation tracking
current_npc.chat_with_history(
text, 0.8, 1500, false,
_on_chat_response
)
func _on_chat_response(response):
if response.has("error"):
add_system_message("[color=red]Error: " + response.error + "[/color]")
else:
var content = response.choices[0].message.content
add_npc_message(content)
API Reference
Configuration
# Set your API credentials
GumyumClient.api_key = "gumyum-pk-your-public-key"
GumyumClient.api_secret = "gumyum-sk-your-secret-key"
# Optional: Set custom API endpoint
GumyumClient.base_url = "https://npc.gumyum.com"
# Optional: Enable debug mode
GumyumClient.debug_mode = true
Spawning NPCs
Method 1: Spawn by ID (Specific or Random)
# Spawn a specific NPC
GumyumClient.npcs.spawn(
"kingdom", # universe_id
42, # world_seed
123456789, # npc_id (specific)
_on_npc_spawned
)
# Spawn a random NPC (API generates from seed)
GumyumClient.npcs.spawn(
"kingdom", # universe_id
42, # world_seed
null, # npc_id (null/omit for random)
_on_npc_spawned
)
Method 2: Spawn with Filters
# Find NPCs by profession and location
GumyumClient.npcs.spawn_filtered(
"kingdom", 42,
{
"profession": ["warrior", "knight", "guard"],
"sex": ["female"],
"location": ["castle", "barracks"]
},
_on_npc_spawned
)
# Filter by personality type and mood
GumyumClient.npcs.spawn_filtered(
"blade-runner", 42,
{
"personality_type": [8, 3, 5],
"mood": ["paranoid", "vigilant"],
"location": ["police_station"]
},
_on_npc_spawned
)
Chatting with NPCs
Simple Chat with History
# chat_with_history automatically tracks the conversation
current_npc.chat_with_history(
"Hello there!", # message
0.8, # temperature (0.0-1.0)
1500, # max_tokens
false, # streaming
_on_chat_response # callback
)
Advanced Chat API
# Full control over messages
current_npc.chat.completions(
[
{"role": "system", "content": "You are in a tavern"},
{"role": "user", "content": "What's on the menu?"}
],
0.8, # temperature
2000, # max_tokens
false, # streaming
_on_chat_response
)
Streaming Responses
Enable real-time streaming for a typewriter effect:
func setup_streaming():
# Connect streaming signals
npc.dialogue_chunk_received.connect(_on_chunk_received)
npc.dialogue_stream_started.connect(_on_stream_started)
npc.dialogue_stream_ended.connect(_on_stream_ended)
# Enable streaming in chat
npc.chat_with_history(
"Tell me a story",
0.8, 1500,
true, # streaming enabled!
_on_final_response
)
func _on_chunk_received(chunk: String):
dialogue_box.text += chunk
Mood Transitions
The GumYum API tracks NPC moods and can detect mood changes during conversations. Both streaming and non-streaming responses include mood transition data:
func _on_dialogue_received(response):
if response.has("choices") and response.choices.size() > 0:
var content = response.choices[0]["message"]["content"]
# Display the dialogue
# Check for mood changes
if response.has("mood_transition"):
var mood_data = response.mood_transition
var new_mood = mood_data.get("new_mood", "")
var old_mood = mood_data.get("old_mood", "")
var confidence = mood_data.get("confidence", 0.0)
var reasoning = mood_data.get("reasoning", "")
if new_mood and new_mood != old_mood:
print("NPC mood changed from %s to %s (confidence: %.1f)" % [old_mood, new_mood, confidence])
print("Reason: %s" % reasoning)
Mood transition data includes:
new_mood: The NPC's current mood after this responseold_mood: The NPC's previous moodconfidence: How confident the AI is about this mood change (0.0-1.0)reasoning: AI's explanation for why the mood changedstress_level: Current stress level (1-9)
NPC Properties
Each GumYumNPC object has these properties:
# Basic info
npc.name # "Aldric"
npc.profession # "blacksmith"
npc.personality_type # 8 (Enneagram type)
# Identity
npc.npc_id # 123456789
npc.universe_id # "kingdom"
npc.seed # 42
# Current state
npc.get_location() # "forge"
npc.get_mood() # "content"
npc.get_stress_level() # 3
# Conversation history
npc.chat_history # Array of messages
Universe Management (Limited)
With API keys, universe management is limited:
# List public universes (works with API keys)
GumyumClient.universes.list_public(
func(universes):
for u in universes:
print(u.name, " - ", u.description)
)
# These methods require user authentication and will NOT work:
# - universes.list() # List user's universes
# - universes.list_user() # Same as list()
# - universes.copy() # Copy a universe to user vault
# - universes.get_universe() # Get universe details
Note: Games using API keys should hardcode their universe ID when spawning NPCs.
Error Handling
All callbacks receive either a valid response or an error dictionary:
func _on_response(response):
if response.has("error"):
print("Error: ", response.error)
# Handle error
else:
# Process successful response
pass
Signals
The client emits these signals:
character_spawned(character: GumYumNPC)- When an NPC is successfully spawneddialogue_received(response: String, context: Dictionary, mood_transition: Dictionary)- Regular chat response with mood datadialogue_chunk_received(chunk: String)- For streaming responsesdialogue_stream_started- When streaming beginsdialogue_stream_ended(full_response: String, context: Dictionary, mood_transition: Dictionary)- Streaming complete with mood datarequest_completed(endpoint: String, data: Dictionary)request_failed(endpoint: String, error: String)
Examples
Check the examples/ folder for:
QuickstartChat.gd- Simple programmatic UI example (matches the docs quickstart)NpcChatExample.gd+.tscn- Full scene-based example with streaming support
Requirements
- Godot 4.0 or later
- GumYum API keys (get one at npc.gumyum.com)
- Internet connection for API requests