AeThex-Engine-Core/docs/tutorials/AI_ASSISTANT_TUTORIAL.md

14 KiB

AI Assistant Tutorial

Learn how to integrate AeThex's AI assistant into your game to provide contextual help and coding assistance to players.


What You'll Build

A game with an in-game AI assistant that can:

  • Answer questions about game mechanics
  • Provide hints and tips
  • Generate code snippets
  • Offer context-aware help

Time: 20 minutes
Difficulty: Beginner
Prerequisites: Basic GDScript knowledge


Prerequisites

  • Completed First Game Tutorial
  • AeThex Cloud connection set up
  • Basic understanding of UI systems

Step 1: Connect to AI Service

First, ensure you're connected to AeThex Cloud with AI services enabled.

# main.gd
extends Node

func _ready():
    # Connect to cloud
    var result = await AeThexCloud.connect_to_cloud()
    
    if result.success:
        print("Connected to AeThex Cloud")
    else:
        print("Failed to connect: ", result.error)

Step 2: Create the AI Assistant UI

Create a simple chat interface for the AI assistant.

# ai_assistant.gd
extends Control

@onready var chat_history = $VBox/ChatHistory
@onready var input_field = $VBox/HBox/InputField
@onready var send_button = $VBox/HBox/SendButton
@onready var loading_indicator = $VBox/LoadingIndicator

func _ready():
    send_button.pressed.connect(_on_send_pressed)
    input_field.text_submitted.connect(_on_text_submitted)
    loading_indicator.visible = false

func _on_send_pressed():
    _send_message(input_field.text)

func _on_text_submitted(text: String):
    _send_message(text)

func _send_message(message: String):
    if message.strip_edges().is_empty():
        return
    
    # Add user message to chat
    add_message("You", message, Color.CYAN)
    input_field.clear()
    
    # Show loading indicator
    loading_indicator.visible = true
    send_button.disabled = true
    
    # Ask AI assistant
    var response = await AeThexAI.ask_assistant(message)
    
    # Hide loading indicator
    loading_indicator.visible = false
    send_button.disabled = false
    
    # Add AI response to chat
    if response.success:
        add_message("AI Assistant", response.answer, Color.GREEN)
    else:
        add_message("AI Assistant", "Sorry, I couldn't process that. " + response.error, Color.RED)

func add_message(sender: String, text: String, color: Color):
    var label = Label.new()
    label.text = "[%s]: %s" % [sender, text]
    label.modulate = color
    label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
    chat_history.add_child(label)
    
    # Auto-scroll to bottom
    await get_tree().process_frame
    if chat_history.get_v_scroll_bar():
        chat_history.scroll_vertical = chat_history.get_v_scroll_bar().max_value

Step 3: Create the Scene

Create a scene structure for the AI assistant:

AIAssistant (Control)
├── Panel (Panel)
│   └── VBox (VBoxContainer)
│       ├── Title (Label) - "AI Assistant"
│       ├── ChatHistory (ScrollContainer)
│       │   └── MessageContainer (VBoxContainer)
│       ├── LoadingIndicator (Label) - "Thinking..."
│       └── HBox (HBoxContainer)
│           ├── InputField (LineEdit)
│           └── SendButton (Button) - "Send"

Layout Tips:

  • Set Panel anchor to center
  • ChatHistory should expand vertically
  • InputField should expand horizontally

Step 4: Context-Aware Help

Make the AI assistant aware of the player's current context.

# context_aware_assistant.gd
extends Control

var player_context = {
    "current_level": 1,
    "player_health": 100,
    "inventory": [],
    "last_checkpoint": "start",
}

func ask_with_context(question: String):
    # Build context string
    var context = "Player context: Level %d, Health: %d, Checkpoint: %s" % [
        player_context.current_level,
        player_context.player_health,
        player_context.last_checkpoint
    ]
    
    # Include context in the question
    var full_question = "%s\n\nContext: %s" % [question, context]
    
    # Ask AI
    var response = await AeThexAI.ask_assistant(full_question)
    return response

func update_context(key: String, value):
    player_context[key] = value

Step 5: Pre-defined Quick Help

Add quick help buttons for common questions.

# quick_help.gd
extends Control

@onready var assistant = get_node("../AIAssistant")

var quick_questions = [
    "How do I jump higher?",
    "What does this item do?",
    "Where should I go next?",
    "How do I defeat this enemy?",
]

