stableEngine v0.4.0 Updated 26 Aug 2026, 12:00

Studio guide

Studio is Subtext's built-in visual novel editor. It lets an author maintain an editable phone-story project, write branching conversations, connect them to the phone apps, manage media, and create a playable package without writing GDScript.

Studio is currently an early preview and writes the subtext-0.4.0 engine format. Older readable 0.x sources are normalized to 0.4.0 when Studio saves them. The story format and editor may still receive breaking changes. The welcome dialog links to the Subtext Discord for development updates and suggestions.

For the editable text syntax, see the Subtext story format.

Opening Studio

Authors open Studio from the normal Studio entry point. The first screen separates:

  • Original stories shipped with Subtext. Players can never edit these files directly. An original can expose a Duplicate action, which creates an independent editable copy with its media.
  • Your projects, stored locally and fully editable. From here an author can create a project, use Import Project to load an editable .subtext-project bundle, open a project, or delete it.

Published .subtext stories never become editable Studio projects. Install them with Import Story in Play Stories > Community instead. Deleting an editable project moves its folder to the operating system's trash when possible.

Feature overview

AreaWhat Studio provides
Story libraryCreate, import, duplicate, open, and delete editable projects.
Story settingsEdit title, author, description, structured tags, cover, phone wallpaper, optional banking, and initial phone content.
CharactersCreate characters, choose script keys, import avatars including the player's, and configure Contacts descriptions and scores.
SkillsDefine player-facing numeric skills with an icon, starting score, and optional minimum and maximum.
ChaptersAdd, rename, reorder, duplicate, delete, and keep future chapters as unpublished drafts.
ConversationsAdd, rename, reorder, duplicate, delete, choose participants, and define start conditions.
Sequence editorAdd and reorder dialogue, choices, media, timing, branching, progress, endings, and phone actions.
Media & eventsReview content for a whole story or one chapter, edit it in place, and jump back to its source conversation or branch.
Text workflowCopy or replace a story, chapter, or conversation as readable Subtext source.
DistributionImport or export editable .subtext-project bundles, and create immutable playable .subtext versions.

Creating and managing stories

New stories

Create a project creates a local editable project with:

  • a unique story id;
  • editable title, author, description, asset style, and content tags;
  • the reserved player character;
  • an initial Introduction chapter;
  • an empty conversation list.

Changes are autosaved. The status in the Studio header reports saving, saved, copied, imported, or validation errors.

Duplicating an original

If an original allows duplication, Duplicate copies its source and assets into a new editable project. The copy receives its own id and can be changed without affecting the original or its saves.

Story metadata and presentation

The story screen edits:

  • Story name;
  • Author;
  • Story description, shown in story selection;
  • Completion status: ongoing, on hold, abandoned, or completed. Completed stories receive a visible completed tag;
  • Tags, entered as a comma-separated list;
  • Story cover;
  • Phone wallpaper;
  • Enable the banking app and, when enabled, its dollar-denominated initial balance.

Cover and wallpaper files accept PNG, JPG, JPEG, WebP, and animated GIF. They may be selected with the file picker or dragged onto the appropriate area. The cover editor includes cropping for static images; GIF files are kept uncropped so their animation is preserved. Removing a wallpaper restores the default Mountains image.

Characters

The character screen lists every character in the story, including the reserved player. An author can:

  • add a character;
  • edit its player-facing Display name;
  • edit its author-facing Script key;
  • choose or drag a PNG or animated GIF avatar for any character, including the player;
  • crop the avatar before saving it;
  • replace an existing avatar;
  • add a description shown in Contacts for a non-player character;
  • show or hide that character's affection score;
  • edit the score's internal story-value key and Contacts display maximum.

The player script key is reserved and cannot be renamed. Other keys must start with a letter or _ and may contain lowercase letters, numbers, _, -, and ..

Renaming a script key updates references throughout the story, including participants, senders, joins and leaves, gift recipients, and conditions inside branches. Existing media filenames are intentionally left unchanged.

