Object-Oriented Prompt Engineering for JavaEst. 2026 · MIT License
PrOOPt

“A Java library that keeps LLMs on a need-to-know basis.”

Use Case · States No. 1

The World That Remembers

Persistent, society-scale NPC populations.

The Story

For forty years, game characters have forgotten you the moment you walked away. The guard who watched you rob the granary greets you the next morning with the same two lines of dialogue he has said since the day the game shipped. He is not a character. He is a doorbell.

The World That Remembers gives every character in a game world a persistent, LLM-managed inner life. Each NPC is a @Persona POJO whose @Trait fields — morale, suspicion, loyalty, memory — are updated by an LLM and persisted to a database. Guards accumulate grievances. Rumours of the player's deeds spread through taverns, getting less accurate with each retelling. Allegiances shift on schedule. And at night, while the server is quiet, the characters process what happened to them and wake up slightly different.

The first world that remembers, gossips, holds grudges — and dreams.

How It Is Built

Three capabilities, never before shipped together, carry the whole design.

Gossip with physics

guards.phaseManager().broadcast(
    crimeWitnessed,
    EventPipeline.create()
        .blastRadius(BlastRadius.WITNESSED
                         .union(BlastRadius.FACTION))
        .attenuation(AttenuationModel.RUMOUR)
        .timing(EventTiming.IMMEDIATE)
        .minSeverity(EventSeverity.WARNING));

Information becomes a simulated, decaying medium. Witnesses know what they saw; their faction hears a version of it; and AttenuationModel.RUMOUR applies the classic rumour psychology — details flatten, drama sharpens, and the story bends to fit what each listener already believed. One declarative pipeline, and your world has a grapevine.

NPCs that dream

@Persona(internalLoop = true, loopSchedule = "@daily", loopDepth = LoopDepth.SHALLOW) means that during quiet hours, each character consolidates the day's encounters into trait changes — tagged UpdateSource.INTERNAL_LOOP in the history table. A weekly DEEP loop reaches genuine belief revision: this is where a loyal guard, after a month of unpaid wages and unsettling rumours, quietly stops being a loyal guard.

The society is a database

List<GuardNpc> mutinous = guards.loadWhere(
    "morale < 20 AND political_sympathy < -40 AND fatigue > 70");

Designers query disposition the way they query inventory, target events with WHERE clauses, and read EvolutionReports — inflection points, trait correlations, forward projections — as production telemetry for souls. Deterministic game logic stays in charge through @OnPersonaEvent thresholds:

@PersonaSubscriber
public class CityAlertService {

    @OnPersonaEvent(persona = GuardNpc.class,
                    type = PersonaEventType.THRESHOLD_CROSSED,
                    trait = "suspicion", threshold = 80,
                    direction = Direction.ABOVE)
    public void lockdown(TraitChangeEvent<GuardNpc> e) {
        world.triggerGateLockdown(e);
    }

    @OnPersonaEvent(persona = GuardNpc.class,
                    type = PersonaEventType.POPULATION_TREND,
                    trend = Trend.FALLING)
    public void watchCollapse(PopulationTrendEvent e) {
        story.unlockMutinyArc();
    }
}

Why It Is Unprecedented

“Emergent narrative” has historically been a polite euphemism for randomness. Here it stops being one: it is threshold mechanics over LLM-managed psychology, with an audit trail. The designer's relationship to the game changes from scripting characters to authoring a society — writing the laws of how feelings move, then reading the chronicles of what happened. No game-AI stack has ever offered persistent state, social transmission with distortion, and database-grade queryability in one system. This is a game world with a paper trail.

The Fine Print

The local tier bounds per-NPC eloquence — this design is about state (memory, disposition, society); dialogue generation is a separable concern. LLM-managed psychology can drift implausibly, which is why PersonaUpdateVetoException exists: the designer's hard veto on nonsense. And a society that genuinely evolves can evolve away from the fun — the nightly authorial rules are the steering wheel, and they are mandatory authorship, not optional seasoning.