Skip to main content

QuestEffect

Struct QuestEffect 

Source
pub struct QuestEffect {
    pub when: Option<Guard>,
    pub happening: Option<Happening>,
    pub audience: Option<EffectAudience>,
    pub within: Option<StealthZone>,
    pub verb: Verb,
}
Expand description

An effect fired by quest progress: one guard, one story note, one verb.

The guard is a property of an effect, not of the verb that first wanted one, so it is declared once in Guard and every verb carries it — including the staging and souls vocabulary (spawn-actor, move-actor, set-checkpoint, bonfire, begin-stealth, sequence, …) that could not be branch-gated while the fields lived on the variants. A gate that can never open on a campaign-complete is caught where it belongs, by the completability proof.

verb is #[serde(flatten)], so the JSON is unchanged in shape apart from the guard moving under when: {"type": "open-gate", "anchor": "…", "when": {"requires_flags": ["…"]}}. Verb keeps deny_unknown_fields, which is what the flattened deserializer applies to everything the outer struct did not claim — an author’s typo is still DW0100.

Fields§

§when: Option<Guard>

When this effect fires. None is the always-open gate.

§happening: Option<Happening>

What this beat does to the story (spec-0025) — validation metadata with no emission of its own.

§audience: Option<EffectAudience>

Who a player-facing effect addresses (spec-0085 §3.2): party or actor, the one player whose act fired the root. Absent = the root’s own answer — a quest completion addresses the party, a death, a respawn, a purchase, a credited kill and a presser trigger address their actor, a polled trigger, a trap and a shortcut address the party — so a campaign that never writes the field emits exactly what it emitted before it existed.

A property of the envelope rather than of any verb: it reaches every verb the emitter addresses to players (Verb::addresses_players), and on any other verb it is refused (DW0942). actor where emission has no acting player is DW0503.

§within: Option<StealthZone>

Narrows the audience to players inside an anchor-centred box (anchor ± extent, spec-0085 §3.2) at the moment the effect fires — the same StealthZone a begin-stealth zone and a lethal_volumes[] region take, resolved through the one Plan::zone_box. Composes with Self::audience: actor + in is the actor, if they stand in the box.

One field on the envelope, reaching every player-facing verb; refused on any other (DW0942) — a box narrows an audience, and a world fact has none.

§verb: Verb

What the effect does.

Implementations§

Source§

impl QuestEffect

Source

pub fn gate(&self) -> Gate<'_>

This effect’s whole gate, as one value (DSL v0.10).

Source§

impl QuestEffect

Source

pub fn nested_effect_dispatch(&self) -> Vec<(&[QuestEffect], NestedDispatch)>

Each nested effect list with how it is dispatched (NestedDispatch) — the same lists, in the same order, as Self::nested_effect_lists.

Source

pub fn addresses_players(&self) -> bool

Whether this effect addresses players at all — Verb::addresses_players.

Source

pub fn open_gate_anchor(&self) -> Option<&AnchorId>

The gate anchor if this is open-gate.

Source

pub fn close_gate_anchor(&self) -> Option<&AnchorId>

The gate anchor if this is close-gate (DSL v0.6).

Source

pub fn close_gate_sealed_hint(&self) -> Option<&str>

The authored sealed_hint if this is a close-gate that declares one (DSL v0.8). None for every other effect and for a close-gate that takes the compiler’s canonical English seal line.

Source

pub fn spawn_wave(&self) -> Option<&WaveId>

The wave id if this is spawn-wave (v0.3).

Source

pub fn set_flag(&self) -> Option<&FlagId>

The flag id if this is set-flag (v0.3).

Source

pub fn give_item(&self) -> Option<&str>

The item id if this is give-item (v0.3).

Source

pub fn give_item_named(&self) -> bool

true if this is a give-item carrying a v0.4 display name.

Source

pub fn give_carrier(&self) -> Option<Carrier>

The declared carrier if this is a give-item that states one (v0.6, spec-0018). None for any other effect and for a give-item that leaves it absent — absent reads as Carrier::All, and the distinction matters only for the pre-0.6 reserved-field gate.

Source

pub fn gives_to_one(&self) -> bool

Does this give-item hand a single copy to the acting player (v0.6, spec-0018)? false for every other effect and for the party-wide default.

Source

pub fn set_block(&self) -> Option<(&AnchorId, &str)>