Every non-player character appears as an expandable entry in the Contacts app with their avatar and optional description. Enabling Show an affection score in Contacts adds a progress bar backed by a global numeric story value. A contact remains visible when its score is disabled. In Messages, tapping a character avatar opens that Contacts entry, and Back returns to the conversation.

Skills

The story screen opens Skills, where an author can add or remove numeric skills. Each skill has:

  • a player-facing name;
  • an internal id used by conditions;
  • one of the built-in icons: Star, Stars, Brain, Build, Gym, Heart, or Speaking;
  • a starting score;
  • a minimum, which defaults to 0;
  • an optional maximum. Bounded skills use the full minimum-to-maximum range in the Journal bar; unbounded skills show their value without a bar.

New skills default to the Star icon, a starting score and minimum of 0, and no maximum. Renaming a skill id updates its score blocks, start and Wait conditions, condition branches, and choice requirements. During play, skills appear before chapters in the Journal. If a story defines no skills, that section is omitted entirely.

Use Change skill score to add or remove any whole-number amount. Use Increase contact score for the same operation on a configured character score. Normal playback shows a short signed score popup; affection uses a heart, while skills use their selected icon.

Banking

Banking is disabled by default. Enable it from the story screen and choose the player's initial balance. When disabled, the Bank app is absent, Bank transfer blocks are invalid, and Nozamart gifts do not require money. Current Studio controls author and display banking values in dollars.

When enabled:

  • the Bank app shows the current balance and newest-first transaction history;
  • Bank transfer can make the player pay a contact or automatically receive money from one;
  • outgoing payments present a button and remain unavailable when the balance is too low;
  • incoming payments immediately create a conversation card such as Ai-chan sent you $20.00;
  • Nozamart items gain a Price field, affordable purchases debit the balance, and unaffordable items cannot be sent;
  • bank_balance becomes available to start conditions, Waits, condition blocks, and choice requirements.

Preloaded content

The story screen opens Preloaded content, which defines what is already present when a fresh playthrough begins. Studio can preload:

  • conversations, including conversations whose normal start conditions are not yet satisfied;
  • Gallery photos and videos;
  • OverFaunt posts;
  • Nozamart items;
  • GPS locations;
  • global story values.

Preloaded conversations are created directly from this screen and can then be edited like any other conversation. Studio does not allow an existing chapter conversation to be added to Preloaded content. App content uses the same visual inspectors and media picker as conversation actions, but it is not inserted into a chat. Preloaded Gallery media goes directly to Gallery.

Preloaded content is applied once per fresh playthrough. A preloaded conversation's linear messages and media are inserted as already-read history before the first chapter separator; photos and videos marked for Gallery are available there too. Interactive choices, unresolved waits, branches, and chapter endings remain live instead of having an outcome invented during preload. Gallery media, OverFaunt posts, Nozamart items, and GPS locations do not create a new-content badge. Restarting the entire story rebuilds the preloaded content, while restarting a chapter restores a checkpoint that already contains it. Copying or loading story text preserves the @preload section.

Chapters

The story screen presents chapters in their playback order. Chapters can be:

  • added;
  • renamed directly in the list;
  • reordered;
  • duplicated with all their time slices and conversations;
  • deleted, except when it is the only remaining chapter;
  • opened for detailed editing.

Inside a chapter, Studio also edits its name and optional subtitle, and presents its time slices, conversations, and media. Conversation names edited directly in this timeline are author-only labels for organizing similar threads. Open a conversation to edit the title displayed to players.

Time slices

Time slices divide a chapter into chronological sections. The first slice is the chapter opening and has no transition. Later slices have:

  • free transition text, such as One hour later, Later, or Three months later;
  • a Small or Big transition;
  • the same All/Any trigger conditions used by conversations.

Conversations are created inside a slice. During playback, a conversation with no start condition becomes available as soon as its slice activates; other conversations in the active slice can use their own start conditions. Every conversation below the next slice stays locked. With no explicit trigger, the next slice waits until every conversation in the active slice has finished. Authored All/Any trigger conditions override that default. Once the next slice is ready, playback stops at the boundary until the player returns to the phone home screen. The transition plays there; only after it finishes does the new slice activate, stage its first incoming message, and send its notification.

