Skip to main content

bevy_brink/
lib.rs

1//! Bevy integration for brink ink stories.
2//!
3//! This crate exposes the brink runtime as a Bevy plugin: story programs
4//! are loaded as `Asset`s, flow state lives on `Component`s, story-wide
5//! globals live in `Resource`s. All types are parameterized over a ZST
6//! marker so multiple independent story instances can coexist in one app.
7//!
8//! Most games will use the default `()` marker and just do:
9//!
10//! ```no_run
11//! # use bevy_app::App;
12//! # use bevy_brink::BrinkPlugin;
13//! # let mut app = App::new();
14//! app.add_plugins(BrinkPlugin::<()>::default());
15//! ```
16//!
17//! Games with multiple concurrent story instances declare marker types
18//! and register a plugin per marker:
19//!
20//! ```no_run
21//! # use bevy_app::App;
22//! # use bevy_brink::BrinkPlugin;
23//! # let mut app = App::new();
24//! struct MainStory;
25//! struct DreamSequence;
26//!
27//! app.add_plugins((
28//!     BrinkPlugin::<MainStory>::default(),
29//!     BrinkPlugin::<DreamSequence>::default(),
30//! ));
31//! ```
32
33// Lets `#[derive(BrinkCommand)]`-generated code reference `::bevy_brink`
34// from within this crate itself (the same trick serde/bevy use for their
35// own derives).
36extern crate self as bevy_brink;
37
38mod asset;
39mod async_bind;
40mod batch;
41mod bindings;
42mod brkt;
43mod call;
44mod capability;
45#[cfg(feature = "dev")]
46mod config_warnings;
47mod event;
48mod flow;
49mod globals;
50#[cfg(feature = "effect-trace")]
51mod ground_truth;
52mod handle;
53mod input;
54mod line_tables;
55mod locale;
56mod plugin;
57#[cfg(feature = "dev")]
58mod replay;
59mod request;
60mod sleep;
61#[cfg(feature = "dev")]
62mod source_loader;
63#[cfg(test)]
64mod test_support;
65mod transcript;
66mod wake_delta;
67
68pub use asset::{
69    BrinkProgram, BrinkStory, BrinkStoryAsset, InkbLoader, InkbLoaderError, LineTablesAsset,
70    ProgramAsset,
71};
72pub use async_bind::{
73    BrinkAwaiting, BrinkExternalAwaited, BrinkPendingTask, BrinkResolveExternalExt,
74    poll_brink_tasks,
75};
76pub use batch::parallel::advance_batch_parallel;
77pub use batch::{BrinkBatchReport, FlowAccessRecord, advance_batch};
78/// `#[derive(BrinkCommand)]` — generates [`BrinkCommand::from_ink_args`].
79/// Shares its name with the trait (macro vs. type namespace), so a single
80/// `use bevy_brink::BrinkCommand;` brings both into scope.
81pub use bevy_brink_derive::BrinkCommand;
82pub use bindings::{
83    BrinkArgError, BrinkBindings, BrinkBindingsAppExt, BrinkCallError, BrinkCommand, BrinkHandler,
84    BrinkQueryInput, advance_flow, any_flow_awaiting_external, call_ink_function,
85    call_ink_function_value, call_ink_functions, resolve_pending_externals,
86};
87/// Re-exported so `#[derive(BrinkCommand)]`-generated code (and binding
88/// authors) can name the ink runtime value type without depending on
89/// `brink-format` directly.
90pub use brink_format::Value;
91/// The whole runtime crate, re-exported as an escape hatch: any `brink_runtime`
92/// type that surfaces in a `bevy-brink` API but isn't individually re-exported
93/// below is reachable as `bevy_brink::runtime::…` — so a consumer never needs a
94/// direct `brink-runtime` Cargo dependency to name one.
95pub use brink_runtime as runtime;
96/// Re-exported so consumers can choose `Overlay`/`Strict` application without
97/// a direct `brink-runtime` dependency.
98pub use brink_runtime::LocaleMode;
99/// `brink_runtime::World` — the single story-state layer shared by every
100/// flow under a marker, carried by [`BrinkGlobals`]. Aliased to avoid the
101/// glob-import collision with `bevy::prelude::World` (the ECS world): `use
102/// bevy::prelude::*; use bevy_brink::*;` would make a bare `World`
103/// ambiguous. Name story state `BrinkWorld` and the ECS world `World`.
104pub use brink_runtime::World as BrinkWorld;
105/// Re-exported so consumers can name the decoded-transcript type and its
106/// error without depending on `brink-runtime` directly.
107pub use brink_runtime::transcript::{TranscriptData, TranscriptError};
108/// The runtime types that appear in `bevy-brink`'s own public signatures,
109/// re-exported so consumers can name them without depending on `brink-runtime`:
110/// [`FlowInstance`](BrinkFlow::inner), [`Program`](crate::ProgramAsset::program),
111/// [`Choice`](crate::BrinkChoicesPresented::choices), [`Step`](advance_flow)'s
112/// return, [`RuntimeError`](BrinkFlow::choose)'s error,
113/// [`FallbackHandler`] for the "no bindings" advance path, the scoped
114/// story-state types a host needs to build a policy and a per-step routing
115/// view (see `docs/scoped-flow-state-spec.md`): [`WorldPolicy`], [`Scope`],
116/// [`PolicyError`], and [`ContextView`] (usually built via
117/// [`flow_context_view`] instead of by hand) — and the per-entity durability
118/// types produced/consumed by [`BrinkGlobals::save_state`]/`load_state` and
119/// [`save_flow_state`]/[`load_flow_state`] (F6.3, see the `globals` module's
120/// "Save/load" docs): [`SaveState`] and [`LoadReport`].
121///
122/// `World` is deliberately absent here — it collides with `bevy::prelude::World`
123/// under a glob import, so it is re-exported under the alias [`BrinkWorld`].
124pub use brink_runtime::{
125    BlockId, Choice, ContextView, ExecMode, FallbackHandler, FlowInstance, FlowLocal, LoadReport,
126    OutputLine, PolicyError, Program, RuntimeError, SaveState, Scope, Step, WorldPolicy,
127};
128pub use brkt::{
129    BrktLoader, BrktLoaderError, TranscriptAsset, capture_transcript, render_transcript_asset,
130};
131pub use call::{
132    BrinkCallBatchRequest, BrinkCallBatchResolved, BrinkCallCommandsExt, BrinkCallFailed,
133    BrinkCallRequest, BrinkCallResolved, IntoBrinkArgs, resolve_brink_call_batches,
134    resolve_brink_calls,
135};
136pub use capability::{
137    BrinkCapabilityAppExt, CapabilityChanges, CapabilityEffects, CapabilityError,
138    CapabilityManifest, CapabilityManifestExternal, CapabilityRegistry, CapabilityTable,
139    ContainerAccess, ContainerAccessTable, compute_container_access, detect_capability_changes,
140    dump_container_access, rebuild_capability_table,
141};
142#[cfg(feature = "dev")]
143pub use config_warnings::BrinkConfigWarnings;
144#[cfg(feature = "dev")]
145pub use event::BrinkFlowReset;
146pub use event::{BrinkChoicesPresented, BrinkLineDelivered, BrinkStoryEnded, BrinkTurnDone};
147pub use flow::{Advance, BrinkFlow};
148pub use globals::{
149    BrinkContext, BrinkExecMode, BrinkGlobals, BrinkWorldPolicy, flow_context_view,
150    load_flow_state, save_flow_state,
151};
152#[cfg(feature = "effect-trace")]
153pub use ground_truth::{AccessKind, GroundTruthLog, ObservedAccess, Violation, check};
154pub use handle::{
155    BrinkDeadHandleDeref, BrinkHandleAppExt, HandleEntityRemap, HandleKind, HandleKinds,
156    HandleLoadError, HandleRegistry, HandleRetentionMetrics, HandleSaveEntry, HandleSaveState,
157    KindRetention, RehydrationPolicy, RehydrationReport, gc_on_turn_done, is_valid_system,
158    load_handles, save_handles,
159};
160pub use input::digit_key_to_choice_index;
161pub use line_tables::BrinkLocale;
162pub use locale::{
163    BrinkBaseLocale, BrinkCurrentLocale, BrinkLocaleChanged, BrinkLocaleOverride, InklLoader,
164    InklLoaderError, LocaleAsset, LocalizedTablesCache, SetBrinkLocale, apply_locale_overlay,
165    catch_up_loaded_locales, on_locale_changed,
166};
167pub use plugin::{BrinkAssetsPlugin, BrinkPlugin};
168#[cfg(feature = "dev")]
169pub use replay::{BrinkReplayConfig, BrinkReplayLog, ReplayQueryModeOverride, replay_on_reload};
170pub use request::{BrinkFlowRequest, FlowStart, fulfill_flow_requests};
171pub use sleep::{
172    DetectSummary, FlowSleep, SleepState, WakeArming, WakeConditionPurityError,
173    check_named_condition_purity, check_value_condition_purity, mark_wake_dirty, run_flow_sleep,
174};
175#[cfg(feature = "dev")]
176pub use source_loader::{CompileStoryInlineError, InkLoader, InkLoaderError, compile_story_inline};
177pub use transcript::{BrinkTranscript, refresh_transcripts};
178pub use wake_delta::{BrinkWorldDelta, WorldDelta};