The set-block block id if this is a v0.4 set-block effect.

Source

pub fn despawn_npc(&self) -> Option<&NpcId>

The NPC id if this is a v0.4 despawn-npc effect.

Source

pub fn move_npc(&self) -> Option<(&NpcId, &Mark)>

(npc, to) if this is a v0.4 move-npc effect.

Source

pub fn v03_effect(&self) -> Option<&'static str>

The v0.3 effect name if this effect is one introduced in DSL v0.3 (give-item/set-flag/spawn-wave). These validate in v0.3 campaigns .

Source

pub fn v04_effect(&self) -> Option<&'static str>

The v0.4 effect name if this effect is one introduced in DSL v0.4 (narrate/set-block/despawn-npc/move-npc/cutscene). These validate in v0.4 campaigns.

Source

pub fn v05_effect(&self) -> Option<&'static str>

The v0.5 effect name if this effect is one introduced in DSL v0.5 (set-time/set-weather, spec-0010).

Source

pub fn v06_effect(&self) -> Option<&'static str>

The v0.6 effect name if this effect is one introduced in DSL v0.6 (set-checkpoint, spec-0012; begin-stealth/end-stealth, spec-0014; play-sound, spec-0014; the scripted-actor staging verbs spawn-actor/despawn-actor/move-actor/unleash-actor/sequence, spec-0014). These validate in v0.6 campaigns earlier. (The narrate art style is a v0.6 addition to an existing verb — see QuestEffect::narrate_art — not a new effect.)

Source

pub fn v10_effect(&self) -> Option<&'static str>

The v0.10 effect name if this effect is one introduced in DSL v0.10 (set-state/add-state/clear-state and the region writes fill-region/clear-region, spec-0031). These validate in v0.10 campaigns.

Source

pub fn v12_effect(&self) -> Option<&'static str>

The v0.12 effect name if this effect is one introduced in DSL v0.12 (open-way, spec-0042).

Source

pub fn way_write(&self) -> Option<(&PrefabId, &str)>

The way this effect opens (DSL v0.12, spec-0042): the placed piece and the name of one way that piece’s spatial contract exports.

The third spelling of the one region write, beside QuestEffect::region_write (the author’s own box) and QuestEffect::gate_region_write (a gate anchor’s box). It answers with a reference and never with geometry, because the geometry is not the campaign’s to state: the cells, the block and the direction all live in the piece’s metadata, and the compiler resolves them there (compiler::ways). A region-shaped accessor here would be the second authority this surface exists to avoid.

Source

pub fn region_write(&self) -> Option<(&StealthZone, Option<&str>)>

The one region write, whichever verb spelled it (DSL v0.10, spec-0031): the box to write and the block to write it with — None for the block meaning clear to air.

This is the accessor the capability belongs to. It answers for fill-region / clear-region, which name their own box; open-gate / close-gate are the same operation over a box a prefab gate anchor declares, so they answer through QuestEffect::gate_region_write — the anchor is theirs, the operation is shared.

Source

pub fn gate_region_write(&self) -> Option<(&AnchorId, bool)>

The gate anchor this effect writes, and whether the write fills it: Some((anchor, true)) for close-gate, Some((anchor, false)) for open-gate, None for everything else.

The gate half of QuestEffect::region_write: same operation, but the box and the fill block come from the prefab’s gate anchor rather than from the author. Everything that reasons about runtime region writes reads both accessors and nothing else.

Source

pub fn volley(&self) -> Option<(&str, &AnchorId, &StealthZone, u32, u32)>

(projectile, from_anchor, kill_zone, salvos, interval) if this is a volley (spec-0022), with the documented defaults already applied.

Source

pub fn collapse(&self) -> Option<(&StealthZone, &str, Option<&str>)>

(region_anchor, falling_block, then_floor) if this is a collapse (spec-0022), with the documented default already applied.

Source

pub fn spawn_npc(&self) -> Option<&NpcId>

The NPC id if this is a v0.6 spawn-npc effect (the dual of QuestEffect::despawn_npc).

Source

pub fn body_entry(&self) -> Option<&str>

The body this effect puts into the world, by id, for every body class alike (BodyRef).

spawn-npc and spawn-actor are the two, and they are answered in one place so a rule about a body’s lifetime quantifies over bodies rather than over the verb that first needed it. A body’s OTHER entry — standing on its mark from world init — is not an effect at all and is BodyRef::at_world_init.

