Playprint Docs
Dashboard Home

Quickstart — Profile a Player in 5 Minutes

This guide walks you through installing @playprint/core, recording decisions during gameplay, and extracting a player's behavioural profile. No server, no API key, no backend required.

1. Install the SDK

npm install @playprint/core

2. Track Decisions During Gameplay

import { PlayprintTracker, createGhost, getArchetype } from '@playprint/core';

const tracker = new PlayprintTracker({ gameId: 'my_game' });

// Start a match
tracker.startMatch();

// Record decisions as they happen (Tier 1: just a label)
tracker.decision({ label: 'attack' });           // risk inferred: 0.7
tracker.decision({ label: 'defend' });            // risk inferred: 0.2
tracker.decision({ label: 'bluff', risk: 0.9, information: 0.3 }); // Tier 2: you set risk

// Record outcomes
tracker.outcome({ type: 'hit', delta: 0.5 });
tracker.outcome({ type: 'block', delta: -0.2 });

// End the match — returns the updated profile
const profile = await tracker.endMatch('win');
console.log(profile);
// { aggressive: 0.72, bold: 0.55, deceptive: 0.33, chaotic: 0.41, urgent: 0.68, expansive: 0.29 }
B biff_legend

You don't need to compute risk values yourself. Tier 1 input ({ label: 'attack' }) automatically infers risk from a built-in keyword map. "attack" → 0.7, "defend" → 0.2, "gamble" → 0.9, etc. You can customize with the riskMap option if needed.

3. Generate a Ghost AI Opponent

import { createGhost, mapGhostBiases } from '@playprint/core';

// Convert profile → 8 bias weights (6 core + 2 comms)
const ghost = createGhost(profile);
// { aggression: 0.72, patience: 0.28, riskTolerance: 0.65,
//   consistency: 0.8, deception: 0.15, reach: 0.29,
//   expressiveness: 0, provocation: 0 }

// With comms data — the ghost also knows how to talk
const ghost = createGhost(profile, commsProfile);
// { ...core biases, expressiveness: 0.57, provocation: 0.68 }

// Map biases to your game's AI parameters
const aiParams = mapGhostBiases(ghost, {
  attackFrequency:  { bias: 'aggression',     range: [0.1, 0.9] },
  retreatThreshold: { bias: 'patience',       range: [0.2, 0.8] },
  bluffChance:      { bias: 'deception',      range: [0, 0.3] },
  emoteFrequency:   { bias: 'expressiveness', range: [0, 0.8] },
  tauntChance:      { bias: 'provocation',    range: [0, 0.5] },
});

4. Classify the Player's Archetype

import { deriveTraits, generateArchetype } from '@playprint/core';

const traits = deriveTraits(profile);
const archetype = generateArchetype(traits);
// {
//   coreArchetype: 'Berserker',
//   styleModifier: 'Reckless',
//   displayName: 'Reckless Berserker',
//   tempoTag: 'Burst player',
//   behaviors: ['Overwhelms with relentless speed'],
//   tagline: 'Charges in hard and trusts instinct over strategy.',
// }
W wiki_legend

For richer archetypes, use generateArchetype() instead — it produces 5-layer personality descriptions with 12 possible core types (Berserker, Ghost, Daredevil, Sentinel, Phantom, Purist, etc.), style modifiers, tempo tags, behaviour phrases, and taglines.

Decision Input Tiers

The SDK supports three levels of detail for recording decisions:

TierInputWhen to Use
1{ label }Quick integration — risk inferred from label keywords
2{ label, risk, information }You compute your own risk/info values (0–1)
3Full DecisionPayloadComplete control over all fields (risk, information, tempo, intent_tags)

Storage

By default, match data is stored in memory (lost on page reload). For persistence:

import { PlayprintTracker, LocalStorageAdapter } from '@playprint/core';

const tracker = new PlayprintTracker({
  gameId: 'my_game',
  storage: new LocalStorageAdapter(),  // persists to browser localStorage
});

Implement the StorageAdapter interface for custom backends (database, IndexedDB, API, etc.).

Next Steps

  • Read the Core Concepts to understand traits, archetypes, and ghost AI
  • See the API Reference for all exported classes, functions, and types
  • Check the Compliance page for privacy and data handling details