Skip to content
Tuxedo CatSTUDIO
Menu

API Overview

Probability Director provides a Game Instance-scoped probability and random-decision runtime for supported Unreal Engine versions (see Compatibility). It is designed to give gameplay code one consistent API for deterministic and secure random streams, keyed deterministic decisions, dice resolution, reusable Resolution Rules Data Assets, probability analysis, statistical distributions, Bias, and procedural name generation.

This document is the recommended starting point for developers using Probability Director from Blueprint or C++. It explains how the public API is organized, how to obtain the subsystem, how stream lifecycle works, how to choose between Sequential and Keyed operations, how failures are reported, and which internal capabilities are intentionally not public.

For deeper subject-specific details, use the dedicated documentation for Streams, Dice, Data Assets, Distributions, Bias, Markov/Names, Persistence, Diagnostics/Warnings, and the Probability Director Runtime Inspector.

Use this index to jump directly from a Blueprint node or C++ function to the section that explains its purpose and usage.

The tables list every explicitly named Blueprint node and C++ function in this overview. Where this overview describes an API family without giving every reflected/native function name, the family is listed separately rather than inventing names that are not documented here.

Area Blueprint node / API Documentation
Streams Create Stream Create Stream
Streams Has Stream Has Stream
Streams Get Stream Configuration Get Stream Configuration
Streams Get Stream IDs Get Stream IDs
Streams Remove Stream Remove Stream
Random Sequential random numeric nodes Random API
Random Keyed random numeric nodes Random API
Dice Resolve Sequential Single Numeric Die Single Numeric Die
Dice Resolve Keyed Single Numeric Die Single Numeric Die
Dice Resolve Sequential Numeric Dice Total Numeric Dice Total
Dice Resolve Keyed Numeric Dice Total Numeric Dice Total
Dice Resolve Sequential Numeric Dice Success Count Numeric Dice Success Count
Dice Resolve Keyed Numeric Dice Success Count Numeric Dice Success Count
Resolution Rules Resolve Sequential Numeric Rules Total Resolution Rules
Resolution Rules Resolve Persistent Keyed Numeric Rules Total Resolution Rules
Resolution Rules Resolve Sequential Numeric Rules Success Count Resolution Rules
Resolution Rules Resolve Persistent Keyed Numeric Rules Success Count Resolution Rules
Dice Make Standard Numeric Dice Pipeline Dice API
Dice Bias Make Probability Dice Bias Dice Bias API
Probability Exact probability query nodes Probability API
Distributions Distribution evaluation nodes Distribution evaluation
Distributions Sequential distribution sampling nodes Distribution sampling
Distributions Keyed distribution sampling nodes Distribution sampling
Probability Bias Probability Bias nodes Probability Bias API
Probability Bias Compose Probability Bias Contributions Generic Bias and Ranked Selection
Ranked Selection Sequential and Keyed ranked weighted selection Generic Bias and Ranked Selection
Distribution Bias Distribution Parameter Bias nodes Distribution Parameter Bias API
Names / Markov Generate Name Sequential Sequential name generation
Names / Markov Generate Name Keyed Keyed name generation
Names / Markov Generate N-Gram Names Simple isolated batch generation
Names / Markov Generate Weighted Syllable Names Simple isolated batch generation
Area C++ function / API Documentation
Streams CreateStream Create Stream
Streams HasStream Has Stream
Streams GetStreamConfiguration Get Stream Configuration
Streams GetStreamIds Get Stream IDs
Streams RemoveStream Remove Stream
Random Public Sequential bounded-random methods Random API
Random Public Keyed bounded-random methods Random API
Dice Sequential single numeric die resolver API Single Numeric Die
Dice Keyed single numeric die resolver API Single Numeric Die
Dice ResolveSequentialNumericDicePipeline Numeric Dice Total
Dice ResolveKeyedNumericDicePipeline Numeric Dice Total
Dice Sequential Success Count pool resolver API Numeric Dice Success Count
Dice Keyed Success Count pool resolver API Numeric Dice Success Count
Dice Bias Native FProbabilityDiceBias API Dice Bias API
Resolution Rules TryResolveNumericRulesTotal Resolution Rules
Resolution Rules TryResolveNumericRulesSuccessCount Resolution Rules
Probability Native exact probability APIs Probability API
Distributions TrySampleSequentialBernoulli Distribution API
Distributions TrySampleKeyedBernoulli Distribution API
Distributions TrySampleSequentialBinomial Distribution API
Distributions TrySampleKeyedBinomial Distribution API
Distributions TrySampleSequentialPoisson Distribution API
Distributions TrySampleKeyedPoisson Distribution API
Distributions TrySampleSequentialContinuousUniform Distribution API
Distributions TrySampleKeyedContinuousUniform Distribution API
Distributions TrySampleSequentialTriangular Distribution API
Distributions TrySampleKeyedTriangular Distribution API
Distributions TrySampleSequentialExponential Distribution API
Distributions TrySampleKeyedExponential Distribution API
Distributions TrySampleSequentialNormal Distribution sampling
Distributions TrySampleKeyedNormal Distribution sampling
Distributions TrySampleSequentialGamma Distribution API
Distributions TrySampleKeyedGamma Distribution API
Distributions TrySampleSequentialChiSquare Distribution API
Distributions TrySampleKeyedChiSquare Distribution API
Distributions TrySampleSequentialBeta Distribution API
Distributions TrySampleKeyedBeta Distribution API
Exact Mass Sampling Sequential numeric exact-mass sampling API Generic Exact Mass Sampling in C++
Exact Mass Sampling Keyed numeric exact-mass sampling API Generic Exact Mass Sampling in C++
Exact Mass Sampling Sequential categorical exact-mass sampling API Generic Exact Mass Sampling in C++
Exact Mass Sampling Keyed categorical exact-mass sampling API Generic Exact Mass Sampling in C++
Probability Bias Native FProbabilityBiasMath API Probability Bias API
Distribution Bias Native FProbabilityDistributionBiasMath API Distribution Parameter Bias API
Weighted Outcome Bias Native FProbabilityWeightedOutcomeBiasMath API Weighted Outcome Bias
Ranked Selection TrySelectSequentialRankedWeighted Generic Bias and Ranked Selection
Ranked Selection TrySelectKeyedRankedWeighted Generic Bias and Ranked Selection
Probability Bias Native FProbabilityBiasComposer API Generic Bias and Ranked Selection
Names / Markov AnalyzeMarkovState Name and Markov API
Names / Markov SampleMarkovTransitionSequential Name and Markov API
Names / Markov SampleMarkovTransitionKeyed Name and Markov API
Names / Markov AnalyzeNameModel Name and Markov API
Names / Markov GenerateNameSequential Sequential name generation
Names / Markov GenerateNameKeyed Keyed name generation