func _ready():
    # Create buttons for quick questions
    for question in quick_questions:
        var button = Button.new()
        button.text = question
        button.pressed.connect(_on_quick_question.bind(question))
        add_child(button)

func _on_quick_question(question: String):
    assistant.send_message(question)

Step 6: Code Generation

Use the AI to generate code snippets for players.

# code_generator.gd
extends Control

@onready var code_output = $VBox/CodeOutput
@onready var request_input = $VBox/RequestInput
@onready var generate_button = $VBox/GenerateButton

func _ready():
    generate_button.pressed.connect(_on_generate_pressed)

func _on_generate_pressed():
    var request = request_input.text
    
    if request.is_empty():
        return
    
    # Request code generation
    var prompt = "Generate GDScript code for: " + request
    var response = await AeThexAI.generate_code(prompt)
    
    if response.success:
        code_output.text = response.code
        # Add syntax highlighting
        code_output.syntax_highlighter = GDScriptSyntaxHighlighter.new()
    else:
        code_output.text = "Error: " + response.error

Step 7: Hint System

Create a progressive hint system using the AI.

# hint_system.gd
extends Node

var current_puzzle = "temple_door"
var hint_level = 0

func get_hint():
    hint_level += 1
    
    var prompt = "Give hint level %d (out of 3) for puzzle: %s. Be progressively more specific." % [
        hint_level,
        current_puzzle
    ]
    
    var response = await AeThexAI.ask_assistant(prompt)
    
    if response.success:
        return response.answer
    else:
        return "No hints available"

func reset_hints():
    hint_level = 0

Step 8: Tutorial Generator

Let AI generate custom tutorials for players.

# tutorial_generator.gd
extends Node

func generate_tutorial_for_mechanic(mechanic: String):
    var prompt = """
    Create a brief in-game tutorial for the mechanic: %s
    Format: 
    1. Title
    2. 3 simple steps
    3. Tips
    """ % mechanic
    
    var response = await AeThexAI.ask_assistant(prompt)
    
    if response.success:
        return parse_tutorial(response.answer)
    else:
        return null

func parse_tutorial(text: String) -> Dictionary:
    # Parse AI response into structured tutorial
    return {
        "title": "Tutorial",
        "steps": text.split("\n"),
        "completed": false
    }

Step 9: Error Explanation

Help players understand errors in custom scripting.

# error_explainer.gd
extends Node

func explain_error(error_message: String):
    var prompt = """
    Explain this game scripting error in simple terms and suggest a fix:
    
    Error: %s
    
    Target audience: Beginners
    """ % error_message
    
    var response = await AeThexAI.ask_assistant(prompt)
    
    if response.success:
        return {
            "explanation": response.answer,
            "success": true
        }
    else:
        return {
            "explanation": "Could not explain error",
            "success": false
        }

Step 10: Rate Limiting and Caching

Implement rate limiting to prevent API abuse.

# ai_manager.gd
extends Node

var request_cache = {}
var last_request_time = 0
var min_request_interval = 2.0  # seconds

func ask_with_cache(question: String):
    # Check cache first
    if question in request_cache:
        return request_cache[question]
    
    # Rate limiting
    var time_since_last = Time.get_ticks_msec() / 1000.0 - last_request_time
    if time_since_last < min_request_interval:
        var wait_time = min_request_interval - time_since_last
        await get_tree().create_timer(wait_time).timeout
    
    # Make request
    last_request_time = Time.get_ticks_msec() / 1000.0
    var response = await AeThexAI.ask_assistant(question)
    
    # Cache successful responses
    if response.success:
        request_cache[question] = response
    
    return response

func clear_cache():
    request_cache.clear()

Complete Example: In-Game Help System

Here's a complete help system implementation:

# help_system.gd
extends Control

@onready var help_panel = $HelpPanel
@onready var chat_container = $HelpPanel/VBox/ChatContainer
@onready var input_field = $HelpPanel/VBox/HBox/Input
@onready var send_btn = $HelpPanel/VBox/HBox/SendBtn
@onready var quick_help = $HelpPanel/VBox/QuickHelp

var is_open = false

func _ready():
    help_panel.visible = false
    send_btn.pressed.connect(_on_send)
    input_field.text_submitted.connect(_on_submit)
    
    # Toggle with F1
    set_process_input(true)
    
    # Setup quick help buttons
    setup_quick_help()

func _input(event):
    if event.is_action_pressed("ui_help"):  # F1
        toggle_help()

func toggle_help():
    is_open = !is_open
    help_panel.visible = is_open
    
    if is_open:
        input_field.grab_focus()