Each conversation thread receives the slice label as a history separator only when a later message or media entry actually arrives. A trailing separator stays hidden, and several slices without intervening content collapse to the newest label. Reordering slices changes the chapter chronology.

Draft chapters

Include this chapter in distributed game controls whether a chapter enters the playable version. An excluded chapter remains editable and is marked Draft, allowing an author to begin future content while continuing to distribute earlier chapters.

The initial chapter is always included. New non-initial chapters and duplicated chapters start as drafts. Normal gameplay hides drafts; developer tools may still play them. Create playable version omits draft chapter source and assets used only by drafts.

Conversations

Within a chapter, conversations can be added, renamed, reordered, duplicated, deleted, copied as text, or replaced from text.

Participants

The participant picker controls which characters belong to the conversation. The player is always included. Group conversations can use any number of the other story characters.

During playback, join and leave actions can change group membership without creating a new conversation thread.

Start conditions

With no start condition, a conversation becomes available as soon as its slice activates. Otherwise, Start when can require either:

  • All conditions (AND); or
  • Any condition (OR).

Available conditions are:

ConditionMeaning
Milestone reachedA named chapter-local or global milestone was reached.
Conversation finishedAnother conversation in the current chapter reached its end.
Location visitedThe player visited an unlocked GPS location.
Gift sentA specific Nozamart item was sent to a recipient.
OverFaunt post viewedThe player opened a specific post.
Story valueA global story value, skill, affection score, or enabled bank balance matches a comparison.

Story values support truthy, falsy, equality, inequality, and ordered comparisons where applicable. Studio labels configured sources as Skill, Affection, or Bank balance so authors do not need to remember their internal ids.

The conversation being opened owns its start conditions. For a normal sequence, give conversation B a Conversation finished: A condition. When B must become available before A ends, set a milestone in A, use that milestone as B's start condition, then add a Wait in A if A must resume only after B finishes. Start conditions reveal conversations; Wait only pauses the sequence containing it.

Messages and actions

The sequence editor shows the conversation in order. Every block can be opened to edit its settings, reordered, duplicated, or deleted. Studio automatically maintains the normal next-block flow.

Blocks can also be inserted anywhere in the sequence:

  • on desktop, hover between two cards to reveal the circular + button;
  • on touch screens, open a card and use Add block before;
  • the existing quick-add bar continues to append blocks to the end.

All three entry points use the same context-aware block menu. After insertion, Studio opens the new block and recalculates the conversation flow automatically.

The quick-add bar groups blocks into Message, Choice, Media, and Actions.

During play, the player can resume the story from an earlier message. Right-clicking a message on desktop, or pressing and holding it on mobile, opens a confirmation. Confirming restores the story state at that point, removes later progress from the current timeline, and continues just after the selected message. This also lets a player revisit an earlier choice without restarting the whole chapter.

Conversation blocks

BlockPurpose
MessageSend dialogue from one participant.
System messageAdd centered contextual text to the current conversation, or silently broadcast it to every discovered conversation.
System noticePause the story with a full-screen out-of-story card, then resume after the player dismisses it.
ChoicePresent two to four player answers, each with an optional condition and branch.
Join / LeaveAdd or remove a character from the current group thread.
Fake typingShow a character typing for a chosen duration, then remove the indicator without sending a message.
DelayPause playback for a duration.
Cum effectInside a Moment, play a small then full white flash and leave the built-in cum texture over its background.
WaitPause until all or any selected story/phone conditions are satisfied.
Increase contact scoreAdd or remove points from a non-player character whose Contacts score is enabled.
Change skill scoreAdd or remove points from a skill defined on the story screen.
Bank transferAutomatically receive money from a contact or wait for the player to confirm a payment.
Add new contactShow a phone notification and reveal a contact in Messages without creating an unread message.

An Add new contact block targets another conversation in the same chapter. That conversation remains hidden until the block runs, even when it has no Start when conditions. The notification then announces the new contact and the conversation appears in Messages as already read. Author its first block as a player message or choice when the player should initiate the exchange.

