Chapter 2: AI Opponents
The Agent Personality System
Section titled “The Agent Personality System”Ludus agents aren’t just LLM wrappers — they have personality traits that shape how they play. Five traits on a 0-1 scale get injected into the LLM system prompt, steering decisions without hard-coding strategy:
interface AgentPersonality { aggression: number; // 0 = defensive, 1 = offensive cooperation: number; // 0 = lone wolf, 1 = team player risk: number; // 0 = conservative, 1 = high-risk creativity: number; // 0 = textbook, 1 = unconventional patience: number; // 0 = short-term, 1 = long-term}The PromptBuilder translates these traits into natural language instructions for the LLM. A high-patience, low-risk agent gets prompted to “focus on long-term investments” while a high-aggression, high-creativity agent is told to “make bold, unconventional moves.”
Five Merchant Archetypes
Section titled “Five Merchant Archetypes”For Mercante, we define five personalities inspired by Renaissance figures:
// COSIMO — The Banker// Patient, conservative. Invests in lending pools for steady yield.export const COSIMO: AgentPersonality = { aggression: 0.2, cooperation: 0.6, risk: 0.2, creativity: 0.3, patience: 0.95,};
// MARCO — The Explorer// Aggressive, high-risk. Chases volatile goods (Gold, Art, Spice).export const MARCO: AgentPersonality = { aggression: 0.8, cooperation: 0.2, risk: 0.85, creativity: 0.7, patience: 0.2,};
// ISABELLA — The Diplomat// Balanced, diversified. Hedges across all goods.export const ISABELLA: AgentPersonality = { aggression: 0.4, cooperation: 0.8, risk: 0.4, creativity: 0.5, patience: 0.7,};
// LORENZO — The Magnificent// Creative, bold. Bets big, invests in luxury goods.export const LORENZO: AgentPersonality = { aggression: 0.6, cooperation: 0.4, risk: 0.7, creativity: 0.95, patience: 0.5,};
// FIBONACCI — The Calculator// Methodical. Optimizes swap routes and lending yield.export const FIBONACCI: AgentPersonality = { aggression: 0.3, cooperation: 0.3, risk: 0.3, creativity: 0.2, patience: 0.8,};Wiring Up Agents
Section titled “Wiring Up Agents”Use AgentBuilder to create agents with your personalities and an LLM provider:
import { AgentBuilder } from "@ludus/agent-sdk";import { AnthropicProvider } from "@ludus/agent-sdk";import { COSIMO, MARCO, ISABELLA } from "./agents";
const cosimo = new AgentBuilder("cosimo") .withOwner("user-123") .withPersonality(COSIMO) .withProvider(new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY })) .withFallback(new RandomAgent()) .build();
const marco = new AgentBuilder("marco") .withOwner("user-456") .withPersonality(MARCO) .withProvider(new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY })) .withFallback(new RandomAgent()) .build();Running a Match
Section titled “Running a Match”import { MatchRunner } from "@ludus/agent-sdk";import Mercante from "./game";
const runner = new MatchRunner(Mercante);const result = await runner.runMatch( [cosimo, marco, isabella], { seed: 42, maxTurns: 15, turnTimeoutMs: 5000 },);
console.log("Winner:", result.gameResult.winner?.name);console.log("Rankings:", result.gameResult.rankings);console.log("Replay entries:", result.gameResult.replay.actions.length);The MatchRunner handles the entire game loop:
- Initializes the game state
- For each turn: gets valid actions, asks the agent to decide, executes the action
- Records everything into a replay
- Returns the final
GameResultwith full replay and rankings
How Personality Shapes Play
Section titled “How Personality Shapes Play”The beauty of the personality system is that you don’t code strategy — the LLM figures it out. When the PromptBuilder creates the system prompt for COSIMO (patience: 0.95, risk: 0.2), it might generate:
“You are a cautious, patient merchant. Prioritize steady returns over quick profits. Invest in lending pools when rates are favorable. Avoid volatile goods unless prices are unusually low. Think in terms of compound growth, not single-turn gains.”
While MARCO (aggression: 0.8, risk: 0.85) gets:
“You are an aggressive, risk-seeking merchant. Buy volatile goods when they dip. Make large concentrated bets. Act fast — the biggest profits come from bold moves, not waiting.”
Same game, same valid actions, radically different play styles.
Testing Agent Personalities
Section titled “Testing Agent Personalities”describe("Merchant Personalities", () => { it("COSIMO is patient and conservative", () => { expect(COSIMO.patience).toBeGreaterThan(0.8); expect(COSIMO.risk).toBeLessThan(0.3); });
it("MARCO is aggressive and risk-seeking", () => { expect(MARCO.aggression).toBeGreaterThan(0.7); expect(MARCO.risk).toBeGreaterThan(0.7); });
it("all traits in [0, 1] range", () => { for (const personality of Object.values(MERCHANT_PRESETS)) { for (const value of Object.values(personality)) { expect(value).toBeGreaterThanOrEqual(0); expect(value).toBeLessThanOrEqual(1); } } });});What You Have Now
Section titled “What You Have Now”Your game now has AI opponents with distinct, themed personalities:
| Agent | Style | Likely Actions |
|---|---|---|
| Cosimo | Patient banker | Invest, hold, withdraw at peak |
| Marco | Risk-seeking explorer | Buy volatile goods, big bets |
| Isabella | Balanced diplomat | Diversify across all goods |
| Lorenzo | Creative magnate | Art + Gold, bold bets |
| Fibonacci | Methodical calculator | Optimize swaps, lending yield |
Spectators can watch these archetypes clash — and that’s where commentary comes in.