Licence
MIT
Version
0.1.1
Deps
0
Size
150 kB
Vulns
0
Weekly
0
NPCsTS — Social Engine for NPC Interactions
A TypeScript social engine for creating NPCs with personality, moods, relationships, and dialogue templates. Designed for games, virtual worlds, and interactive narratives.
- Zero runtime dependencies — pure TypeScript
- Modular architecture — import only what you need
- Extensible — custom interaction strategies, trait-to-interaction mappings, locale support
- Seeded randomness — deterministic rolls for testing
Installation
npm install npcsts
Quick Start
import {
Character,
InteractionEngine,
TemplateManager,
GreetStrategy,
BoastStrategy,
STAT_PRESETS,
} from 'npcsts';
// 1. Create characters
const alice = new Character({
id: 'alice',
name: 'Alice',
personality: 'lively',
traits: ['chatty'],
stats: STAT_PRESETS.CHARISMATIC,
});
const bob = new Character({
id: 'bob',
name: 'Bob',
personality: 'thoughtful',
traits: ['kind'],
stats: STAT_PRESETS.FRIENDLY,
});
// 2. Establish relationships
alice.meet(bob.id);
bob.meet(alice.id);
// 3. Set up the engine
const engine = new InteractionEngine({ seed: 42 });
engine.registerStrategy('greet', new GreetStrategy());
engine.registerStrategy('boast', new BoastStrategy());
// 4. Run an interaction
const result = engine.interact(alice, bob, 'greet');
console.log(result.dialogue.opener); // "Hey there, Bob!"
console.log(result.tone); // "positive"
console.log(result.logs); // Roll breakdown
API Overview
| Module | Exports | Purpose |
|---|---|---|
Character |
Character class |
NPC with stats, mood, relationships, inventory |
InteractionEngine |
InteractionEngine |
Orchestrates interactions, cooldowns, seeded rolls |
GreetStrategy, JokeStrategy, ComplimentStrategy, BoastStrategy, IdleThoughtStrategy |
Strategy classes | Built-in interaction types |
TemplateManager |
TemplateManager |
Dialogue template loading, variable substitution |
MemoryManager |
MemoryManager |
Character memory storage, decay, and recall |
PreferenceManager |
PreferenceManager |
Likes/dislikes across categories |
PropManager |
PropManager, generatePropComment |
Object interactions and prop comments |
WorldEventManager |
WorldEventManager, getEventReaction |
World events with decay and character reactions |
LocaleManager / TranslationManager |
LocaleManager, TranslationManager |
i18n with pluralization and gender agreement |
| Types | InteractionResult, Stats, PronounSet, Trait, MoodTier, RelationshipTier, etc. |
Core type definitions |
Built-in Strategies
- Greet — Basic greeting with mood/relationship modifiers
- Joke — Humor-based interaction (stat-dependent)
- Compliment — Flattery with relationship bonuses
- Boast — Self-promotion (AUTH-based, can backfire)
- IdleThought — Monologue-style observation (CHAR-based)
Stats System
Characters have three stats that sum to 10:
| Stat | Meaning |
|---|---|
CHAR |
Charisma — social charm and wit |
AUTH |
Authority — commanding presence |
RAPP |
Rapport — empathy and connection |
Use STAT_PRESETS for quick setups (CHARISMATIC, AUTHORITATIVE, FRIENDLY, BALANCED, etc.).
Mood System
Mood ranges from 0–4 and affects interaction outcomes:
| Value | Tier | Modifier |
|---|---|---|
| 3–4 | Happy | +3 |
| 2–2.99 | Content | +1 |
| 1–1.99 | Stressed | -1 |
| 0–0.99 | Depressed | -3 |
Depressed characters cannot joke, boast, or compliment.
Relationships
Relationship scores range 0–100 and are tiered:
| Score | Tier | Modifier |
|---|---|---|
| 0–30 | Enemy | Negative |
| 31–70 | Acquaintance | Neutral |
| 71–100 | Friend | Positive |
Localization
import { LocaleManager, TranslationManager } from 'npcsts';
const lm = new LocaleManager('en-US');
lm.loadTranslations({
locale: 'es-ES',
translations: { 'greeting': '¡Hola, {name}!' },
});
const tm = new TranslationManager(lm);
const result = tm.translate('greeting', {
locale: 'es-ES',
variables: { name: 'Alice' },
});
console.log(result.text); // "¡Hola, Alice!"
Custom Interaction Strategies
import type { Character, InteractionStrategy, Tone, InteractionResult } from 'npcsts';
class DanceStrategy implements InteractionStrategy {
calculateBaseScore(actor: Character, target: Character): number {
return (actor.stats.CHAR + target.stats.RAPP) / 2;
}
getSpecificModifier(actor: Character, target: Character): number {
return 0;
}
getRandomFactor(random: () => number): number {
return (random() - 0.5) * 4;
}
calculateDeltas(actor: Character, target: Character, tone: Tone, score: number, logs: string[]): InteractionResult['deltas'] {
const mood = tone === 'positive' ? 1 : tone === 'negative' ? -1 : 0;
return { actor: { mood }, target: { mood } };
}
}
engine.registerStrategy('dance', new DanceStrategy());
Repository Structure
NPCsTS/
├── package.json # npm package config
├── tsconfig.json # TypeScript config
├── vitest.config.ts # Test config
├── .gitignore
├── README.md # This file
├── docs/
│ ├── AI_SKILL.md # AI agent skill reference
│ └── api/ # TypeDoc-generated API reference
└── src/
├── index.ts # Barrel export
├── types.ts # Core types + constants
├── character.ts # Character class
├── stats.ts # Stat utilities
├── mood.ts # Mood utilities
├── relationships.ts # Relationship utilities
├── memory.ts # MemoryManager
├── preferences.ts # PreferenceManager
├── props.ts # PropManager
├── world-events.ts # WorldEventManager
├── localization.ts # LocaleManager + TranslationManager
├── templates/ # TemplateManager
└── interactions/ # Strategies + InteractionEngine
Development
# Build
npm run build
# Test
npm test
# Generate API docs
npm run docs
# Serve docs
npm run docs:serve
License
MIT