API Families Without Exact Function Names in This Overview

Section titled “API Families Without Exact Function Names in This Overview”

A few sections intentionally describe a public API family without spelling out every reflected/native symbol. Those entries are still indexed above, but their exact names should be taken from the corresponding Runtime header or subject-specific documentation rather than inferred here. This applies especially to:

  • General Blueprint Random nodes.
  • Blueprint Probability evaluation nodes.
  • Blueprint Distribution evaluation/sampling nodes.
  • Native single-die and Success Count resolver overloads.
  • Native generic exact-mass sampling overloads.
  • Ranked weighted selection and resolved-bias composition APIs.
  • Individual methods on the native Bias math types.


Probability Director exists to centralize probability and random-decision behavior that would otherwise be spread across ad hoc random calls, Blueprint utility functions, local FRandomStream instances, or one-off gameplay implementations.

Use it when you need one or more of the following:

  • Reproducible random behavior from a Fixed Seed.
  • Secure runtime randomness without exposing secret seed material.
  • Multiple independent gameplay random streams.
  • Deterministic Keyed decisions that do not depend on call order.
  • Exact probability calculations.
  • Numeric dice, dice pools, modifiers, Dice Bias, rerolls, explosions, selection, or Success Count resolution.
  • Bernoulli, Binomial, Poisson, Uniform, Triangular, Exponential, Normal, Gamma, Chi-square, or Beta distribution evaluation and sampling.
  • Probability Bias or supported distribution-parameter Bias.
  • Markov or weighted-syllable name generation.
  • Structured failures instead of silent clamping or undefined behavior.
  • Game Instance isolation, including safe multi-PIE behavior.
  • Sanitized runtime diagnostics without exposing secure RNG state.

Probability Director is not intended to replace gameplay authority, networking, save-slot orchestration, or application-specific rules about what a random result means.


The basic runtime model is:

  1. Unreal creates one UProbabilityDirectorSubsystem for each UGameInstance.
  2. Gameplay creates named Probability Director streams.
  3. Each stream has an authored configuration, including its decision mode and seed source.
  4. Gameplay calls either:- Sequential operations, which advance that stream’s random sequence, or- Keyed operations, which derive a result from an explicit Decision Key rather than a persistent sequential cursor.
  5. Probability Director validates the request, performs the requested operation, and returns a structured result/status.
  6. The Game Instance owns the subsystem lifetime. Destroying the Game Instance destroys that runtime context.

There is no process-global Probability Director singleton.

This matters in PIE and multi-PIE: two Game Instances have two independent Probability Director subsystems, even if they use the same Stream IDs and configuration.


Normal Blueprint gameplay should use the target-free Probability Director nodes exposed through UProbabilityDirectorWorldContextBlueprintLibrary.

The WorldContextObject pin is hidden. Unreal supplies the current world context, and the facade resolves the correct UProbabilityDirectorSubsystem from the current World and GameInstance.

This means normal Actor Blueprints and Level Blueprints do not need a manually wired Probability Director Subsystem Target pin.

Typical Blueprint categories include:

  • Probability Director|Streams
  • Probability Director|Random
  • Probability Director|Dice
  • Probability Director|Dice|Presets
  • Probability Director|Probability
  • Probability Director|Distributions
  • Probability Director|Bias
  • Probability Director name/Markov categories

Older direct-subsystem Blueprint nodes remain loadable for serialized compatibility, but the world-context facade is the normal authoring path.

C++ gameplay code normally resolves the Game Instance subsystem directly.

#include "ProbabilityDirectorSubsystem.h"
#include "Engine/GameInstance.h"
#include "Engine/World.h"
UProbabilityDirectorSubsystem* GetProbabilityDirector(UObject* WorldContextObject)
{
if (!WorldContextObject)
{
return nullptr;
}
UWorld* World = WorldContextObject->GetWorld();
if (!World)
{
return nullptr;
}
UGameInstance* GameInstance = World->GetGameInstance();
if (!GameInstance)
{
return nullptr;
}
return GameInstance->GetSubsystem<UProbabilityDirectorSubsystem>();
}

At a call site:

UProbabilityDirectorSubsystem* Probability = GetProbabilityDirector(this);
if (!Probability)
{
// The current object has no valid Game Instance runtime context.
return;
}

Do not cache a subsystem pointer in a process-global or static variable. If you retain a reference, its lifetime must not outlive the owning Game Instance.


For most Blueprint calls, you do not obtain the subsystem manually.

Actor / Level Blueprint
|
+--> Probability Director node
|
+--> hidden World Context resolves current Game Instance
|
+--> UProbabilityDirectorSubsystem

This is the preferred pattern for:

  • Stream lifecycle nodes.
  • Sequential and Keyed random operations.
  • Dice resolution.
  • Distribution sampling.
  • Name generation.
  • Other stateful gameplay operations exposed by the world-context facade.

If an advanced workflow genuinely needs a subsystem reference, use Unreal’s Game Instance Subsystem access for Probability Director Subsystem.

Do not use a subsystem reference obtained from one PIE/Game Instance in another PIE/Game Instance.

Do not build a Blueprint global variable that assumes there is one Probability Director subsystem for the whole process.


Probability Director does not require a separate Start, Boot, or Initialize Session call.

The subsystem lifecycle follows the owning UGameInstance:

Game Instance created
|
+--> Probability Director subsystem created
|
+--> Create gameplay streams
|
+--> Perform probability/random operations
|
+--> Remove temporary streams when appropriate
|
Game Instance shutdown
|
+--> subsystem and remaining runtime stream state are destroyed

The first developer-managed lifecycle is therefore the stream lifecycle.


The normal Blueprint lifecycle nodes are:

  • Create Stream
  • Has Stream
  • Get Stream Configuration
  • Get Stream IDs
  • Remove Stream

