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.
API Call Index
Section titled “API Call Index”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.
Blueprint API Calls
Section titled “Blueprint API Calls”| 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 |
C++ API Calls
Section titled “C++ API Calls”| 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.
1. Purpose
Section titled “1. Purpose”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.
2. Core Model
Section titled “2. Core Model”The basic runtime model is:
- Unreal creates one
UProbabilityDirectorSubsystemfor eachUGameInstance. - Gameplay creates named Probability Director streams.
- Each stream has an authored configuration, including its decision mode and seed source.
- 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.
- Probability Director validates the request, performs the requested operation, and returns a structured result/status.
- 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.
3. Blueprint and C++ Entry Points
Section titled “3. Blueprint and C++ Entry Points”Blueprint
Section titled “Blueprint”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|StreamsProbability Director|RandomProbability Director|DiceProbability Director|Dice|PresetsProbability Director|ProbabilityProbability Director|DistributionsProbability 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.
4. Obtaining the Subsystem in Blueprint
Section titled “4. Obtaining the Subsystem in Blueprint”For most Blueprint calls, you do not obtain the subsystem manually.
Preferred Blueprint pattern
Section titled “Preferred Blueprint pattern”Actor / Level Blueprint | +--> Probability Director node | +--> hidden World Context resolves current Game Instance | +--> UProbabilityDirectorSubsystemThis 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.
Direct Blueprint subsystem access
Section titled “Direct Blueprint subsystem access”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.
5. Subsystem Lifecycle
Section titled “5. Subsystem Lifecycle”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 destroyedThe first developer-managed lifecycle is therefore the stream lifecycle.
6. Stream Lifecycle API
Section titled “6. Stream Lifecycle API”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.
6.1 Create Stream
Section titled “6.1 Create Stream”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.
Blueprint example
Section titled “Blueprint example”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 streamFor deterministic testing:
Event BeginPlay | +--> Create Stream Stream Id: Combat.Damage Seed Source: Fixed Fixed Seed: 12345 Decision Mode: SequentialC++ usage pattern
Section titled “C++ usage pattern”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.
Recommended pattern
Section titled “Recommended pattern”Use stable semantic IDs:
Combat.DamageCombat.CriticalLoot.DropTableAI.DecisionWorld.EncountersNames.CharactersAvoid IDs based on temporary Actor names, pointer values, array positions, or transient object numbering.
6.2 Has Stream
Section titled “6.2 Has Stream”Purpose: Test whether the selected Game Instance currently has a registered stream.
Blueprint example
Section titled “Blueprint example”Has Stream Stream Id: Loot.DropTable | +--> True -> perform the operation | +--> False -> create the stream or report configuration errorC++ usage pattern
Section titled “C++ usage pattern”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.
6.3 Get Stream Configuration
Section titled “6.3 Get Stream Configuration”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.
Blueprint example
Section titled “Blueprint example”Get Stream Configuration Stream Id: Combat.Damage | +--> Seed Source +--> Decision Mode +--> Persistence Policy +--> Fixed Seed, when applicableC++ usage pattern
Section titled “C++ usage pattern”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.
6.4 Get Stream IDs
Section titled “6.4 Get Stream IDs”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.
Blueprint example
Section titled “Blueprint example”Get Stream IDs | +--> For Each Loop | +--> Print / inspect Stream IdC++ usage pattern
Section titled “C++ usage pattern”// 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.
6.5 Remove Stream
Section titled “6.5 Remove Stream”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.
Blueprint example
Section titled “Blueprint example”End Temporary Gameplay Mode | +--> Remove Stream Stream Id: Temporary.MinigameC++ usage pattern
Section titled “C++ usage pattern”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.
7. Stream Configuration Responsibilities
Section titled “7. Stream Configuration Responsibilities”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.
8. Sequential vs. Keyed APIs
Section titled “8. Sequential vs. Keyed APIs”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 |
8.1 Sequential API
Section titled “8.1 Sequential API”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.
Blueprint pattern
Section titled “Blueprint pattern”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 sequenceC++ pattern
Section titled “C++ pattern”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.
8.2 Keyed API
Section titled “8.2 Keyed API”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.
Blueprint pattern
Section titled “Blueprint pattern”Decision Key Namespace: Loot Stable Subject ID: Chest.Forest.0042 Decision: Rarity Occurrence: 0 | +--> Keyed Probability Director operation Stream Id: Loot.WorldDecisionsC++ pattern
Section titled “C++ pattern”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);Decision Key rule
Section titled “Decision Key rule”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: WorldLootStable Subject ID: Region03.Chest0042Decision: ItemTierOccurrence: 0Poor:
Namespace: RandomStable Subject ID: BP_Chest_C_2147481250Decision: RollOccurrence: current array index9. Fixed vs. Secure Seed Sources
Section titled “9. Fixed vs. Secure Seed Sources”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.
Secure
Section titled “Secure”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.
10. Random API
Section titled “10. Random API”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.
Blueprint example: repeated random value
Section titled “Blueprint example: repeated random value”Create Stream Stream Id: AI.Timing Decision Mode: Sequential | +--> Sequential random numeric node Min: 0 Max: 100Blueprint example: stable keyed choice
Section titled “Blueprint example: stable keyed choice”Decision Key Namespace: AI Stable Subject ID: Guard.17 Decision: PatrolVariant Occurrence: 0 | +--> Keyed random numeric nodeC++ example
Section titled “C++ example”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.
11. Dice API
Section titled “11. Dice API”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.
11.1 Single Numeric Die
Section titled “11.1 Single Numeric Die”Use the Single Numeric Die API for one die when you need the single-die result contract.
Blueprint example
Section titled “Blueprint example”Make numeric die definition | +--> Resolve Sequential Single Numeric Die Stream Id: Combat.DamageKeyed:
Decision Key | +--> Resolve Keyed Single Numeric Die Stream Id: Combat.StableChecks Decision Key: <explicit key>C++ pattern
Section titled “C++ pattern”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.
11.2 Numeric Dice Total
Section titled “11.2 Numeric Dice Total”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.
Blueprint example
Section titled “Blueprint example”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%C++ example
Section titled “C++ example”// 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.
11.3 Numeric Dice Success Count
Section titled “11.3 Numeric Dice Success Count”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.
Blueprint example
Section titled “Blueprint example”Dice Pool: Pool Size: 10 Sides: 6 Success Rule: At or Above Success Threshold: 5 | +--> Resolve Sequential Numeric Dice Success Count Stream Id: Skills.ChecksC++ pattern
Section titled “C++ pattern”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.
11.4 Resolution Rules
Section titled “11.4 Resolution Rules”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.
12. Dice Bias API
Section titled “12. Dice Bias API”Make Probability Dice Bias is the normal designer-facing Blueprint constructor.
Inputs:
- Direction
- Bias Percent, from
0%through100%
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.
Blueprint example
Section titled “Blueprint example”Make Probability Dice Bias Direction: Positive Bias Percent: 25 | +--> Resolve Sequential Numeric Dice TotalC++ pattern
Section titled “C++ pattern”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.
13. Probability API
Section titled “13. Probability API”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.
Blueprint example
Section titled “Blueprint example”Construct / provide probability definition | +--> Exact probability query | +--> branch or display exact resultC++ example
Section titled “C++ example”For native exact work, use the public exact probability types such as:
FProbabilityExactRatioFProbabilityDiscreteMassFunctionFProbabilityCategoricalMassFunction
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.
14. Distribution API
Section titled “14. Distribution API”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.
14.1 Distribution evaluation
Section titled “14.1 Distribution evaluation”Pure evaluation may include, as applicable to the family:
- PMF
- 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.
Blueprint example
Section titled “Blueprint example”Normal Distribution Mean: 100 Standard Deviation: 15 | +--> Normal PDF / CDF / statistics nodeNo stream is required for evaluation.
C++ pattern
Section titled “C++ pattern”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.14.2 Distribution sampling
Section titled “14.2 Distribution sampling”Sampling requires a registered stream whose mode matches the requested API.
Blueprint example
Section titled “Blueprint example”Create Stream Stream Id: Economy.PriceNoise Decision Mode: Sequential | +--> Sample Sequential Normal Mean: 0 Standard Deviation: 1C++ example
Section titled “C++ example”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.
15. Generic Exact Mass Sampling in C++
Section titled “15. Generic Exact Mass Sampling in C++”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.
16. Probability Bias API
Section titled “16. Probability Bias API”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.
Blueprint example
Section titled “Blueprint example”Base Probability | +--> Probability Bias Direction: Positive Magnitude: <authored exact/validated value>C++ pattern
Section titled “C++ pattern”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.
17. Distribution Parameter Bias API
Section titled “17. Distribution Parameter Bias API”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.
Blueprint example
Section titled “Blueprint example”Base Normal Mean: 0 StdDev: 1
Target Normal Mean: 10 StdDev: 3
Distribution Bias: 75% | +--> Configured NormalC++ pattern
Section titled “C++ pattern”Use the corresponding native FProbabilityDistributionBiasMath per-family transformation.
Handle invalid-input and numerical-failure results. Do not clamp an invalid transformed distribution.
18. Weighted Outcome Bias
Section titled “18. Weighted Outcome Bias”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.
Generic Bias and Ranked Selection
Section titled “Generic Bias and Ranked Selection”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.
19. Name and Markov API
Section titled “19. Name and Markov API”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:
AnalyzeMarkovStateSampleMarkovTransitionSequentialSampleMarkovTransitionKeyedAnalyzeNameModelGenerateNameSequentialGenerateNameKeyed
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 RequestedCountGeneratedCount- Status
Use the explicit Sequential/Keyed Name API when you need deterministic control through an existing gameplay stream or Decision Key.
19.1 Sequential name generation
Section titled “19.1 Sequential name generation”Sequential generation advances the selected Probability Director stream.
Blueprint example
Section titled “Blueprint example”Name Model Asset | +--> Generate Name Sequential Stream Id: Names.CharactersC++ pattern
Section titled “C++ pattern”// Use GenerateNameSequential with:// - the selected StreamId// - the UProbabilityNameModel// - the public output/result structure//// Check generation status before accepting the produced name.19.2 Keyed name generation
Section titled “19.2 Keyed name generation”Keyed generation uses an explicit Decision Key and caller-controlled Occurrence.
There is no hidden keyed name cursor.
Blueprint example
Section titled “Blueprint example”Decision Key Namespace: CharacterNames Stable Subject ID: NPC.Village.004 Decision: GivenName Occurrence: 0 | +--> Generate Name KeyedC++ pattern
Section titled “C++ pattern”// GenerateNameKeyed(... StreamId, DecisionKey, NameModel, ...)//// The same valid model + stream configuration + key + occurrence// reproduces the same keyed generation contract.19.3 Simple isolated batch generation
Section titled “19.3 Simple isolated batch generation”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.
20. Error Handling
Section titled “20. Error Handling”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.
Required caller behavior
Section titled “Required caller behavior”- Check the returned status/result.
- Treat the output payload as successful only when the status reports success.
- Do not silently substitute a default random value after failure unless that is an explicit gameplay rule.
- Log or surface enough semantic context to diagnose invalid configuration.
- Do not assume every failure rolls back random state.
Important Sequential rule
Section titled “Important Sequential rule”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 unchangedunless that specific API contract explicitly guarantees zero consumption for that failure.
Important Keyed rule
Section titled “Important Keyed rule”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.
21. Validation and Clamping
Section titled “21. Validation and Clamping”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.
22. API Selection Guide
Section titled “22. API Selection Guide”| 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. Recommended Usage Patterns
Section titled “23. Recommended Usage Patterns”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 streamsPoor:
Every attack -> create a new stream -> roll once -> remove stream23.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.DamageCombat.CriticalCosmetics.VariationAudio.Randomization23.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.
23.4 Keep Decision Keys semantic
Section titled “23.4 Keep Decision Keys semantic”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.
24. Responsibilities
Section titled “24. Responsibilities”Probability Director owns
Section titled “Probability Director owns”- 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.
The game owns
Section titled “The game owns”- 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:
- Perform the authoritative random/probability operation in the authoritative gameplay context.
- Apply the gameplay result there.
- 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.
26. Threading and Execution Model
Section titled “26. Threading and Execution Model”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.
27. Diagnostics
Section titled “27. Diagnostics”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.
28. Persistence Boundary
Section titled “28. Persistence Boundary”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.
29. Public Safety Boundaries
Section titled “29. Public Safety Boundaries”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
UInt256exact-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.
30. Common Mistakes
Section titled “30. Common Mistakes”Creating a new stream for every roll
Section titled “Creating a new stream for every roll”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.
Applying % Bound to raw randomness
Section titled “Applying % Bound to raw randomness”Use Probability Director’s bounded APIs.
Treating Dice Bias as a Flat Modifier
Section titled “Treating Dice Bias as a Flat Modifier”Dice Bias changes face probabilities. Flat Modifier adds to the aggregate.
Ignoring structured status results
Section titled “Ignoring structured status results”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.
Caching a subsystem across Game Instances
Section titled “Caching a subsystem across Game Instances”Resolve/use the subsystem belonging to the current Game Instance.
31. First Blueprint Workflow
Section titled “31. First Blueprint Workflow”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 successRun 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.
32. First C++ Workflow
Section titled “32. First C++ Workflow”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.
33. Suggested Project Organization
Section titled “33. Suggested Project Organization”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 NPCDocument 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.
34. API Stability and Compatibility
Section titled “34. API Stability and Compatibility”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.
35. Where to Go Next
Section titled “35. Where to Go Next”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.
36. Quick Reference
Section titled “36. Quick Reference”Blueprint
Section titled “Blueprint”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 endsUGameInstance* 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.
Rule of thumb
Section titled “Rule of thumb”- 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.”