System messages

A System message inserts centered contextual text without playing a slice transition or leaving the conversation. Show in every discovered conversation is disabled by default. When enabled, the same entry is copied silently to every conversation already known to the player, without notifications, unread dots, or changes to conversation ordering.

System notices

A System notice is intended for information outside the fiction, such as an author update, a content warning, or a note that more chapters are in development. It opens above the current conversation using the same card language as the developer note. Authors can edit its eyebrow, title, message, and button. After the player dismisses it, playback continues with the following block. Skip suppresses notices that have already been seen.

Media blocks

BlockPurposeSupported files
PhotoSend an image with an optional caption, Gallery unlock, and character tags.PNG, JPG, JPEG, WebP, animated GIF
VideoSend a video with an optional caption, Gallery unlock, character tags, and optional looping playback. Desktop Studio converts MP4 automatically.MP4, OGV
AudioSend an audio file with an optional caption.OGG, WAV, MP3
MomentBuild a closed full-screen sequence whose images or videos become the background while messages fade above them.PNG, JPG, JPEG, WebP, animated GIF, MP4, OGV

Media can be selected with the file picker or dragged onto the selected block. Studio copies imported files into the story's assets folder and manages their internal paths. The editable asset name remains readable in the source and UI. Each media inspector has an NSFW checkbox. Media is SFW by default; enable the checkbox only for NSFW content.

Desktop Studio accepts MP4 for Video blocks and video OverFaunt posts. It converts the selected file to Ogg Theora (.ogv) before storing it, so the authored source and published package never depend on MP4 playback. Conversion runs in the background and keeps the original MP4 filename as the readable asset name. OGV files continue to import directly without conversion.

Exported builds do not include FFmpeg. Web and mobile Studio accept OGV directly but do not offer MP4 conversion. On desktop, MP4 conversion is available only when FFmpeg is installed separately: Studio checks SUBTEXT_FFMPEG, the system PATH, and, for development from the Godot editor, tools/ffmpeg/<platform>/.

A Moment opens its own ordered timeline editor. Its first block must be an image or video. That media becomes both the invitation in Messages and the first visual. In both modes, the invitation displays a white tap icon above Open Moment over a dark bottom gradient, the story waits for the player to open it, and the same invitation can replay the Moment after completion. A Conversation Moment keeps the real SMS interface visible beneath the visual and delivers its timeline through Messages; a Live Moment replaces the phone with a full-screen VN presentation and keeps its timeline out of Messages.

Authoring a Moment

  1. Add a Moment from the Media group in a conversation or branch.
  2. Open Edit Moment timeline.
  3. Add a Photo or Video as the first block. Studio reports the Moment as incomplete until this opening visual exists.
  4. Add messages, background changes, and timing blocks in the order they should play.
  5. Return to the conversation editor when the sequence is complete. Studio creates the closing structure automatically; there is no End Moment card.

The Moment timeline supports only these blocks:

BlockUse
MessageConversation: deliver a standard SMS bubble, using the normal composer for player messages. Live: show one VN line and wait for a tap unless Auto is enabled.
PhotoReplace the current visual. It fades toward the phone UI in Conversation mode and fills the screen in Live mode. Enable Dynamic pan and zoom for a subtle looping camera movement.
VideoReplace the current visual and begin playback immediately. Enable Loop video to repeat it until another visual replaces it or the Moment ends.
DelayHold the current state for an exact duration.
Fake typingShow the normal typing indicator in a Conversation Moment, or add a silent pacing pause in a Live Moment.
ChoicePause for two to four player answers using the current mode's controls. Each answer can continue through its own Moment branch before returning to the timeline.
Cum effectPlay a smaller white flash followed by a full flash, retain the built-in texture for the configured duration, then fade it out.

Messages from other characters advance automatically after a reading pause based on their length. Use Delay when a line needs more breathing room or when dialogue must synchronize with a video, since videos do not stop the timeline. Media captions are not drawn over the visual itself; use a Message block when text must appear in the Live presentation.