unleash-actor is deliberately not an entry: it puts no new body on the mark, it replaces the one already standing there (see Self::body_exit).

Source

pub fn body_exit(&self) -> Option<&str>

The body this effect takes out of the world, by id, for every body class alike.

despawn-npc and despawn-actor remove the body outright. unleash-actor is the third: it kills the staged puppet and stands a real-AI twin in its place, and from that moment the compiler makes no claim about where that body is or whether it is still alive — the twin walks, fights and dies under vanilla AI. Answering all three here is what keeps “can this body still be standing?” from being decided one verb at a time.

Deliberately NOT an exit: move-npc / move-actor. A walked body is still in the world, and its declared mark is still the cell the engine summoned it onto — a mark two live bodies share is shared whether or not one of them has since walked off it.

Source

pub fn set_checkpoint(&self) -> Option<(&AnchorId, &[QuestEffect])>

(anchor, on_respawn) if this is a v0.6 set-checkpoint effect.

Source

pub fn bonfire(&self) -> Option<(&AnchorId, &[QuestEffect])>

(anchor, on_rest) if this is a bonfire effect (spec-0016 §1).

Source

pub fn bonfire_labels(&self) -> Option<BonfireLabels<'_>>

The bonfire’s authored rest-dialog strings, each None when unauthored (the compiler then bakes its canonical English). None for every other effect (spec-0016 §1).

Source

pub fn damage_within(&self) -> Option<&StealthZone>

The within filter zone if this is a v0.6 damage-players effect that declares one (the in spatial scope). None for an unscoped damage-players and for every other effect.

Source

pub fn begin_stealth(&self) -> Option<(&[StealthZone], &[QuestEffect], u32)>

(zones, on_caught, grace_ticks) if this is a v0.6 begin-stealth effect.

Source

pub fn set_time(&self) -> Option<WorldTime>

The target time if this is a v0.5 set-time effect.

Source

pub fn set_weather(&self) -> Option<WorldWeather>

The target weather if this is a v0.5 set-weather effect.

Source

pub fn nested_effect_lists(&self) -> Vec<&[QuestEffect]>

The effect lists nested one level inside this effect (DSL v0.6): a sequence’s per-step effects (in step order), a set-checkpoint’s on_respawn, a begin-stealth’s on_caught, and a move-actor’s / move-npc’s on_arrive. Empty for a leaf effect.

This is the single authority on effect nesting. Every deep traversal — the flag/wave producer scans, the checkpoint/stealth collector, the l10n string inventory, and emission — walks the tree through it (see Self::visit_deep), so a new nesting site is picked up everywhere at once and no walker can silently miss a list (the class of bug where a set-flag/set-checkpoint nested in a sequence was skipped).

Source