A stream is identified by FProbabilityStreamId.

A stream configuration defines the runtime contract for that Stream ID, including the selected seed source, decision mode, persistence policy, and Fixed Seed where applicable.

There is no hidden default gameplay stream. Gameplay should deliberately create and select the stream it intends to use.


Purpose: Register a Stream ID and its configuration with the current Game Instance’s Probability Director subsystem.

Create long-lived gameplay streams during a stable initialization point such as Game Instance startup, a gameplay manager’s initialization, or the BeginPlay of an authoritative owner.

Do not create and destroy a new stream for every random draw.

Event BeginPlay
|
+--> Create Stream
Stream Id: Combat.Damage
Seed Source: Secure
Decision Mode: Sequential
Persistence Policy: <project choice>
|
+--> Check the returned success/status before using the stream

For deterministic testing:

Event BeginPlay
|
+--> Create Stream
Stream Id: Combat.Damage
Seed Source: Fixed
Fixed Seed: 12345
Decision Mode: Sequential
FProbabilityStreamConfig Config;
// Configure Config with:
// - StreamId
// - SeedSource
// - DecisionMode
// - PersistencePolicy
// - FixedSeed when Fixed is selected
Probability->CreateStream(Config);

Use the status/result returned by the public declaration in ProbabilityDirectorSubsystem.h. Do not assume a create request succeeded merely because the Stream ID was non-empty.

Use stable semantic IDs:

Combat.Damage
Combat.Critical
Loot.DropTable
AI.Decision
World.Encounters
Names.Characters

Avoid IDs based on temporary Actor names, pointer values, array positions, or transient object numbering.


Purpose: Test whether the selected Game Instance currently has a registered stream.

Has Stream
Stream Id: Loot.DropTable
|
+--> True -> perform the operation
|
+--> False -> create the stream or report configuration error
if (!Probability->HasStream(StreamId))
{
// The requested runtime stream has not been created in this Game Instance.
return;
}

Use Has Stream for lifecycle validation, not as a substitute for handling the status returned by the sampling operation itself.


Purpose: Read the registered configuration for a Stream ID.

This is useful when:

  • Debugging why a call was rejected.
  • Verifying Sequential versus Keyed mode.
  • Inspecting Fixed versus Secure configuration.
  • Building developer tools.
  • Confirming the active persistence policy.
Get Stream Configuration
Stream Id: Combat.Damage
|
+--> Seed Source
+--> Decision Mode
+--> Persistence Policy
+--> Fixed Seed, when applicable
FProbabilityStreamConfig RegisteredConfig;
// Query the current configuration for StreamId using
// GetStreamConfiguration(...), then inspect the returned
// status/success value before consuming RegisteredConfig.

Treat the registered configuration as authoritative. Do not infer a stream’s mode from the function you intended to call.


Purpose: Enumerate the streams registered in the current Game Instance.

This is primarily useful for:

  • Runtime developer tools.
  • Debug menus.
  • Diagnostics.
  • Integration validation.
  • Editor tooling.

Gameplay systems should normally know the Stream IDs they own rather than searching all registered streams every frame.

Get Stream IDs
|
+--> For Each Loop
|
+--> Print / inspect Stream Id
// Query GetStreamIds() / the corresponding public subsystem
// overload and inspect the returned FProbabilityStreamId values.

Do not use Stream ID enumeration as a global registry shared across Game Instances. The returned IDs belong only to the subsystem being queried.


Purpose: Remove a registered stream from the current Game Instance.

Use this for genuinely temporary streams or when a system deliberately owns the complete lifecycle of a stream.

End Temporary Gameplay Mode
|
+--> Remove Stream
Stream Id: Temporary.Minigame
Probability->RemoveStream(StreamId);

Do not remove a stream while another gameplay system still expects to use it.

Removing and recreating a Sequential stream also changes its runtime progression. Do not use remove/recreate as an accidental “reroll until I like the result” mechanism.


Probability Director owns validation and runtime state. The caller owns the semantic configuration.

The caller must choose:

  • A stable Stream ID.
  • Fixed or Secure seed behavior.
  • Sequential or Keyed decision mode.
  • An appropriate persistence policy.
  • A Fixed Seed when Fixed mode is selected.
  • Stable Decision Keys for Keyed calls.

A stream’s configuration should reflect one gameplay responsibility.

A useful rule is:

If changing the random-call order in System A should not change the results in System B, the systems should usually use separate Sequential streams or use Keyed decisions.


This is the most important API-selection decision.

Requirement Sequential Keyed
Result changes as the stream advances Yes No persistent cursor
Call order matters Yes No, when semantic key/occurrence is stable
Good for continuous rolls/sampling Yes Sometimes
Good for stable world decisions Usually no Yes
Fixed Seed reproducibility Yes, if call order is the same Yes
Explicit Decision Key required No Yes
Explicit Occurrence Not used as keyed identity Yes
Advances Sequential state Yes No
Hidden occurrence counter No No

Sequential calls consume the selected stream in order.

Use Sequential for:

  • Combat rolls.
  • Repeated dice rolls.
  • Continuous procedural sampling.
  • Loot rolls where order is intentionally part of the simulation.
  • Runtime distributions that should evolve as calls occur.
  • Secure gameplay randomness.
Create Stream
Stream Id: Combat.Damage
Decision Mode: Sequential
|
+--> Resolve Sequential Numeric Dice Total
|
+--> Resolve Sequential Numeric Dice Total
|
+--> each successful random operation advances the sequence

Use the Sequential variant of the required public subsystem operation.

For example, distribution sampling uses functions such as:

double Sample = 0.0;
FProbabilityDistributionSamplingStatus Status =
Probability->TrySampleSequentialNormal(
StreamId,
NormalDistribution,
Sample);

Only use Sample after Status reports success according to the public result contract.


Keyed calls derive a deterministic operation-local result from a registered Keyed stream plus an explicit FProbabilityDecisionKey.

Keyed calls do not use a hidden persistent occurrence counter.

A Decision Key contains semantic identity such as:

  • Namespace
  • Stable Subject ID
  • Decision
  • Occurrence

Use Keyed for:

  • “What variant should this persistent chest use?”
  • “Which procedural option belongs to this stable world object?”
  • “What deterministic choice corresponds to this subject and decision?”
  • Recomputable choices that should not change because an unrelated random call was added elsewhere.