During a Conversation Moment, the media is opaque across the upper screen and fades smoothly to full transparency toward the bottom. The real Messages interface remains visible beneath it: dialogue uses the standard SMS bubbles, incoming lines use the normal typing animation, player lines use the normal composer, and choices use the normal phone controls. As the conversation grows, earlier bubbles scroll upward behind the increasingly opaque media and disappear progressively. Messages, selected answers, and later nested media join the conversation history as they play.

During a Live Moment, the phone interface disappears completely. The media fills the screen and dialogue uses a classic visual-novel presentation: only the current line is visible at the bottom and each line waits for a tap. The Auto control at the top advances dialogue using the selected message-speed pacing; choices always require an explicit selection. The top-right visibility control hides or restores the VN dialogue and any pending action. Live dialogue and nested media stay out of Messages. Replaying either mode does not add duplicate history entries.

Moments can contain choices whose branches use the same Moment blocks (messages, photos, videos, timing, and Cum effects). Conditions, audio, state changes, and chapter actions remain outside Moments.

For Gallery media, People in this media controls the character filter. The sender is selected by default, but authors can remove that tag, leave the media untagged, or select several characters.

Branching and story state

BlockPurpose
Set valueStore a global story value such as restarted = true.
ConditionPlay an If or Else branch based on a story value.
MilestoneSet one named boolean milestone, scoped to this chapter or to all chapters.
End chapterShow an ending, optionally offer a chapter restart, set a value on restart, or continue to another chapter.

A choice answer can have its own nested messages and actions. It may also be visible only when a story value is true. Each answer chooses what happens afterward: continue after the choice, jump to another main block, or end the conversation.

A milestone has a unique name within its scope. Choose This chapter when the name belongs only to the current chapter and may be reused elsewhere, or All chapters when later chapters must see the same value. Milestone conditions use one picker that shows the scope and name; they do not ask for a conversation separately. Name a milestone after the state it represents, such as report_available, rather than an instruction such as open_report.

When developer mode starts a chapter directly, chapter milestones always start empty. The launch dialog only offers story values and All chapters milestones authored before the selected chapter. Anything first introduced in the selected chapter or a later chapter is excluded because it cannot be part of the selected chapter's inherited state.

Condition blocks use the same branch editor for their If and Else paths. Media inside choice and condition branches remains discoverable from the media library.

Phone app actions

BlockResult in the playable phone
OverFaunt postCreates a post with profile, text, optional photo/video, fake likes, and fake reposts. Photo and video posts can also be added to Gallery and tagged by character.
Nozamart itemUnlocks a gift with name, description, image, recipient, and an optional price when banking is enabled.
Bank transferAdds an incoming transaction immediately or presents an outgoing payment button in Messages.
GPS locationUnlocks a location with name, description, and image.

Use a later start, slice trigger, or wait condition to react to the player viewing a post, sending a gift, or visiting a location.

Choices and branches

A choice contains between two and four answers. For each answer Studio can:

  • edit the answer sent by the player;
  • add an optional score requirement using a story value, skill, affection score, or bank balance;
  • open a branch containing the same message and action blocks as a normal conversation;
  • duplicate the answer and its branch;
  • select the destination after the branch.

An empty branch simply sends the player's answer and continues. This is useful when several answers share the same following dialogue.

Score requirements do not hide answers. An unmet answer remains visible, appears faded and disabled, and shows the required comparison. If every answer is locked, the choice remains on screen until the relevant score changes or the player rewinds to make a different earlier decision.

Media & events library

The story-level Media & events screen inventories authored content from Preloaded content and across all conversations. The same screen is available inside each chapter with a chapter-only filter.

It currently groups:

  • conversation photos, videos, and audio;
  • OverFaunt posts;
  • Nozamart items.

Each card shows a preview, content type, sender when relevant, chapter, conversation, branch context, and source asset. Missing image assets use a black placeholder bearing the asset name.

