Playthrough.h header

#include <ew/app/Playthrough.h>

Namespace ew::app

PlayChoice struct

struct ew::app::PlayChoice

A way onward from where the reader is standing.

Members

QString ew::app::branching::PlayChoice::label

What the reader picks – a choice's option label, or "Continue" phrased by the client.

ew::core::foundation::ContentId ew::app::branching::PlayChoice::sceneId

The scene the option leads to.

ew::core::foundation::BranchNodeId ew::app::branching::PlayChoice::nodeId

The node the option leads to.

bool ew::app::branching::PlayChoice::available = true

Whether the story's current state permits this way onward.

A reader only ever sees the permitted ones. They are all reported so a client can show an author WHY a branch never opens – and, in debug, let them take it anyway.

QString ew::app::branching::PlayChoice::reason

Why it is or is not open, in the story's own terms: "gold >= 50 is false". Empty for a way onward nothing gates.

QString ew::app::branching::PlayChoice::requirement

What the reader is told about a shut option – "Requires 10 Charisma" – when its author chose to show it rather than hide it. Empty otherwise.

The author's own words, not the expression: the expression is what the story tests, and putting a variable name in front of a reader leaks the machinery into the fiction.

PlayStep struct

struct ew::app::PlayStep

One node a reader arrived at, and what they did to leave it.

Members

ew::core::foundation::ContentId ew::app::branching::PlayStep::sceneId

The scene the node is in – a playthrough crosses scenes (2.5).

ew::core::foundation::BranchNodeId ew::app::branching::PlayStep::nodeId

The node arrived at.

QString ew::app::branching::PlayStep::text

What was read there.

QString ew::app::branching::PlayStep::chosen

The label of the option taken to leave it; empty for a step that was simply continued through, and for the node the reader is standing on now.

bool ew::app::branching::PlayStep::forced = false

Whether the author took a way onward the story's own state forbade.

Recorded on the step and shown in the transcript, because a forced run is not a run: it proves the branch behind the gate reads well, and proves nothing about whether a reader can ever get there. A transcript that did not say so would be evidence of something that never happened.

Playthrough class

class ew::app::Playthrough

A reader walking one path through a story, one node at a time.

Not simulateScene. That is a whole-graph analysis: it explores every choice at once, deliberately, to answer "what can never be reached". This answers a different question – "what happens if I go THIS way" – and it is the question an author asks all day. Both exist because neither can be built out of the other: the analysis has no current node and no history, and a playthrough that explored every branch would not be a playthrough.

The two share applyEffects and conditionHolds rather than each having their own, so an author cannot be told one thing by the player and another by the validator about the same node.

Effects apply on ARRIVAL, before the node's ways out are offered, exactly as the analysis does: a Condition carrying an effect tests the state it arrived with, and everything after it sees the change.

Members

ew::app::branching::Playthrough::Playthrough(const ew::core::project::Project &project, const ew::core::branching::BranchScene &scene)

Starts a playthrough of scene, with project's variables at their initial values. Neither is owned, and both must outlive this.

void ew::app::branching::Playthrough::restart()

Returns to the scene's start, applying setOverrides, and empties the transcript.

void ew::app::branching::Playthrough::setOverrides(const std::vector< ew::core::branching::RunOverride > &overrides)

Starts each named variable somewhere other than the project declares, from the next restart.

The project is never touched. Variable::initialValue is what the story starts from and what every export and analysis reads; these are a lens for beginning in the middle of a story without rewriting its beginning. An override naming a variable the project no longer declares is ignored rather than invented.

const ew::core::branching::BranchScene * ew::app::branching::Playthrough::currentScene() const

The scene the reader is in; null only when the scene has no usable start node.

const ew::core::branching::BranchNode * ew::app::branching::Playthrough::currentNode() const

The node the reader is standing on; null when the playthrough cannot start or has ended.

const std::vector< PlayChoice > & ew::app::branching::Playthrough::choices() const

The ways onward a READER is offered, in order. Empty at an ending.

The ones the story's state permits, PLUS any whose author chose to show them greyed rather than hide them (BranchLink::whenUnavailable). Those come back with PlayChoice::available false and a PlayChoice::requirement to render beside them, and take refuses them – telling a reader what they cannot do is a design decision, and letting them do it anyway is not. A single unlabelled way onward is what a client shows as "Continue".

const std::vector< PlayChoice > & ew::app::branching::Playthrough::waysOnward() const

Every way onward, open or shut, each carrying whether it is open and why – the debug view.

Separate from choices rather than replacing it, because they answer different questions and only one of them is what a reader sees. A panel driving a normal playthrough off this list would present shut branches as though they were live.

void ew::app::branching::Playthrough::take(std::size_t index)

Takes the choice at index, moving the reader to it and applying what it enters.

Out-of-range does nothing, so a stale click cannot walk the story somewhere unasked – and neither does a choice shown greyed, which a reader can see and must not be able to pick. force is how an AUTHOR takes one anyway.

void ew::app::branching::Playthrough::force(std::size_t index)

Takes the way onward at index of waysOnward, whether or not the story permits it.

Forcing a shut branch is the only practical way to reach a late-game one, and the step records that it was forced – a transcript that did not say so would be evidence of a run that never happened. Forcing an OPEN way is an ordinary step and is not marked.

bool ew::app::branching::Playthrough::canStepBack() const

Whether there is a step to go back to.

void ew::app::branching::Playthrough::stepBack()

Undoes the last step, restoring the variables to exactly what they were on arriving at the previous node.

The state is RESTORED from a record kept per step rather than recomputed by replaying the path: replaying would give the same answer only while every effect is deterministic, and the day one is not, stepping back would silently land the author in a world their story never produced.

const VariableState & ew::app::branching::Playthrough::variables() const

The variables as they stand where the reader is.

const std::vector< PlayStep > & ew::app::branching::Playthrough::transcript() const

Every node arrived at, in order, ending with the one the reader is on.

QString ew::app::branching::Playthrough::transcriptText() const

The transcript as plain text, one line per step, ready for the clipboard.