Decision Key
Namespace: Loot
Stable Subject ID: Chest.Forest.0042
Decision: Rarity
Occurrence: 0
|
+--> Keyed Probability Director operation
Stream Id: Loot.WorldDecisions
FProbabilityDecisionKey DecisionKey;
// Fill the semantic fields through the public construction/validation path.
// The caller owns Occurrence. There is no hidden keyed counter.
double Sample = 0.0;
FProbabilityDistributionSamplingStatus Status =
Probability->TrySampleKeyedNormal(
StreamId,
DecisionKey,
NormalDistribution,
Sample);

A key should identify the meaning of the decision, not the memory location or temporary runtime identity of the object making the request.

Good:

Namespace: WorldLoot
Stable Subject ID: Region03.Chest0042
Decision: ItemTier
Occurrence: 0

Poor:

Namespace: Random
Stable Subject ID: BP_Chest_C_2147481250
Decision: Roll
Occurrence: current array index

Use Fixed when you need:

  • Reproducible automated tests.
  • Repeatable debugging.
  • Deterministic replays where the call sequence is controlled.
  • Known test vectors.
  • Reproducible procedural generation.

A Fixed Seed is not secret.

A Fixed Sequential stream reproduces only when its call order and relevant inputs remain compatible.

Use Secure when you need:

  • Fresh runtime unpredictability.
  • Gameplay randomness that should not be trivially derived from a user-visible seed.
  • A secure campaign/runtime random root managed internally by Probability Director.

Secure root material, derived keys, nonces, entropy bytes, and raw generator state are not exposed through normal Blueprint, diagnostics, or the Inspector.

Do not choose Secure when you require a user-entered seed to reproduce the same run later.


The Random API provides Sequential and Keyed random operations for common gameplay-safe numeric types.

Blueprint-facing random APIs use checked gameplay types rather than exposing internal raw byte generation.

Typical choices include:

  • Integer/range generation.
  • Float generation.
  • Double generation.
  • Sequential variants.
  • Keyed variants requiring a Decision Key.
Create Stream
Stream Id: AI.Timing
Decision Mode: Sequential
|
+--> Sequential random numeric node
Min: 0
Max: 100
Decision Key
Namespace: AI
Stable Subject ID: Guard.17
Decision: PatrolVariant
Occurrence: 0
|
+--> Keyed random numeric node

For C++, use the public random-generation methods on UProbabilityDirectorSubsystem that match the required numeric domain and stream mode.

Do not bypass the public bounded-generation API with modulo arithmetic such as:

// Do not do this:
Value = RawRandom % Bound;

Probability Director’s bounded generation exists to avoid biased range selection and to preserve the established deterministic contract.


The normal Blueprint dice surface includes:

  • Resolve Sequential Single Numeric Die
  • Resolve Keyed Single Numeric Die
  • Resolve Sequential Numeric Dice Total
  • Resolve Keyed Numeric Dice Total
  • Resolve Sequential Numeric Dice Success Count
  • Resolve Keyed Numeric Dice Success Count
  • Make Standard Numeric Dice Pipeline

Standard die presets include:

  • D4
  • D6
  • D8
  • D10
  • D12
  • D20
  • D100

Make Standard Numeric Dice Pipeline constructs a pipeline. It does not roll.


Use the Single Numeric Die API for one die when you need the single-die result contract.

Make numeric die definition
|
+--> Resolve Sequential Single Numeric Die
Stream Id: Combat.Damage

Keyed:

Decision Key
|
+--> Resolve Keyed Single Numeric Die
Stream Id: Combat.StableChecks
Decision Key: <explicit key>

The native subsystem exposes Sequential and Keyed single-die resolution through the corresponding numeric die resolver APIs.

Handle the returned dice resolution status before consuming the result.


Use Numeric Dice Total when several dice and their transformations should resolve to one final numeric total.

The operation-level inputs are:

  • Stream ID
  • Pipeline
  • Flat Modifier
  • Dice Bias
  • Decision Key for Keyed mode

Flat Modifier is applied once after aggregation.

Dice Bias changes generated-face probabilities and applies during generated-face resolution. It is not an additive modifier.

Make Standard Numeric Dice Pipeline
Standard Die: D20
Quantity: 2
|
+--> Resolve Sequential Numeric Dice Total
Stream Id: Combat.Attack
Flat Modifier: +5
Dice Bias: Positive 10%
// OutResult is the public result type required by the resolver overload.
Probability->ResolveSequentialNumericDicePipeline(
StreamId,
Pipeline,
FlatModifier,
DiceBias,
OutResult);

Keyed:

// OutResult is the public result type required by the resolver overload.
Probability->ResolveKeyedNumericDicePipeline(
StreamId,
DecisionKey,
Pipeline,
FlatModifier,
DiceBias,
OutResult);

The exact public result type/status should be handled as declared in the Runtime header. Do not use the output as a successful roll unless the returned status reports success.


Use Success Count for dice-pool mechanics where each completed candidate is classified as a success or failure and the final output is a count.

Examples:

  • 10D6, success on >= 5.
  • 8D10, success in an inclusive range.
  • Dice pool with Dice Bias, bounded reroll, and bounded explosion.

Success Count intentionally does not add an unrelated Flat Modifier.

Dice Pool:
Pool Size: 10
Sides: 6
Success Rule: At or Above
Success Threshold: 5
|
+--> Resolve Sequential Numeric Dice Success Count
Stream Id: Skills.Checks

Use the public Sequential or Keyed Success Count pool resolver for the selected stream mode. Treat the returned Success Count result as the complete pool observation.


V1.11 adds reusable authored numeric behavior through the abstract UProbabilityResolutionRules Data Asset family and its UNumericDiceResolutionRules subclass. The asset is immutable shared configuration; FProbabilityStreamId and, for Persistent Keyed calls, FProbabilityDecisionKey remain per-call context.

The numeric mode enum is EProbabilityNumericResolutionRulesMode: HomogeneousPipeline, HeterogeneousExpression, and SuccessCount. Die authoring uses EProbabilityNumericDieDefinitionAuthoringMode (StandardSides or ExplicitNumericFaces) and EProbabilityNumericResolutionRulesDiePreset (D4, D6, D8, D10, D12, D20, D100, Custom). FProbabilityNumericResolutionRulesDieDefinition and FProbabilityNumericResolutionRulesTerm materialize to the existing numeric die definitions and ordered expression terms.