From a card:

  • Edit opens the block settings directly in the library;
  • Go to conversation opens the source conversation, enters its choice or condition branch when necessary, selects the block, and scrolls to it. Preloaded-content entries instead return to the Preloaded content screen.

GPS locations are edited from their action block in the conversation editor; they are not currently grouped in the Media & events library.

Editable text workflow

Studio can copy and load readable Subtext source at three levels:

ScopeCopyLoad behavior
StoryEntire storyReplaces the currently open story structure.
ChapterChapter and its conversationsReplaces that chapter and its conversations.
ConversationOne conversationReplaces the current conversation while keeping its place in the chapter.

This makes it practical to edit in a text editor or ask an LLM to revise dialogue and structure. Studio validates imported text and reports syntax or reference problems before accepting it.

Text copy/import contains source only. It does not embed binary media. When replacing existing source, files already present in the story package stay in place and continue to work when their asset names remain referenced.

See Studio and LLM workflow for the recommended prompt and Command reference for the complete syntax.

Project transfer and playable versions

Export Project creates an editable .subtext-project bundle containing the current source and its media. Import Project on the Studio project list restores that authoring bundle. When the project has already has a playable version, the bundle also carries its recorded frozen release so moving the project to another device does not lose its version history.

Tools that generate these bundles outside Studio must follow the normative archive layout, manifest schema, asset allowlist, identity matching, validation order, and diagnostic contract documented under Editable .subtext-project transfer bundle. That section also includes a complete minimal source and a deterministic checklist intended for LLMs and other automated generators. A .subtext-project is a ZIP with root-level story.phone and .subtext-project.json; adding a wrapping directory is a common cause of rejected imports.

Create playable version opens a four-step assistant. It reports missing assets and validation problems, recommends a MINOR or MAJOR update while allowing a compatible higher choice, handles save compatibility when required, and finally creates an immutable version. No destination is requested at this point. The result screen can launch the Story directly in the app or export its read-only .subtext package for sharing.

Use Test draft in the app before creating that version to play the current editable content without freezing or publishing it. Draft previews use a separate save slot, so they do not replace normal player progress; reopening a preview offers Continue or Restart. The same action is available from the final review step of the playable-version assistant.

For an editable project, the first playable version is v1.0 and freezes an internal .published/v1.0.subtext artifact. If the content has not changed, exporting again copies the exact bytes of the current frozen revision without incrementing it. Every changed release receives a new immutable MAJOR.MINOR revision:

  • presentation, dialogue, image, audio, metadata, or other non-structural changes increment MINOR, such as v1.0 to v1.1;
  • inserting, removing, or rerouting story structure increments MAJOR and resets MINOR, such as v1.3 to v2.0.

For a MAJOR release, Studio also offers Breaking update. This explicitly publishes the next MAJOR without running a migration. The compatibility step becomes a reset confirmation, and players whose save predates that version restart the Story from the beginning. Saves created on the breaking version or a later revision are not reset again.

Studio determines this automatically from the frozen structural and persistent-state contracts. A playable revision is never rewritten in place, including a small MINOR update.

Published media paths are content-addressed. Replacing assets/photo.png therefore gives the new bytes a new internal assets/_published/<sha256>.<ext> path, while later releases retain the old path and bytes for message, Gallery, and phone-app snapshots already stored in player progress. A release also carries migrations.phone as authored when present. Migration operations shipped in an earlier frozen release cannot be changed or removed later. A next-MAJOR step that has not appeared in any frozen release may still be discarded.

After v1.0, save compatibility is handled inside step 3 of Create playable version. The editor targets the next MAJOR boundary: any v1.x release prepares 1 -> 2, any v2.x release prepares 2 -> 3, and so on. It loads the existing file or starts that template, checks its syntax and story id, and saves it atomically; this works for editable Projects and developer-edited Originals.

Before advancing a revision, Studio compares the previously recorded structure and public compatibility contract with the candidate. Any structure or routing change creates the next MAJOR release. A purely structural change may publish without a migration because the runtime can restart only the active incomplete chapter from its checkpoint. Removing or renaming a persisted story value, global milestone, ending, chapter, or phone-content key additionally requires the sequential MAJOR migration, for example @migration 1 -> 2. Including a previously drafted next chapter is structurally a new MAJOR release, but adding the route to that new chapter does not itself require a migration: players who had reached the old ending are reopened onto the new chapter after installing the update.