func _on_send():
    _send_message(input_field.text)

func _on_submit(text: String):
    _send_message(text)

func _send_message(message: String):
    if message.strip_edges().is_empty():
        return
    
    add_message("You", message, Color.CYAN)
    input_field.clear()
    
    # Get context from game
    var context = get_game_context()
    var full_message = "%s\n\nGame context: %s" % [message, context]
    
    # Ask AI
    var response = await AeThexAI.ask_assistant(full_message)
    
    if response.success:
        add_message("Assistant", response.answer, Color.GREEN)
    else:
        add_message("Assistant", "Error: " + response.error, Color.RED)

func add_message(sender: String, text: String, color: Color):
    var msg = RichTextLabel.new()
    msg.bbcode_enabled = true
    msg.text = "[color=%s][b]%s:[/b] %s[/color]" % [color.to_html(), sender, text]
    msg.fit_content = true
    chat_container.add_child(msg)

func get_game_context() -> String:
    # Gather relevant game state
    var player = get_tree().get_first_node_in_group("player")
    if player:
        return "Level: %d, Health: %d, Position: %s" % [
            player.current_level,
            player.health,
            player.global_position
        ]
    return "No context available"

func setup_quick_help():
    var questions = [
        "How do I play?",
        "What are the controls?",
        "Where should I go?",
        "How do I use items?",
    ]
    
    for q in questions:
        var btn = Button.new()
        btn.text = q
        btn.pressed.connect(func(): _send_message(q))
        quick_help.add_child(btn)

Best Practices

1. Provide Context

Always include relevant game state when asking the AI:

var context = "Player is at checkpoint 3, has 50% health"
var question_with_context = "%s\nContext: %s" % [user_question, context]

2. Clear Expectations

Tell players what the AI can and cannot do:

var help_text = """
AI Assistant can help with:
- Game mechanics
- Quest objectives
- Strategy tips

Cannot help with:
- Technical support
- Account issues
"""

3. Rate Limiting

Prevent abuse with rate limiting:

const MAX_REQUESTS_PER_MINUTE = 10

4. Caching

Cache common questions to reduce API calls:

var faq_cache = {
    "how to jump": "Press Space or A button",
    "how to save": "Game auto-saves at checkpoints",
}

5. Fallback Responses

Always have fallback responses:

if not response.success:
    return "Check the tutorial at Main Menu → Help"

Advanced Features

Personality Customization

Give your AI assistant personality:

func ask_with_personality(question: String):
    var system_prompt = """
    You are a helpful wizard companion in a fantasy RPG.
    Speak in a wise, mystical tone.
    Be encouraging and friendly.
    """
    
    var response = await AeThexAI.ask_assistant(
        question,
        {"system_prompt": system_prompt}
    )
    return response

Multi-Language Support

Support multiple languages:

func ask_in_language(question: String, language: String):
    var prompt = "Answer in %s: %s" % [language, question]
    return await AeThexAI.ask_assistant(prompt)

Voice Integration

Combine with text-to-speech:

func speak_response(text: String):
    # Use DisplayServer TTS if available
    if DisplayServer.tts_is_speaking():
        DisplayServer.tts_stop()
    
    DisplayServer.tts_speak(text, "en", 50, 1.0, 1.0, 0, true)

Testing

Test your AI assistant:

# test_ai_assistant.gd
extends Node

func _ready():
    run_tests()

func run_tests():
    print("Testing AI Assistant...")
    
    # Test basic question
    var r1 = await AeThexAI.ask_assistant("How do I move?")
    assert(r1.success, "Basic question failed")
    
    # Test code generation
    var r2 = await AeThexAI.generate_code("Create a jump function")
    assert(r2.success and "func" in r2.code, "Code generation failed")
    
    print("All tests passed!")

Troubleshooting

AI not responding:

  • Check cloud connection: AeThexCloud.is_connected()
  • Verify AI service is enabled in project settings
  • Check console for error messages

Slow responses:

  • Implement request caching
  • Use loading indicators
  • Consider reducing context size

Irrelevant answers:

  • Provide more specific context
  • Use structured prompts
  • Implement feedback system

Next Steps


Summary

You've learned how to: Integrate AI assistant into your game
Create context-aware help systems
Generate code and tutorials with AI
Implement caching and rate limiting
Build an in-game help UI

The AI assistant can dramatically improve player experience by providing instant, contextual help!

Questions? Ask the AI assistant in your game! 🤖