EProbabilityResolutionDecisionPolicy provides Sequential and PersistentKeyed; Persistent Keyed is authoring terminology mapped to existing Keyed behavior. EProbabilityResolutionSourcePolicy provides InheritConfiguredStream, RequireFixed, and RequireSecure constraints on the registered stream; these policies do not create streams or choose seeds.

Native callers use TryResolveNumericRulesTotal or TryResolveNumericRulesSuccessCount on UProbabilityDirectorSubsystem. They return FProbabilityResolutionRulesStatus and the existing FProbabilityNumericDiceResolution or FProbabilityNumericSuccessCountResolution, preserving native trace/provenance and underlying status.

Blueprint callers use the four WorldContext convenience nodes indexed above. They return EProbabilityResolutionRulesError, an existing Blueprint dice/runtime status, and the existing Blueprint-safe numeric result projection.

FProbabilityResolutionContext contains the registered stream and optional policy overrides. FProbabilityNumericResolutionOverrides contains checked-additive AdditionalFlatModifier, bHasAdditionalDiceBias, and signed AdditionalDiceBiasPercent in -99..+99. Authored DiceBiasPercent uses the same range. Percentages convert exactly as Percent/100, compose exactly, and clamp internally to [-1,+1]; native exact bias APIs are unchanged. For Success Count, Flat Modifier is not applicable.

Invalid rules/context/policy data fails before RNG consumption and output commits. See Data Assets, Dice, and Streams and Decision Keys for authoring and runtime boundaries.


Make Probability Dice Bias is the normal designer-facing Blueprint constructor.

Inputs:

  • Direction
  • Bias Percent, from 0% through 100%

The Blueprint constructor converts the percentage through the canonical exact authoring path. Authoritative Dice Bias math is not performed as an approximate gameplay float.

Semantics:

  • Neutral: base generated-face distribution.
  • Positive: favors numerically higher generated faces.
  • Negative: favors numerically lower generated faces.
  • Positive 100%: deterministic maximum numeric generated face.
  • Negative 100%: deterministic minimum numeric generated face.
Make Probability Dice Bias
Direction: Positive
Bias Percent: 25
|
+--> Resolve Sequential Numeric Dice Total

C++ may construct/use the native FProbabilityDiceBias exact representation directly and pass it to the dice resolver.

Do not reinterpret Dice Bias as +N or -N added to the final total. Use FlatModifier for ordinary additive total modification.


Probability APIs are for analysis and probability transformation. Pure probability evaluation does not consume random state.

Use them when you want to answer questions such as:

  • What is the probability of one outcome?
  • What is the probability of a numeric range?
  • What is the probability at or below/above a threshold?
  • What quantile corresponds to an exact discrete distribution?
  • How does Probability Bias change a base probability?

The exact finite-discrete system supports numeric and symbolic weighted outcomes. Blueprint intentionally exposes safe query projections rather than every native exact internal type.

Construct / provide probability definition
|
+--> Exact probability query
|
+--> branch or display exact result

For native exact work, use the public exact probability types such as:

  • FProbabilityExactRatio
  • FProbabilityDiscreteMassFunction
  • FProbabilityCategoricalMassFunction

Example pattern:

FProbabilityDiscreteMassFunction MassFunction;
// Construct the exact function through its validated public creation API,
// then use its exact PMF/range/quantile queries.
//
// No Probability Director stream is required for pure evaluation.

Do not create a random stream solely to perform exact analysis.


Probability Director supports runtime evaluation and Sequential/Keyed sampling for the core V1 distribution families.

Family C++ Sequential sampler C++ Keyed sampler Sample type
Bernoulli TrySampleSequentialBernoulli TrySampleKeyedBernoulli bool
Binomial TrySampleSequentialBinomial TrySampleKeyedBinomial int32
Poisson TrySampleSequentialPoisson TrySampleKeyedPoisson int64
Continuous Uniform TrySampleSequentialContinuousUniform TrySampleKeyedContinuousUniform double
Triangular TrySampleSequentialTriangular TrySampleKeyedTriangular double
Exponential TrySampleSequentialExponential TrySampleKeyedExponential double
Normal TrySampleSequentialNormal TrySampleKeyedNormal double
Gamma TrySampleSequentialGamma TrySampleKeyedGamma double
Chi-square TrySampleSequentialChiSquare TrySampleKeyedChiSquare double
Beta TrySampleSequentialBeta TrySampleKeyedBeta double

Blueprint exposes corresponding safe distribution definition/evaluation/sampling nodes without exposing raw generator objects.


Pure evaluation may include, as applicable to the family:

  • PMF
  • PDF
  • CDF
  • Expectation
  • Variance

Not every metric mathematically applies to every family. For example, Poisson intentionally uses its supported numerical PMF/statistics surface rather than inventing an unsupported CDF contract.

Normal Distribution
Mean: 100
Standard Deviation: 15
|
+--> Normal PDF / CDF / statistics node

No stream is required for evaluation.

FProbabilityNormalDistribution Distribution;
// Configure Distribution through its public fields/constructor.
// Call the distribution's public numerical evaluation API.
// Check the returned numerical result before consuming Value.

Sampling requires a registered stream whose mode matches the requested API.

Create Stream
Stream Id: Economy.PriceNoise
Decision Mode: Sequential
|
+--> Sample Sequential Normal
Mean: 0
Standard Deviation: 1
double Sample = 0.0;
FProbabilityDistributionSamplingStatus Status =
Probability->TrySampleSequentialNormal(
StreamId,
Distribution,
Sample);

Keyed:

double Sample = 0.0;
FProbabilityDistributionSamplingStatus Status =
Probability->TrySampleKeyedNormal(
StreamId,
DecisionKey,
Distribution,
Sample);

Raw Blueprint-edited values may temporarily be invalid. Distribution sampling calls validate through the native authority; they do not silently clamp a mathematically invalid request into a different distribution.


C++ supports direct runtime sampling from the native exact mass-function representations.

Numeric:

  • FProbabilityDiscreteMassFunction
  • Sequential numeric mass sampling
  • Keyed numeric mass sampling

Categorical:

  • FProbabilityCategoricalMassFunction
  • Sequential categorical mass sampling
  • Keyed categorical mass sampling