Presentation edits—text, images, names, covers, and similar display changes—still create a new immutable MINOR revision, but they do not restart play. Previously saved history keeps its original text and content-addressed media. Inserting, removing, or rerouting blocks changes the chapter's structural fingerprint; only an incomplete chapter currently in progress restarts from its saved chapter-start checkpoint. Completed chapters, their history, and previously reached global state remain intact. Keep the story id, published chapter ids, story-value names, global milestone names, ending keys, and persistent post/shop/location keys stable. Use a migration when one of those saved-state keys must change. Ordinary generated message/block ids are structural rather than permanent save-schema keys.

Studio records the frozen artifact's size and content hash and refuses to publish or export it if that artifact changed afterward. The editable project may continue evolving independently between releases. This SHA-256 check provides local integrity and same-revision consistency, not a publisher signature, authenticity guarantee, or DRM.

When a player installs an update, the app keeps the previous installed release until saved progress has been migrated and written successfully. A failed migration restores that previous release instead of leaving the story half-updated. A small durable update journal lets the next Play Stories load finish or roll back the same story-id/version transaction if the app stopped during the swap. Studio likewise writes and validates story sources, manifests, and release archives through temporary files before replacing the previous complete file.

The release filter excludes:

  • chapters marked as drafts;
  • conversations belonging only to those chapters;
  • assets referenced only by excluded content.

Published packages contain data and media only and cannot execute GDScript. Install a published .subtext file only with Import Story in Play Stories > Community; it enters the read-only Community library and cannot be opened as a Studio project.

Keep the .subtext-project bundle as the editable authoring copy or backup. Distribute the immutable .subtext release to players.

Developer mode and original stories

In Settings, tap the version label five times within 2.5 seconds and enter the default password subtext-dev. Developer mode persists locally and provides additional playtesting tools.

Outside Studio, those tools can unlock every conversation in the current chapter or restart the active story. Skip may accelerate unseen content. The Journal reveals every chapter and adds Play, which starts a selected chapter from a clean story state after prompting for its global story values.

When developer mode is active and the project runs from the Godot editor, Studio becomes the internal original-story authoring tool. Original stories can then be opened and saved directly under res://stories/stories/<package>/. In exported builds, originals remain read-only even when developer mode is enabled. Developer publication uses the same internal manifest and .published/vMAJOR.MINOR.subtext freeze as a normal Project, but Originals do not expose Project import/export actions. Creating the version also atomically refreshes _published/runtime.subtext: gameplay reads this pinned release rather than the live story.phone draft. An exported build ignores any Original without this pin, so create a playable version for every Original at least once before shipping; later draft edits cannot enter gameplay until the next successful playable-version creation.

Original availability is configured in Godot through an OriginalStorySettings resource in res://stories/originals/:

SettingEffect
story_filePoints to the original story.phone source.
display_orderOrders originals; lower values appear first.
playable_in_gameShows or hides the story in player-facing story selection.
can_duplicateAllows Studio users to create an editable Project copy.

These controls intentionally live outside story text so an imported Project cannot change official-story availability.

Current constraints

  • Studio is an early preview and the format may still change.
  • Original stories are never directly editable by players.
  • Clipboard text does not carry media files.
  • Animated GIF avatars are kept uncropped so their animation is preserved.
  • Published videos use Ogg Theora (.ogv). Exported builds do not bundle an MP4 converter; web and mobile authoring require OGV input, while desktop builds can use a separately installed FFmpeg.
  • Choices contain two to four answers.
  • The Media & events overview currently indexes Preloaded content, conversation media, OverFaunt posts, and Nozamart items; other phone actions remain editable from their source screen.
  • Go to conversation handles the current choice or condition branch; media nested several branch levels deep may still require manual navigation.
  • Story packages cannot run scripts.