# AI Assistant Tutorial

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

> [!TIP]
> The AI Assistant can understand your game's context, player actions, and current state to provide relevant and helpful responses.

---

## 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

```mermaid
graph LR
    Player[👤 Player] -->|Asks Question| UI[Chat UI]
    UI -->|Send Message| AI[⚡ AI Service]
    AI -->|Context| Game[Game State]
    AI -->|Generate| Response[AI Response]
    Response -->|Display| UI
    
    style Player fill:#00ffff22,stroke:#00ffff
    style AI fill:#ff00ff22,stroke:#ff00ff
    style Game fill:#00ffff22,stroke:#00ffff
```

---

## Prerequisites

- Completed [First Game Tutorial](FIRST_GAME_TUTORIAL.md)
- AeThex Cloud connection set up
- Basic understanding of UI systems

> [!WARNING]
> AI features require an active AeThex Cloud connection. Make sure you're authenticated before using AI services.

---

## Step 1: Connect to AI Service

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

> [!NOTE]
> AeThex Cloud handles all AI infrastructure, rate limiting, and caching automatically.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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.

```gdscript
# 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:

```gdscript
# 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:
```gdscript
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:
```gdscript
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:
```gdscript
const MAX_REQUESTS_PER_MINUTE = 10
```

### 4. **Caching**
Cache common questions to reduce API calls:
```gdscript
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:
```gdscript
if not response.success:
    return "Check the tutorial at Main Menu → Help"
```

---

## Advanced Features

### Personality Customization

Give your AI assistant personality:
```gdscript
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:
```gdscript
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:
```gdscript
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:

```gdscript
# 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

- **[Authentication Tutorial](AUTH_TUTORIAL.md)** - Add user accounts
- **[Analytics Tutorial](ANALYTICS_TUTORIAL.md)** - Track AI usage
- **[API Reference](../API_REFERENCE.md#aethexai-singleton)** - Complete AI API docs

---

## 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! 🤖