These APIs preserve exact integer relative masses and canonical ordering.

Generic mass-function construction and generic mass sampling are intentionally not exposed as a broad Blueprint authoring surface in V1.

Use the specialized Blueprint Dice, Probability, Distribution, and Name APIs where possible.


Probability Bias changes a valid probability toward a boundary using the approved exact Probability Director semantics.

Use Probability Bias when the thing being biased is itself a probability.

Do not use Dice Bias as a substitute for Probability Bias.

Base Probability
|
+--> Probability Bias
Direction: Positive
Magnitude: <authored exact/validated value>

Use the native Probability Bias types and FProbabilityBiasMath through their validated exact path.

Do not convert an exact probability to a float, apply an ad hoc interpolation, and convert it back.


Distribution Parameter Bias changes mathematically meaningful distribution parameters toward caller-supplied target parameters.

The caller chooses the target.

Bias does not invent a target and does not reinterpret the target based on the sign.

Examples:

  • Normal: move Mean/Standard Deviation toward target values.
  • Poisson: move Lambda toward a target.
  • Gamma: move Shape/Scale toward targets.
  • Beta: move Alpha/Beta toward targets.
Base Normal
Mean: 0
StdDev: 1
Target Normal
Mean: 10
StdDev: 3
Distribution Bias: 75%
|
+--> Configured Normal

Use the corresponding native FProbabilityDistributionBiasMath per-family transformation.

Handle invalid-input and numerical-failure results. Do not clamp an invalid transformed distribution.


Weighted Outcome Bias is intentionally a C++-only advanced API in V1.

It operates on exact mass/affinity semantics that would be misleading if replaced by an approximate floating-weight Blueprint shortcut.

Use the native FProbabilityWeightedOutcomeBiasMath APIs when you specifically need weighted-affinity overlays.

Do not implement a Blueprint substitute by normalizing arbitrary floats and calling it equivalent.


Probability provides generic Sequential and Keyed ranked-weighted selection for callers that own candidate data and rank meaning. See Generic Bias and Ranked Selection for candidate validation, rank/bias semantics, deterministic-single-outcome validation, stream behavior, result status domains, and Blueprint/C++ entry points.


UProbabilityNameModel supports the V1 name-generation methods:

  • N-Gram Markov
  • Weighted Syllables

The model stores authored generation data, not gameplay RNG state.

The public structured API includes:

  • AnalyzeMarkovState
  • SampleMarkovTransitionSequential
  • SampleMarkovTransitionKeyed
  • AnalyzeNameModel
  • GenerateNameSequential
  • GenerateNameKeyed

Blueprint also provides simple batch convenience operations:

  • Generate N-Gram Names
  • Generate Weighted Syllable Names

The simple batch facade takes a Runtime Name Model and requested count and returns a structured batch result containing:

  • Ordered Names
  • RequestedCount
  • GeneratedCount
  • Status

Use the explicit Sequential/Keyed Name API when you need deterministic control through an existing gameplay stream or Decision Key.


Sequential generation advances the selected Probability Director stream.

Name Model Asset
|
+--> Generate Name Sequential
Stream Id: Names.Characters
// Use GenerateNameSequential with:
// - the selected StreamId
// - the UProbabilityNameModel
// - the public output/result structure
//
// Check generation status before accepting the produced name.

Keyed generation uses an explicit Decision Key and caller-controlled Occurrence.

There is no hidden keyed name cursor.

Decision Key
Namespace: CharacterNames
Stable Subject ID: NPC.Village.004
Decision: GivenName
Occurrence: 0
|
+--> Generate Name Keyed
// GenerateNameKeyed(... StreamId, DecisionKey, NameModel, ...)
//
// The same valid model + stream configuration + key + occurrence
// reproduces the same keyed generation contract.

Use Generate N-Gram Names or Generate Weighted Syllable Names when you want a convenient batch of names without managing gameplay-stream identity.

This convenience path is intentionally simpler than the explicit Sequential/Keyed gameplay API.

Use the explicit APIs when stream progression or semantic Decision Keys matter.


Probability Director uses domain-specific statuses/results rather than treating every failure as a generic Boolean error.

Depending on the API, failures can include concepts such as:

  • Invalid input.
  • Non-finite numerical input.
  • Unknown or unregistered Stream ID.
  • Stream decision-mode mismatch.
  • Unsupported seed-source behavior.
  • Invalid Decision Key.
  • Exact capacity exceeded.
  • Exact complexity exceeded.
  • Sampling limit reached.
  • Work limit reached.
  • Numerical failure.
  • Dice outcome range overflow.
  • Name generation bound reached.
  • Unsupported operation for the selected type.
  1. Check the returned status/result.
  2. Treat the output payload as successful only when the status reports success.
  3. Do not silently substitute a default random value after failure unless that is an explicit gameplay rule.
  4. Log or surface enough semantic context to diagnose invalid configuration.
  5. Do not assume every failure rolls back random state.

A request rejected during preflight validation is designed not to become a successful random operation.

However, some algorithms can consume random draws before a later bounded work/numerical failure occurs.

Do not write gameplay code that assumes:

Failed random call == Sequential stream definitely unchanged

unless that specific API contract explicitly guarantees zero consumption for that failure.

Keyed operations have no persistent sequential cursor to roll back. Their deterministic identity comes from the registered Keyed stream plus the explicit Decision Key and occurrence.


Probability Director generally validates authored/runtime inputs instead of silently changing their meaning.

Examples:

  • Invalid distribution parameters are rejected.
  • Invalid Decision Keys are rejected.
  • Invalid exact ratios are rejected.
  • Exact capacity overflow is reported.
  • Numerical failure is reported.
  • Bounded algorithms report work/sampling limits.

Do not rely on the runtime API to turn invalid gameplay data into a nearby valid value.

Editor controls may constrain normal authoring UX, but the Runtime API remains the validation authority.


