Node editor: interactive storytelling
Interactive narrative affords a difficult authorship experience. This editorial system was designed for a company providing educational workshops that simulate applied ethical scenarios.
Workshop content is authored in-house, frequently in collaboration with external advisors. We therefore required an internal platform suitable for a largely non-technical audience. The following editor was embedded directly into Sanity Studio, which was being used to drive the application. It is built on top of React Flow.
Design choices
Workshops are conducted live, with multiple rooms in parallel. Each route must therefore be of a similar duration. The shortest and longest durational path is calculated live, allowing warnings to surface dynamically. Facilitators may then pace around any remaining variance. Terminal points may appear anywhere within the graph, making them hard to glance without a distinct treatment.
Plane Crash – City
Explosion at Train Station
Shape cues are borrowed from flowcharts
to provide affordances for both decision points and these terminal nodes. Space is at a premium, and
so the shrink-wrap problem is addressed through
react-wrap-balancer in disallowing the native
implementation.
Native experience
The editor is, fundamentally, a navigatory experience. As this supplants the native document pane, feature parity necessitates the inclusion of undocumented APIs. Drafting status is signified with an orange dot, and user presence is indicated by a stack of avatars. Both implementations adopt the same component used internally, silently exposed in the package.
Design tokens are inherited from the environment through the use of Sanity UI primitives. Tailwind has similarly been configured to extend these theme values.
Behavioural considerations
The graph is furnished with an acyclicer to remove the potential for loops. Redundant choices, overrides that merely reimplement the default route, are disallowed to maintain legibility. Layouting is handled through dagre.
Sanity is a real-time editor, and so connection modifications are patched live to ensure users can work in parallel. Undo functionality can emit rapid-fire patches, therefore update transactions are batched and debounced. Listeners are made instance-aware, allowing sessions in split view to remain synchronised.
Future directions
I’d like to alter the underlying architecture, divorcing documents from referrals. This will permit nodes to be cloned by reference, and allow context-aware variables and flags to alter narrative trajectory. A single document could then be shared across story arcs.
With the entire tree model now held within a single document, the native drafting, scheduling, and history experience is unlocked for free.