Files

9.0 KiB

Architettura

Panoramica

MUDlet AI Client usa un'architettura a 3 layer basata su Electron:

┌─────────────────────────────────────────────────────────┐
│                    ELECTRON MAIN                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐ │
│  │ TelnetService│  │ OllamaService│  │ AutoplayerService│ │
│  └──────┬──────┘  └──────┬──────┘  └────────┬────────┘ │
│         │                │                   │          │
│         └────────────────┼───────────────────┘          │
│                          ▼                              │
│              ┌─────────────────────┐                    │
│              │   IPC Handlers      │                    │
│              └─────────┬───────────┘                    │
└────────────────────────┼────────────────────────────────┘
                         │
┌────────────────────────┼────────────────────────────────┐
│                  PRELOAD JS                               │
│         contextBridge.exposeInMainWorld()                 │
└────────────────────────┼────────────────────────────────┘
                         │
┌────────────────────────┼────────────────────────────────┐
│                    REACT RENDERER                         │
│  ┌─────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   App   │  │ GameWindow  │  │  AutoplayerPanel    │  │
│  └─────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────┘

Layer 1: Electron Main Process

Main Entry (src/main/index.ts)

Responsabilità:

  • Inizializzazione finestra BrowserWindow
  • Setup IPC handlers
  • Event forwarding tra servizi e renderer
  • Lifecycle management (app ready, window closed, etc.)
// Flusso dati Telnet
telnetService.on('output', (data) => {
  mainWindow.webContents.send('telnet-output', data);
  autoplayerService.processOutput(data);  // Forward all'autoplayer
});

TelnetService (src/main/services/TelnetService.ts)

Wrapper attorno a telnet-client con funzionalità aggiuntive:

Metodo Descrizione
connect(host, port) Stabilisce connessione Telnet
send(data) Invia comando al server
getOutput() Restituisce buffer output
parseAnsiCodes(text) Converte ANSI escape codes in HTML

Eventi:

  • output - Emesso quando arrives nuovo output
  • connected - Connessione stabilita
  • disconnected - Connessione chiusa
  • error - Errore di connessione

Parsing ANSI:

// ansicolor converte sequenze ANSI in spans colorati
// Ogni span viene convertito in <span style="...">

OllamaService (src/main/services/OllamaService.ts)

Client HTTP per Ollama API. Supporta:

Metodo Descrizione
chat(messages, options) Chat singola, attesa risposta
chatStream(messages, options) Streaming response token-by-token
getLocalModels() Lista modelli disponibili
isAvailable() Check server reachability

API Endpoint:

POST http://ollama.solarpi.net/api/chat
{
  "model": "llama3.2",
  "messages": [...],
  "stream": true,
  "options": {
    "temperature": 0.7,
    "num_predict": 512
  }
}

AutoplayerService (src/main/services/AutoplayerService.ts)

Decision engine che orchestrate il loop autoplayer:

┌─────────────────────────────────────────────────────────┐
│                    AUTOPLAYER LOOP                      │
│                                                         │
│  1. OBSERVE  ← processOutput(output)                   │
│  2. PARSE    ← parseGameState()                         │
│  3. THINK    ← ollamaService.chat()                     │
│  4. DECIDE   ← extractAction()                          │
│  5. ACT      ← executeAction() / queueAction()          │
│                                                         │
└─────────────────────────────────────────────────────────┘

Configurazione:

interface AutoplayerConfig {
  model: string;           // Model LLM da usare
  systemPrompt: string;    // Comportamento del bot
  temperature: number;     // Creatività (0.0-1.0)
  autoSend: boolean;       // Auto-esegui azioni
}

Game State Parser:

parseGameState(output: string): GameState {
  // Estrae: location, exits, players, objects, description
}

Decision Prompt:

Context: [ultimi 30 righe output]
Sei in: [location]
Uscite disponibili: north, south, east

Cosa fai? (rispondi SOLO con il comando)

Layer 2: Preload Script

espone API sicure al renderer tramite contextBridge:

// Telnet
telnetConnect(host, port)
telnetSend(data)
onTelnetOutput(callback)

// Ollama
ollamaChat(messages, options)
ollamaGetModels()
ollamaIsAvailable()

// Autoplayer
autoplayerConfigure(config)
autoplayerStart()
autoplayerStop()
autoplayerExecuteAction(action)
onAutoplayerDecision(callback)
onAutoplayerAction(callback)

Layer 3: React Renderer

App (src/renderer/App.tsx)

Root component con navigation:

// Navigation state
const [activePanel, setActivePanel] = useState<'connection' | 'game' | 'autoplayer'>();

// Connection status
const [isConnected, setIsConnected] = useState(false);

GameWindow (src/renderer/components/GameWindow.tsx)

Display principale del gioco:

Componente Funzione
Output div Visualizza output HTML con colors
Form Input comandi + submit
Auto-scroll Mantiene focus su output recente
// Subscribe a output Telnet
useEffect(() => {
  window.electronAPI.onTelnetOutput((data) => {
    setOutput(prev => prev + data);
  });
}, []);

AutoplayerPanel (src/renderer/components/AutoplayerPanel.tsx)

Pannello controllo autoplayer:

Feature UI
Toggle On/Off Switch button
Model selection Dropdown (da Ollama)
System prompt Textarea modificabile
Live status Ultime decisioni/azioni
Ollama availability Check automatico

Flusso Dati

Telnet → UI

1. Telnet server → telnet-client
2. TelnetService → emits 'output'
3. Main process → ipcRenderer.send('telnet-output')
4. GameWindow → onTelnetOutput callback
5. React state → setOutput()
6. Render → HTML display

Autoplayer Decision

1. Output Telnet arrives
2. AutoplayerService.processOutput()
3. parseGameState() → GameState { location, exits, ... }
4. shouldMakeDecision() → true/false
5. ollamaService.chat(messages)
6. extractAction() → "go north"
7. autoSend ? executeAction() : queueAction()
8. Events: 'decision', 'action'
9. UI updates: lastDecision, lastAction

Configurazione

Environment

  • Server Ollama: http://ollama.solarpi.net (hardcoded)
  • LPMUD default: 172.24.19.225:6666

Tipi Condivisi

// src/main/services/AutoplayerService.ts
interface GameState {
  location: string;
  description: string;
  exits: string[];
  players: string[];
  objects: string[];
  health?: string;
  mana?: string;
  prompt?: string;
}

interface OllamaMessage {
  role: 'user' | 'assistant' | 'system';
  content: string;
}

Limitazioni Attuali

Componente Limitation Piani
ANSI Parsing Solo colori basic Parser completo
Game Parser Regex-based, fragile ML parser
Autoplayer No memory persistent SQLite storage
Mapper Non implementato Fase 3
Triggers Non implementati Fase 3
Plugins Non implementati Fase 4