You need to… Use
Roll/sample repeatedly and intentionally advance state Sequential stream
Recompute a stable decision independent of unrelated call order Keyed stream + Decision Key
Reproduce a test sequence Fixed Seed stream
Use fresh unpredictable runtime randomness Secure stream
Evaluate probability without sampling Pure Probability/Distribution evaluation
Roll one numeric die Single Numeric Die resolver
Resolve several dice to one total Numeric Dice Total
Count successful dice-pool candidates Numeric Dice Success Count
Reuse authored numeric/dice behavior Numeric Dice Resolution Rules Data Asset
Add a normal integer bonus after dice aggregation Flat Modifier
Favor high/low generated die faces Dice Bias
Change a base probability toward a boundary Probability Bias
Move distribution parameters toward selected targets Distribution Parameter Bias
Sample Bernoulli/Binomial/etc. Distribution sampler
Sample arbitrary exact numeric/categorical masses Native C++ exact mass sampler
Generate deterministic names from a gameplay stream GenerateNameSequential
Generate stable semantic names by key GenerateNameKeyed
Generate a simple isolated batch of names Generate N-Gram Names / Generate Weighted Syllable Names
Inspect runtime streams and decisions Probability Director Runtime Inspector
Save/load Probability Director state Persistence API / host save integration
Manage save files, slots, or autosave Host SaveGame system or optional DirectorBridge Probability.SaveGame

23.1 Create streams once, use them many times

Section titled “23.1 Create streams once, use them many times”

Good:

Game/session startup
-> Create Combat.Damage
-> Create Combat.Critical
-> Create Loot.DropTable
Gameplay
-> reuse those streams

Poor:

Every attack
-> create a new stream
-> roll once
-> remove stream

23.2 Separate unrelated Sequential responsibilities

Section titled “23.2 Separate unrelated Sequential responsibilities”

If adding an extra cosmetic roll should not change combat damage, do not put both on the same Sequential stream.

Prefer:

Combat.Damage
Combat.Critical
Cosmetics.Variation
Audio.Randomization

23.3 Use Keyed for stable identity, not manual reseeding

Section titled “23.3 Use Keyed for stable identity, not manual reseeding”

If you want a stable answer for Chest 42, use a Keyed decision.

Do not repeatedly destroy/recreate a Fixed Sequential stream with a hand-computed seed for every object.


Treat Decision Keys like stable data contracts.

Do not base them on:

  • Pointer addresses.
  • UObject transient indices.
  • PIE object suffixes.
  • Iteration order that may change after refactoring.

23.5 Keep pure evaluation separate from sampling

Section titled “23.5 Keep pure evaluation separate from sampling”

Probability/PMF/PDF/CDF/statistics queries do not need to consume gameplay RNG.

Compute first, sample only when gameplay needs a realized random result.


23.6 Use specialized Blueprint APIs before advanced native mass APIs

Section titled “23.6 Use specialized Blueprint APIs before advanced native mass APIs”

For Blueprint gameplay:

  • Dice -> Dice API.
  • Bernoulli/Binomial/etc. -> Distribution API.
  • Weighted probability queries -> Probability API.
  • Names -> Name API.

Use generic C++ exact-mass sampling only when your system genuinely needs an arbitrary exact weighted runtime distribution.


  • Per-GameInstance runtime isolation.
  • Stream registration and runtime state.
  • Fixed and Secure seed behavior.
  • Sequential progression.
  • Keyed operation derivation.
  • Exact bounded range generation.
  • Dice runtime semantics.
  • Distribution evaluation/sampling.
  • Exact probability math.
  • Approved Bias transforms.
  • Name/Markov generation.
  • Structured validation/status reporting.
  • Sanitized diagnostics.
  • Probability Director persistence state/validation where the persistence API is used.
  • Choosing stable Stream IDs.
  • Choosing Fixed versus Secure behavior.
  • Choosing Sequential versus Keyed behavior.
  • Supplying stable Decision Keys and explicit occurrences.
  • Handling failure results.
  • Deciding what a random result means for gameplay.
  • Server/client authority.
  • Replicating authoritative gameplay results.
  • Save-slot names, files, cloud storage, autosave timing, and storage policy.
  • Calling stream creation/removal at appropriate lifecycle points.
  • Avoiding accidental coupling between unrelated Sequential systems.

25. Networking and Multiplayer Responsibility

Section titled “25. Networking and Multiplayer Responsibility”

Probability Director is Game Instance-scoped. It is not a replication framework.

If a gameplay result must be authoritative in multiplayer:

  1. Perform the authoritative random/probability operation in the authoritative gameplay context.
  2. Apply the gameplay result there.
  3. Replicate the resulting gameplay state through your normal Unreal networking architecture.

Do not expect two machines to remain synchronized merely because they created streams with similar names.

For deterministic network designs, explicitly define which side owns the decision and which data is replicated.


Normal gameplay sampling APIs are synchronous operations.

Blueprint sampling/dice nodes are callable operations, not pure nodes. This prevents Blueprint reevaluation from silently performing additional random operations.

Pure evaluation and construction helpers may be Blueprint Pure when they consume no RNG and mutate no Probability Director state.

Do not move Probability Director subsystem operations onto arbitrary worker threads unless the specific public API explicitly documents worker-thread support.


Probability Director diagnostics are observational.

They must not be used as:

  • A second gameplay state store.
  • A random result history that gameplay logic depends on.
  • A way to reconstruct secure RNG state.
  • A persistence replacement.

Developer diagnostics can include sanitized information such as:

  • Stream ID.
  • Operation category.
  • Decision mode.
  • Result/status.
  • Distribution family.
  • Bounded counts.
  • Sanitized Decision Key fields where approved.

Diagnostics do not expose secure roots, entropy bytes, keys, nonces, raw generator state, byte position, or other reconstructable secret material.

Use the Probability Director Runtime Inspector for interactive runtime inspection during PIE.


Probability Director can preserve its own deterministic runtime state through its native persistence contract, but it does not own your save-slot/file workflow.

The core plugin does not decide:

  • Slot names.
  • Where a save file is stored.
  • When autosave occurs.
  • Cloud synchronization.
  • User-profile selection.

A host save workflow can orchestrate storage directly; projects using SaveGame Director can use the optional DirectorBridge Probability.SaveGame adapter.

Probability Director persistence internals that can contain sensitive deterministic state are intentionally not exposed as ordinary Blueprint fields.

Plain save serialization is not encryption. If save-file confidentiality is required, it must be provided by the host storage/security design.