pub fn visit_deep<'a>(&'a self, f: &mut dyn FnMut(&'a QuestEffect))

Visit self and every transitively nested effect (depth-first, pre-order), descending through Self::nested_effect_lists.

Source

pub fn nested_effect_lists_keyed_mut( &mut self, ) -> Vec<(String, &mut [QuestEffect])>

Each nested effect list (Self::nested_effect_lists) paired with the stable key segment used to derive child l10n keys / diagnostic paths, and exposed mutably so the localization pass can rewrite nested player-visible strings in place. Segments: seq.<step> for each sequence step (step index), respawn for set-checkpoint.on_respawn, caught for begin-stealth.on_caught, arrive for move-actor.on_arrive. Kept in lockstep with nested_effect_lists (same lists, same order) — the position- derived segments make every derived key deterministic and stable across builds (ADR-0006 byte-identity).

Source

pub fn nested_effect_lists_labeled( &self, ) -> Vec<(String, String, &[QuestEffect])>

Immutable sibling of Self::nested_effect_lists_keyed_mut that additionally exposes the JSON-pointer path segment for each nested list, so a deep consumer scan (sound/art/give/wave refs) can report a precise diagnostic path and the matching l10n key. Each entry is (path_seg, key_seg, list); the caller appends the per-effect index — /{j} to the path, .{j} to the key. Kept in lockstep with nested_effect_lists / nested_effect_lists_keyed_mut (same lists, same order): the l10n key segments match nested_effect_lists_keyed_mut exactly (seq.<step>/respawn/caught/ arrive), and the path segments name the real fields (steps/<step>/effects, on_respawn, on_caught, on_arrive).

Source

pub fn anchor_refs(&self) -> Vec<(String, &AnchorId, Option<StationKind>)>

Every world anchor this effect names at this node — the single authority on the anchor-bearing effect surface, the referential sibling of Self::nested_effect_lists. Each entry is (json_path_suffix, anchor), where the suffix is appended to the effect’s own JSON pointer (anchor, to/anchor, in/anchor, zones/<i>/anchor, at/anchor, shots/<i>/path/<j>/anchor, …).

Not recursive: pair it with Self::visit_deep to sweep a whole effect tree. Every consumer that must resolve an anchor — the DSL’s DW0142 reference scan, the compiler’s build-time resolution seal (DW0360) — goes through here, so a new anchor-bearing variant (or a new anchor field on an existing one) is picked up by all of them at once. That closes the silent-drop class of bug: an anchor-bearing effect whose anchor is typo’d used to emit nothing (the emitter’s for … if name == anchor loop simply found no match) while every shallow validator looked straight past it.

§The third element is the SHAPE the site demands

A reference is not only a name: close-gate fills and clears a region and bonfire seats a body, and until spec-0052 those two sat in one match arm with nothing recording the difference. The demand rides with the reference so that a new anchor-bearing variant cannot be added without stating what it does with the anchor — the same reason this is one authority and not three walks.

A demand is stated only where the shape is structurally required, and the line is drawn where this engine’s own DW0845 already draws it — a region is not a place to stand:

  • StationKind::Gate where the verb cannot function without a region that seals and clears: the two gate verbs. A point is not a gate, and gate_region_block_any finds nothing for one.
  • StationKind::Point where a body is put: a checkpoint seat, a bonfire, a move-npc/move-actor destination, a teleport destination. A body cannot stand inside bars.
  • None wherever a reference merely names a location — every anchor-centred volume’s centre, every camera field, a set-block, a play-sound. A gate region’s own corner is a perfectly good answer there, and refusing it would refuse correct content.

That last case is not a gap left for later. An earlier draft of this rule demanded a point at every non-gate site, and the gallery refused to compile: trigger/east-door-wrong-side is a use trigger sitting on the very anchor/seam-… of a barred door so that it can say “the east door does not open from this side”. A check that resolves against a smaller world than the campaign has refuses CONTENT, which is the lesson DW0343 carries three files away.

Source

pub fn subject_objects(&self) -> Vec<&str>

Every object of a subject kind this effect names at this node — the npc/, actor/, wave/ and anchor/ ids Happening::subject may name, in a fixed order, deduplicated (spec-0071 §3).

The bodies come from Self::body_entry / Self::body_exit and the move verbs; the anchors come from Self::anchor_refs, the single authority on the anchor-bearing surface, so a verb that gains an anchor gains it here too. Not recursive: a sequence’s steps each answer for themselves.

This is a question about the object class a beat can be about, not about a list of verbs somebody maintains — which is why unleash-actor (one actor), set-block (one anchor) and fill-region (one anchor) answer it without being named anywhere, and why move-actor (an actor AND a destination anchor) and teleport (two anchors) answer with two.

Source

pub fn happening_subject(&self) -> Option<HappeningSubject<'_>>

What this effect’s happening is about: the subject the branch chronicle records and the contradiction proof (DW0485) reasons over (spec-0071 §3).

A stated Happening::subject always wins — the caller knows more. An absent one resolves to the effect’s own object when it has exactly one (Self::subject_objects), because the beat that opens a gate is about that gate and the id is otherwise typed twice, two keys apart. An effect with several objects, or none, resolves nothing: naming one of them would be the compiler guessing which.

The one derivation. The namespace check (dsl::validate) and the chronicle writer (delvec::compiler::branch) both read the subject through here, so a beat cannot be about one thing for the proof and another for the account a reader is handed.

Source

pub fn cutscene_look_at(&self) -> Option<&Mark>

The cutscene camera subject if this is a single-shot cutscene carrying the v0.6 look_at field.

Source

pub fn cutscene_party(&self) -> Option<CutsceneParty>

Whether this cutscene shows the party’s bodies (spec-0095): the stated party, or present when none is stated. None for any other effect.

Source

pub fn cutscene_multi_shot(&self) -> bool

true if this is a cutscene written in the v0.6 multi-shot form .

Source

pub fn cutscene_shots(&self) -> Option<Vec<CameraShot>>

The normalized shot list of a cutscene, whichever spelling was used: the v0.6 shots list as-is, or the v0.4 path/seconds/look_at fields as a single shot. None for a non-cutscene effect; an empty list for a cutscene whose shape is invalid (DW0199 reports that).

Source

pub fn narrate_art(&self) -> bool

true if this is a narrate carrying the art style (glyph-checked DW0328).

Source

pub fn narrate_art_text(&self) -> Option<&str>

The narrate line’s text if this is a narrate with the art style.

Source

pub fn narrate_on_screen(&self) -> Option<(NarrateStyle, &str)>

The narrate line’s style and text if this is a narrate rendered on screen — title, subtitle or art — rather than in chat. These are the styles vanilla draws centred and unwrapped, so their rendered width is length-checked against the screen (DW0330); chat scrolls and wraps, so it is exempt.

Source

pub fn sound_refs(&self) -> Vec<(&'static str, &str)>

Every vanilla sound-event id this effect references, for registry validation (DW0326): a play-sound’s sound, and a narrate’s optional sound. Returns (subpath, id) pairs where subpath locates the field within the effect (e.g. sound).

Source

pub fn play_sound_actor(&self) -> Option<&str>

The play-sound at: actor id, if this effect is a play-sound targeting an actor (rejected DW0335).

Source

pub fn requires_flags(&self) -> &[FlagId]

The per-effect flag gate: flags that must ALL be set (per party) for this effect to fire. Empty for an ungated effect. Read off the one Guard, so every verb answers it — the staging and souls vocabulary included.

Source

pub fn forbids_flags(&self) -> &[FlagId]

The per-effect negative flag gate: flags whose being set suppresses this effect — the dual of QuestEffect::requires_flags, on the same guard.

Source

pub fn requires_state(&self) -> &[StateCompare]

The numeric gate terms (spec-0031) — the third axis of the same guard, so “which verbs are gatable” has exactly one answer.

Source

pub fn writes_state(&self) -> Option<(&StateId, StateWrite)>

The datum this effect writes and how, if it is one of the DSL v0.10 state verbs (set-state / add-state / clear-state).

Source

pub fn move_npc_on_arrive(&self) -> Option<&[QuestEffect]>

The on_arrive bundle if this is a move-npc carrying one (DSL v0.6; parity with move-actor). None for a bare move-npc and every other effect.

Source

pub fn actor_ref(&self) -> Option<&ActorId>

The actor id this effect targets, if it is one of the actor staging effects (spawn-actor/despawn-actor/move-actor/unleash-actor). sequence has no single actor (its nested effects each carry their own).

Source

pub fn status_effect_refs(&self) -> Vec<(&'static str, &str)>

Every vanilla status-effect id this effect names, for registry validation (DW0192) — the sibling of Self::sound_refs and the single authority on the status-effect-bearing verb surface. (subpath, id) pairs; empty for a clear-effect that names none (which clears all).

Source

pub fn give_effect( &self, ) -> Option<(&str, u32, u32, bool, Option<&StealthZone>)>

(effect, seconds, amplifier, hide_particles, in) if this is a give-effect (DSL v0.10), with the documented defaults already applied.

Source

pub fn clear_effect(&self) -> Option<(Option<&str>, Option<&StealthZone>)>

(effect, in) if this is a clear-effect (DSL v0.10). The effect is None for the clear-everything form, exactly as vanilla spells it.

Source

pub fn teleport(&self) -> Option<(&StealthZone, &Mark)>

(from, to) if this is a teleport (DSL v0.10): the source volume and the destination mark.

Trait Implementations§

Source§

impl Clone for QuestEffect

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for QuestEffect

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for QuestEffect

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<Verb> for QuestEffect

Source§

fn from(verb: Verb) -> Self

An unguarded effect with no story note and the root’s own audience — the shape a compiler-synthesized beat and most tests want.

Source§

impl JsonSchema for QuestEffect

Source§

fn schema_name() -> Cow<'static, str>

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
Source§

fn inline_schema() -> bool

Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being re-used where possible using the $ref keyword. Read more
Source§

impl PartialEq for QuestEffect

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for QuestEffect

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for QuestEffect

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.