The following are intentionally not part of the normal Blueprint API:

  • Raw random bytes.
  • Raw generator objects.
  • Secure campaign roots.
  • Entropy bytes.
  • ChaCha keys.
  • ChaCha nonces.
  • Raw generator state.
  • Sequential byte position.
  • Reconstructable RNG fingerprints.
  • Seed-derivation/KDF internals.
  • Private UInt256 exact-arithmetic internals.
  • Raw persistence secret bytes.
  • Persistence archive internals.
  • Prepare/Commit/Discard secret candidate state.
  • Generic exact-mass construction/sampling as a broad Blueprint workflow.
  • Weighted Outcome Bias authoring.

The public API should let gameplay ask for a random/probability result without giving gameplay direct access to the cryptographic machinery that produces it.

A Fixed Seed is not secret. Secure internal state is.


Use a long-lived Sequential stream instead.

Calling a Sequential API on a Keyed stream

Section titled “Calling a Sequential API on a Keyed stream”

Use the API matching the registered stream’s Decision Mode.

Calling a Keyed API without a stable Decision Key

Section titled “Calling a Keyed API without a stable Decision Key”

A Keyed result is only as stable as the semantic identity you provide.

Using Actor runtime names as Stable Subject IDs

Section titled “Using Actor runtime names as Stable Subject IDs”

Use stable authored/gameplay identity instead.

Assuming Fixed means call-order independent

Section titled “Assuming Fixed means call-order independent”

Fixed Sequential streams are deterministic, but call order still matters.

Assuming Secure means persistent replayable seed

Section titled “Assuming Secure means persistent replayable seed”

Secure state is intentionally hidden. Use Fixed when a human-visible seed must reproduce a sequence.

Use Probability Director’s bounded APIs.

Dice Bias changes face probabilities. Flat Modifier adds to the aggregate.

A returned output is not automatically a successful gameplay result.

Assuming a failed Sequential call always consumed zero RNG

Section titled “Assuming a failed Sequential call always consumed zero RNG”

Only rely on zero-consumption guarantees explicitly documented for that failure path.

Resolve/use the subsystem belonging to the current Game Instance.


A useful first test is a Fixed Sequential D20 stream.

Event BeginPlay
|
+--> Create Stream
Stream Id: Tutorial.Dice
Seed Source: Fixed
Fixed Seed: 123
Decision Mode: Sequential
|
+--> Make Standard Numeric Dice Pipeline
Standard Die: D20
Quantity: 1
|
+--> Resolve Sequential Numeric Dice Total
Stream Id: Tutorial.Dice
Flat Modifier: 0
Dice Bias: Neutral
|
+--> Print returned result after success

Run PIE twice from a clean equivalent setup. The Fixed stream should reproduce the same deterministic sequence when the same operations occur in the same order.

Then change the stream to Secure to test the normal unpredictable runtime path.


The following example shows the intended shape: obtain the subsystem, use a stream created by your initialization path, and perform a distribution sample.

#include "ProbabilityDirectorSubsystem.h"
void UMyGameplayComponent::SampleGameplayValue()
{
UProbabilityDirectorSubsystem* Probability = GetProbabilityDirector(this);
if (!Probability)
{
return;
}
// This StreamId should have been created during your normal
// Game Instance/gameplay initialization.
FProbabilityStreamId StreamId;
StreamId.Name = TEXT("Gameplay.NormalExample");
FProbabilityNormalDistribution Distribution;
// Configure the distribution through its public constructor/fields
// for the version of the Runtime API you are compiling against.
double Sample = 0.0;
const FProbabilityDistributionSamplingStatus Status =
Probability->TrySampleSequentialNormal(
StreamId,
Distribution,
Sample);
// Branch on the public Status success/result contract before using Sample.
}

For a Keyed workflow, use a stream configured for Keyed decisions, construct a valid semantic FProbabilityDecisionKey, and call TrySampleKeyedNormal.


For a larger game, centralize Probability Director IDs and key conventions.

Example:

Streams
Combat.Damage
Combat.Critical
Loot.DropTable
World.Encounters
NPC.Names
Decision namespaces
Combat
Loot
WorldGeneration
NPC

Document which gameplay system owns each Sequential stream.

For Keyed decisions, document the Stable Subject ID source and the meaning of Occurrence.

This makes deterministic behavior easier to preserve during refactors.


Treat these as persistent contracts:

  • Stream ID meaning.
  • Decision Key Namespace.
  • Stable Subject ID construction.
  • Decision name.
  • Occurrence meaning.
  • Stream Decision Mode.
  • Seed policy for systems that require deterministic compatibility.

Changing those can intentionally change deterministic outputs even when Probability Director itself has not changed.

Do not use display labels or temporary runtime object names as compatibility identifiers.


After this overview, read the subject-specific documentation for the system you are implementing:

  • Streams and Random — stream configuration, Fixed/Secure behavior, Sequential/Keyed semantics, Decision Keys.
  • Dice — pipeline order, Dice Bias, Flat Modifier, explosion, reroll, selection, Success Count, critical classification.
  • Data Assets — reusable authored Runtime Data Assets and Numeric Dice Resolution Rules.
  • Probability and Bias — exact probability queries and Bias semantics.
  • Distributions — family definitions, evaluation, sampling, numerical behavior, work limits.
  • Markov and Names — N-Gram Markov, Weighted Syllables, Name Model assets, Sequential/Keyed generation.
  • Persistence — campaign identity, stream persistence, save/restore integration and security boundaries.
  • Diagnostics and Warnings — runtime diagnostics, warning causes, retention and Shipping behavior.
  • Probability Director Runtime Inspector — PIE/Game Instance selection, Streams, Recent Decisions, Events, Warnings, Freeze View, and safe deterministic-contract metadata.

Prefer target-free world-context Probability Director nodes.

Create Stream
-> perform Sequential or Keyed operation
-> handle structured result/status
-> Remove Stream only when its owned lifecycle actually ends
UGameInstance* GameInstance = World->GetGameInstance();
UProbabilityDirectorSubsystem* Probability =
GameInstance->GetSubsystem<UProbabilityDirectorSubsystem>();

Then use the subsystem’s public API for stateful operations and the pure math/types for evaluation.

  • Sequential = “give me the next result.”
  • Keyed = “give me the result for this exact semantic decision.”
  • Fixed = “I need reproducibility.”
  • Secure = “I need fresh unpredictability.”
  • Pure evaluation = “tell me the probability; do not roll.”