CYOA Viewer is a tiny (4Kb) and extremely lightweight webapp which I developed for sake of viewing CYOAs (as should be evident from the name). The reason I made it is because, frankly speaking, most websites used for hosting CYOA images aren't exactly providing the most convenient fullscreen mode for viewing large images that are the traditional format for CYOAs; and the browser itself, in the single-image mode, isn't well-suited for that purpose either (aside from the fact that I have to open several tabs to view one CYOA, just the fact that an accidental click would reset my zoom level is already highly annoying). And even the downloaded CYOAs can't be easily viewed in a way that would be convenient for a CYOA… In the end, I got tired of all that crap and made A Thing That Works For Me.
It had been lying around on my hard drive for a couple years until I noticed that lately, a lot of large CYOAs started appearing, and since I loathe gaming with spreadsheets, I decided it was time to make a "playable" version of the Viewer. I actually had a project for making a proper CYOA editor (for taking an arbitrary CYOA and producing an interactive overlay, with rulesets, alternative costs, and calculated options), but after implementing a proof-of-concept I realized it'd take the kind of time and effort which I don't really have (as I have a day job, and I'm too lazy to be bothered with a lot of effort at once in my spare time); so in the end I decided to do a "makeshift" interactive version which would let me start playing any CYOA hosted (almost) anywhere immediately, without having to download it or spend time on creating/waiting for someone to create a proper interactive version. Naturally, soon after I decided to also implement an import/export feature that would (aside from regular save/load functionality) allow to have a "base" state which would simulate a proper interactive CYOA (meaning, user won't have to select every card he wants to use by dragging rectangles on the screen every time he opens the CYOA), even if proper interactive CYOA rulesets are entirely out of scope for this one. Several more neat features (at least from my own perspective) followed after, but the focus stayed on keeping the app minimal and easy on resources (as the browsers do like to eat up RAM on prolonged usage), even if the resulting v2 HTML file (yes, being single-file and easily downloadable and usable from any location is one of its features) has grown to a couple dozen times of v1 (123Kb, thirty times larger as of now).
CYOA Viewer was developed mostly for my own personal usage, but since I put this much effort into making an advanced version, I figured – why not share it? I even added a few features which I didn't care much for originally to make it more accessible (for instance, whole-CYOA-config-in-one-URL, and allowing to view – as well as play, to some extent, – CYOAs in mobile browsers).
View mode, also existing separately as the smaller (and lighter!) v1 version; fullscreen-oriented, designed for displaying CYOA images in full-page width, as well as browsing them continuously.
Play mode: the only actual difference between v1 and View mode of v2 (aside from features that depend on v2 data) is existence of the "play" button in the latter; clicking it will allow you to enter the Play mode, which will display a navigation panel for the interactive Play mode.
Overview mode: after you've finished picking your cards, you may want to switch to the Overview
mode (from the toolbar), which will let you browse your enabled cards in fullscreen mode (including flavour-text
cards if they exist), as well as do the finishing touches to your playthrough (change card comments, attachments, and
Ze Plan), and overview the text of your build.
Both cards list and build view have multiple toggleable options (like changing card size limit between thin,
width/height fit, and 100% size, or regrouping cards in build by category and counting points).
Unless you somehow managed to miss it, this manual is external to both v1 and v2 versions of the app, and is hosted (along with a few other things) together with it, mainly providing users with a few helpful bits of functionality. Most of these have additional information included.
presets/{title}.json
.presets.json
entry, or fill
the form of URL generator for further editing (URL data can be re-scanned from a v1 page by parsing its URL query);
all commands available via userscript manager menu.
View mode (including v1) is geared towards maximizing viewing area; the fullscreen toggle button allows to hide the
annoying address bar on a touchscreen device (though this changes UI size).
For further viewing convenience, images are scaled down to fit screen width; you can increase their size using browser
zoom level (I prefer 120% zoom for CYOA viewing), and/or increase width limit using "page width limit" dropdown (visible
on hover).
View mode in v2 only differs in that it has access to v2 state data, including page names (in navigation dropdown and in
tooltips) and toggleable censor boxes (which can be used to hide, for example, visual gay content if you don't like
seeing it mixed in with straight content).
By clicking "play", a panel will open; the default view in it is CYOA tab. In Play mode it includes global stats counter
as well as overall CYOA/build comment input; and in the view area, when a card is selected, toggleable overlays
containing its meta info and cost/stats counters (single card cost, bonus for multi-selectable cards, and total cost for
picked cards) are shown. Since cards can be bought/discarded in the viewing area, this minimizes the need to switch
between tabs (as adding comments and attachments can be done in Overview mode after buying all the cards first, in
general case).
Switching to the cards tab will display cards list (grouped by pages), with a toggleable category filter at the top
(right or middle click on a category counter, excluding flavour text, will open a random card from that category).
Hovering a card title in the list will highlight the card in viewing area, and vice versa (in the latter case the card
title is scrolled into view). Picked cards are also marked in the list.
Selecting a card with cards tab open will display its details within the panel; including card preview (double-click on
which scrolls the viewing area to display the card), meta/cost info, and inputs to enable/disable the card (or select
amount if applicable), add a comment or attach an image URL.
Clicking the button on the side of the panel, you can hide it (or show again), thus giving you wider viewing area again.
In this "fullscreen view", the overlays (in expanded or collapsed state) are displayed permanently, with them containing
CYOA information (meta/stats) when there's no card selected. (Also, CYOA information is transparent when not hovered.)
As you can tell from the screenshot, these stats may include things other than points that you may want to keep track
of.
After you've finished picking all the cards, you can open Overview mode, where all the cards you've picked are displayed
(as well as flavour text cards) with subcards grouped under the parent card. There's several display options, as well as
category filter similar to the one in Play mode (except the counters are for top-level enabled cards only).
Here's the same tab of Overview mode with different display options (cards are displayed in rows instead of columns,
these rows are limited in size to the panel width, and attachment images are displayed before the card itself.)
The final step of the playing process, build tab of Overview mode. It displays the same stuff as CYOA tab of Play mode,
except CYOA title is replaced with an input for build title; and to the right of it, there's a generated build page,
which can be either downloaded (as plain HTML with a wee tad of CSS), or selected and copied in whatever way your
browser/OS does so for portions of webpages (if it's copied as plain text, attached images are replaced with URLs).
Since CYOA Viewer doesn't support rulesets, Edit mode can be switched into at any moment (and of course, you'll be using
it if you're creating/updating a base state, or playing a CYOA without a base state). In the CYOA tab, it allows to edit
CYOA meta, stats (point sets and their initial values) and page titles. CYOA title can be changed from the view controls
(except it changes the URL and storage key, so it's best to change it before doing any editing/playing).
The cards list in Edit mode can be reordered (within page), and categories can be renamed (or removed if empty).
Selected card in Edit mode can be moved or resized (with mouse or via geometry inputs – the latter allowing for finer
adjustment, as well as quick repositioning of copied cards). And, of course, card data can be edited, with card cost
split into individual cost and category cost (the latter being equal for all cards within the category).
Aside from copying existing cards with the
+
button (when there's no cards on page, a small card in top-left corner is
created), you can add new cards by simply selecting the area on CYOA page.
Storage manager allows to review and remove old CYOA states from browser storage. Hovering on a CYOA title shows its URL
parameters (which double as storage key).
The index page includes an URL generator form as well as a list of presets (fetched as a separate file) with page URLs
and preset URL (relative to v2 location), as well as a short comment if I have anything to say about the CYOA.
Gallery scraper is an userscript that allows to collect and operate Imgur/ImageChest galleries (to get an URL or preset
data). Make sure to load all pages first (it says how many URLs were collected).
Those who create base states can use the state analyzer userscript; its primary function is to display the current state
of the CYOA (as well as what faults were detected).
If you don't like the default colour scheme, feel free to alter it with an userstyle; here's what the example userstyle
looks like.
Links:
The main purpose of CYOA Viewer (and the sole function of v1) is viewing CYOAs, which are typically made as series of
wide (around screen width) and long (up to 1000px or so) images; thus, the Viewer is geared towards providing the
optimal viewing area for such images and displaying them as a single sequence. (The background is normally grey but is
switched to black when using fullscreen feature.)
The only UI element aside from the viewing area itself in v1 is the controls panel in top-left corner. It's normally
highly transparent (to prevent it from getting in the way too much).
By hovering it with mouse cursor (in case of touchscreen, tapping on the panel makes it "hovered") or focusing on one of
its elements will both make it less transparent and show extra elements (in v1 that's the zoom dropdown).
As v2 has access to state data, the controls panel in it also has a censoring checkbox (when there's censor-boxes in the
state), and page titles in the pagelist dropdown (in addition to their numbers).
These controls are, from left to right:
The main purpose of the title input is changing the webpage title, so that user can easily distinguish browser tabs with
multiple CYOA Viewer instances open (also, the play/edit panel is blocked with no title).
Take note that title (as well as the URL) resets when opening a new CYOA.
Pagelist dropdown shows which page is currently displayed (if there's multiple, it's picked by direction of last
scroll). Selecting another page will scroll viewing area to that page (in most browsers this means the top of the page).
The dropdown isn't displayed when there's only one page.
Normally, page width is limited to the width of viewing area, as it's usually inconvenient to scroll the page
horizontally and vertically all the time; but if the CYOA pages are noticeably wider than the viewing area, it's
possible to increase the maximum width. (This is a fixed set of values, but they should be enough for most cases.)
Note that if you want the pages to be displayed larger than their full size, you'll need to use browser zoom (which
also affects webapp UI):
Also, when in View mode, you can open a remote single-page CYOA by dragging its image into the page from another browser tab (I'm not aware of any way to drag multiple images like this). You can also drag image files from your local drive, which does exactly the same thing as when opening these images with the "open" button.
Whether you're playing a complex CYOA with alternative card costs, or creating your own base state, or simply trying to
play a CYOA without having a pre-existing base state, you're going to work in the Edit mode at least sometimes. It can
be switched on at any time from Play mode toolbar (the "edit" button).
Note that you don't need a base state to play a CYOA; just, if you don't have one, you'll have to select the cards
you pick manually instead of using pre-made ones.
Global parameters can be set in the CYOA tab of the Edit mode.
At the top, you'll see the standard toolbar and the CYOA title (which can be changed in the view controls).
The toolbar buttons are:
Take note that your state is stored locally based on the URL parameters and the title (as a precaution, it doesn't get
stored with an empty title), so that you don't lose all of your changes if you accidentally close or reload the page. If
you change the title when there's some existing state already, that state will become unsynced from the storage; to
sync it again, you can either change any value in it (which will overwrite stored state for the current URL), or
replace current state with the stored one by pressing "load" button which appears in place of "reset" button (it's
disabled when the URL doesn't have any stored data).
If there's no current state (e.g. you chose to clear all state and reopened the panel) and no stored data to load,
"reset" button will be replaced with "storage" button, which opens storage manager dialog. In case of empty title, it
will be always displayed, along with most of the panel blocked.
The "import" button is available in this case because during export the CYOA name is included in exported data, and
it's used to override an empty title when importing. Thus, the fastest way to load a CYOA stored on your hard drive
would be to open its pages, and then import its state (if you only have it in browser storage, you'll have to load it
instead by setting the correct title first – or by copypasting it from storage manager).
As you might have noticed, the CYOA title displayed in the panel has the word "CYOA" added into it.
The exact rules are quite straightforward, so you won't have trouble choosing the title for your preset/base state.
vX
, where X
stands for any digit), "CYOA" is added before
it: "Keeper of Magic CYOA v2
.3" #X
, where X
stands for any digit; these are for unrelated CYOAs
with the same exact title), "CYOA" is added before it: "Guardian spirit CYOA #2
" [
), "CYOA" is added before it:
"Branching heart CYOA [
full version]" v1
.5 [
all DLCs]"
The meta textbox contains global information about the CYOA, or recommendations on how to play it (with regards to
engine limitations, or the current base state in particular). When such information is related to a specific part of the
CYOA (card or section), it should be placed there instead.
The points (stats) can be freely added, removed (confirmation dialog will say how many cards are using them), renamed
(they have internal identifiers, so cards data won't be affected – though empty names aren't valid and will be replaced
with the word "points"), and have their initial amounts set to any value (initial value is displayed separately in stats
list). They also have a fixed order (both in stats list and in card edit view) which can be changed here. Point values
are always integers (whole numbers).
Page titles can be set here. This makes navigating large CYOAs less confusing as you have at least some idea where you
are. (Not displayed when there's only one page.)
Clicking on a page number will scroll viewing area to that page.
Separate cards data can be edited in the cards tab.
At the top of the tab, there's a dropdown with two +
/−
buttons on its sides. The dropdown can be used to select
cards (it's always displayed and contains all cards in Edit mode); the buttons can be used to add a new card or delete
the selected card (with confirmation).
When a card is selected,
+
creates its exact copy and places it as the next card on the list. When no card is
selected, the last card on the current page is copied and placed in the beginning of the list. When there's no cards on
the current page, a small area in top-left corner is selected.
It's also possible to create a card by selecting a rectangle area with the mouse in viewing area (when no card is
active). In this case, the card data will be copied from the last card of the page, and it's placed as the last card.
(Selecting is done by either dragging position or clicking on unoccupied part of the page and then on the other corner
of desired area.)
When a card is selected, the next thing under the cards dropdown is the card preview along with its geometry parameters:
position and size of the card (counting from the top-left corner of the page), in percents of the page size (so that a
base state can be applied to rescaled pages of the same CYOA without change). That is, the number inputs are: x,
width, y, height. The next line shows the x and y ranges covered by the card (which helps when adjusting cards
to fit together, or ensuring that all subcards are entirely within the parent card). Minimum step is 0.05%, minimum
width/height is 0.25% (this also applies to new cards; if the selected area is too small, it's highlighted in red).
(When a new card is created using
+
on an empty page, its x
and y
are 0%, and size is 5%×5%.)
Additionally, you can drag the card or its borders in the viewing area to move or resize a card.
When a card is selected and the viewing area is focused, you can delete the card by pressing Delete (allowing it in panel would cause problems when editing text). To deselect a card, click outside of any cards within the viewing area (or press Escape). Clicking a different card within viewing area will select it (in Edit mode, this will also switch the view from CYOA tab to cards tab). Also, double-click on the card preview will scroll the viewing area to the position of the card.
After the card preview follows the card title, which consists of two parts: category and name. Categories are card
groups which can be considered being of the same type. They can be filtered out as a whole, and they may share the same
cost (which can be edited for the category as a whole, and then some cards can have their individual cost adjusted
separately). However, categories don't actually exist in CYOA Viewer: they're generated from the set of category
values from all cards in real time; thus, in the card data editor, it's a free-text input.
As for the name, it should be unique for all cards within the category (Or, more specifically, the title should be
unique). This is due to the fact that some choices can consist of multiple cards, and in Play mode they're all treated
as one card (more on that later). If two cards have the same title according to the CYOA naming, clarify which one it is
in parentheses.
Incidentally, to create a multipart card, you create one main card normally with the part that you consider to be the
primary one, and then create rest of these parts as secondary, by adding
#X
at the end of card name (where X
is a number). If you do it correctly, you'll see the rest of the card parameters replaced with its main card data:
(If you need a regular card name ending with
#
and a number, just add a whitespace at the end.)
The title is normally generated very straightforwardly: {category}: {name}
. However, sometimes it's more convenient to
split cards within the same general type into subcategories; in this case, you can add colon (:
) into the card
category (before subcategory name) – this will change the title pattern to {category} ({name})
. (Alternatively, you
can wrap subcategory name into parentheses instead, which will use default title pattern – e.g. Harem (Red): She-Ra
.)
Additionally, secondary cards have a
*
prepended to their title.
A card can have an empty category. In this case it's considered a flavour text card (its title is displayed without category, and in italics). Flavour cards can't be selected, but they can be seen in Overview mode, and they can have meta information added to them. They (as well as regular cards) can have subcards ("suboptions" that are shown as part of the card in Overview mode; they need to fit entirely within their parent card – check their geometry ranges to ensure that).
For the flavour cards, the next option is the censor box checkbox. Setting it will turn the card into a censor-box, with
its name replaced with
[censored]
(and name input disabled); in the viewing area it's highlighted with red border. (In
other modes it's displayed as an opaque black rectangle, not listed as a card and can't be interacted with, other than
hiding all censor boxes by toggling off censoring.)
The next field is meta textbox; it's available for all cards (except for censor boxes), and has the same purpose as the
global meta information.
The multiple checkbox defines whether the card can be picked multiple times.
Finally, there's three groups of cost fields; for each, you can pick any of the existing points (stats), and set by how
much the value changes if you pick the option.
The differences are following:
{bonus} + 3*({category cost}+{cost})
.)
The fields copied when creating a new card are:
When no card is selected, the first thing under the cards dropdown is a toggleable categories filter. It also shows card
counters for each of the categories, and category cost in tooltips (where it exists). If a category has a cost but no
cards (most likely a leftover category after some reorganization), it's displayed with the counter replaced with removal
button instead (with exception of flavour cards).
A category (except for flavour cards) can be renamed by using right or middle click on its name; this will change the
category value of all cards that had this category, as well as for stored category cost (if there is already a category
cost assigned to that name, the old cost will be discarded; be careful when merging categories).
In the flavour text category, censor-boxes are displayed separately (as a second number).
Lastly, under categories, there's the cards list, grouped by page. Clicking on the page title within it will scroll the
viewing area to that page; similarly, scrolling the viewing area to a new page will scroll the cards list to the
respective section. Hovering a card title in the list will highlight it in the viewing area (if visible); hovering a
card in the viewing area will highlight it in the cards list (and bring into view). Hovering either will also generate a
tooltip with card meta and costs in it. After deselecting a card, it will be scrolled into view again (more
specifically, the scroll position will be moved to that of the current page section, with adjusting it so that the card
title is brought into view).
The card titles can be reordered within their page section by dragging the ⇅ handle. To avoid having to stop dragging and scroll separately, there's thin areas on top and bottom of the list, hovering which starts gradual scrolling (but card titles can't be clicked through them). Card order determines in what order they're displayed in all lists (including the build view), as well as rendering order in the viewing area (the ones rendered later are on top of the ones rendered first, and will be selected if you click in that place). The only exception is that in Edit mode, the selected card is always rendered on top of others.
This section contains a few words of advice for those who want to create a base state for some CYOA. Feel free to ignore it, though I do believe it would be at least somewhat helpful.
The most important part to remember is that the engine is limited in what can be done with it – there's no implemented
way to add arbitrary rules and rule changes like those you can find in many CYOAs, so you'll need to keep a flexible
mind with it; in some cases, you can leave it for the player to follow the CYOA rules (it's not like you can force him
either way); in others, you can simulate the rule with some additional stats and a few words in the card meta. If you
find it difficult to adequately support different sets of rules within the same CYOA, you can create several separate
base states (make sure they have different titles, i.e. Some title [special rules]
); for the main base state, however,
try to make the most variations possible within it (at least for the "default rules" kind of build).
Stats, by the way, aren't just currency counters – they're meant to keep track of whatever the player might need to (or
have trouble) keep counting in his head; for instance, if there's a number of choice combinations that unlock other
cards, you can add some point sets for these combinations.
Stats are always integer, so if the CYOA has fractional costs, you may want to rebase them to an integer base (dividing
all the costs by their least common multiple, which should raise them to integers). Come to think of it, you may want to
do that if the author made all prices divisible by the same integer larger than 1, too (e.g. the lowest cost of an
option is 25 or 500 points). In either case such cost values are pointless and serve no purpose other than complicating
calculations for the player, anyway.
A good convention for page titles is a short (1-3 items) list of comma-separated sections that the page includes, with
multi-page sections numbered. (You also can just mark where the section starts, but that may leave some pages without a
title, which kinda defeats the purpose.)
Try to not get them titles too long, they affect the size of the relevant UI (like the pagelist dropdown).
When adding new cards, the most likely fields to contain the same information are copied (either from current card or
from the last one): size, category and cost. This speeds up the process of creating cards for all choices, especially if
the CYOA was generated from a template (in which case the cards may have the same size or at least the same width within
the row). Combined with the fact that a copied card is inserted into the list after the original card (with one
exception which you're least likely to use), it means that the fastest strategy to create cards (within one section at
least) is to make the top-left one, then fill the leftmost column by successively copying these cards, and then going
back to the top of the page and making more copies of each card to fill the rest of their rows. When you do this, it's
more convenient to use geometry inputs to move the copied cards (rather than dragging them or their borders); you can
also use keyboard (up/down keys, or mousewheel on the field when they don't work) to gradually change them, as well as
copy-paste either numbers from geometry range of original card (right/bottom-most coordinate of original card is a
better starting point to start moving its copy than its original position), or positions of other cards (i.e. if the
cards are arranged in columns, you can simply copy the x position of the topmost card, and fill other rows by copying
a card from previous column and replacing x position of the copy – which takes two clicks and one keystroke). In large
CYOAs you can usually also reuse sizes/positions of cards from another page – most often the previous one (there's even
a REPL command for copying the whole page, if you know how to use browser console). And in cases of
same-template CYOAs (e.g. Kyapitallisym selection series) you can just import a state from another one and edit it (or,
you can make a copy with removed card names/metas to ensure you don't miss any).
In case of subcards, they're less likely to coincide in sizes; and if they do, you can simply drag the title to
appropriate position in the list after copying a subcard. Also, make sure that subcards are after their main card in the
list (though it should be obvious logically), as they won't be clickable otherwise (since they'd be rendered
underneath their parent card in that case).
CYOA Viewer isn't really tied to the website I'm hosting it on. It's a standalone webapp which can be used whenever and
however you like; that, of course, includes remotely hosted base states.
Here
(or here),
for example, is an URL that opens a CYOA in the initial release version of v2, hosted on a free HTML hosting site here (the HTML paste died by now), with
CYOA pages hosted on the original gallery website (which allows showing pages remotely but not downloading them), and
with base state hosted on a free code/JSON hosting website. The only requirement for hosting base states is that they
should be downloadable by a webapp (i.e. CORS requests must be allowed); here's a few options:
From View mode, you can enter Play mode by using the "play" button in top-right corner.
It's the mode that you're going to spend most time in (if you're here to play CYOAs). Still, in some cases you may need
to switch to Edit mode for a bit, to adjust card data according to the rule changes caused by your choices (e.g., allow
a card to be selected multiple times, or change its cost). You probably won't need to do stuff like adding new cards
though (…but you still can if you want to).
Censoring checkbox from view controls affects card previews as well.
Also, saving/loading CYOA state (export/import) is discussed in Edit mode section. That includes recommendations for opening CYOAs from hard drive.
Similar to Edit mode, the top of the play panel is taken by toolbar.
They're mostly the same, except instead of "play" button, mode switchers include "edit" and "overview" buttons for
respective modes.
When you open Play mode, the first view you're going to see is the CYOA tab. It contains CYOA title, meta information
(most likely instructions on how to play or a general commentary), stats list, and the plan textbox (entitled "Ze Plan")
with a word counter (since some CYOAs have conditions based on essay length). A "word" in this context is defined as "a
space-limited sequence of characters that includes at least one letter or digit" (considering numbers as words); thus,
foo bar-baz + 42!
counts as three words (foo
, bar-baz
, 42!
).
Stats are displayed as a sum of up to three numbers: initial value, total amount added, total amount subtracted (with zeroes omitted). It there's more than one, their sum is displayed afterwards; if there's none, the stat is omitted.
You can navigate the viewing area with the CYOA tab open, same way as you'd do it in View mode. Unlike View mode,
however, you can hover cards to see their meta/cost info, and select them to have this info displayed in overlays.
In top-right corner you'll find the info overlay, containing card title and meta information. It can be collapsed to
stop it from covering part of the screen.
In bottom-left corner, you'll find the stats overlay, which includes cost info for the selected card. (Category cost is
merged into individual card cost in Play mode.)
It can be collapsed as well. (Both overlays are highly transparent when collapsed, unless hovered.)
You can pick a card by clicking
+
/−
next to it. You can deselect a card by clicking outside in the viewing area.
Alternatively, you can switch from CYOA tab to cards tab; in which case, you'll see a list of cards (basically the same
as in Edit mode, albeit without reordering support). The card titles include selection information, and on hover you'll
see the same information as when hovering a card in viewing area.
Note that in Play mode, secondary cards and censor-boxes aren't in the list.
Above the cards list, you'll find a toggleable categories filter. Unlike in Edit mode, it doesn't allow renaming or
removing categories, and the counters don't include secondary cards or censor-boxes.
Also, right or middle click on a category counter (except for flavour text) will open a random card from that category.
On the top of the panel, there's the cards dropdown with ←/→ buttons on its sides. They can be used to move up/down the
dropdown list without opening it (it's not affected by categories filter).
When a card is selected, the cards tab displays its information. It begins with card preview, which includes previews of
all its secondary cards as well (clicking on a secondary card will select the main card), in the order within Edit mode.
Double-clicking any of them will scroll the card into view in the viewing area. (The rest is card play data.)
In viewing area, the
+
/−
buttons are displayed next to the main card. If there are some secondary cards on another
page, the first of them will be considered "main" for this purpose.
Yet another alternative is to hide the panel altogether, going into "fullscreen view" (referring to the viewing area
taking up the whole page). In this mode, info/stats overlays are always shown (though still can be collapsed), with the
CYOA data (title, meta, stats) being displayed when there's no card selected (these are transparent unless hovered).
As mentioned in previous section, there's two places where you can access play data, and three approaches to the playing process; namely:
A selected card can be picked from the viewing area using
+
/−
buttons next to it (usually on top, except when it's
too close to the page top, then it's at the bottom of the card). Naturally, buttons that don't apply aren't displayed
(i.e. −
can't be used when the card is disabled, +
can't be used when a single-use card is enabled, and flavour text
cards can't be picked at all).
Picked cards are highlighted with green background; picked multi-use cards have their amount displayed in top-right
corner (of the main card).
Under the card previews, card meta information is displayed. It can be instructions on how to handle this card in the
Viewer, or maybe just some commentary.
A single-pick card will then have the "chosen" checkbox (that enables/disables it), and the cost (stats change) of
picking it.
A multi-pick card will have the amount number input instead, and cost per each pick (as well as bonus that's applied
once) displayed.
In either case, for enabled cards, total amount and cost (stats change) is displayed as well.
You can add a comment to a picked card (well, you can add it to any card, it just won't end up in the build).
Lastly, you can add some remotely hosted images to the card (there's no place to store image pixel data in the
storage, so URLs it is). Add them with
+
, remove them with −
(or double-click). If an image failed to load, the URL
is displayed as alt text (it's also displayed as text while the image isn't loaded yet, but in black font).
Basically, you can supply your own "this is what I/my house/my waifu/{this option} will look like".
After you've finished making your choices, you might want to look through your choices (e.g. "for aesthetical reasons"),
or to finish your build. Both options are available in the Overview mode, accessible from Play mode toolbar.
When switching to it, the panel will expand to full-screen width, maximizing the area available for overviewing.
When you open Overview mode, the first view you'll see will be the cards tab.
Here, all selected top-level cards (including flavour-text cards) are displayed grouped by their page; for each card,
its play info is displayed, with ability to edit comments and add/remove attachments (if you didn't do that in Play
mode), which is followed by its subcards, and their overall (i.e. taken together) stats total, all arranged in columns.
The subcards that weren't picked are censored out in their parent cards (so that only picked parts are visible).
The toolbar here contains the CYOA title, and a number of display options.
Take note that regular censor-boxes follow the same rules as in Play mode (so if you don't want to see them, toggle off censoring before opening Overview mode).
If you want to save the build as an external file, or copy it as a text, you can do that after switching to the build
tab.
More or less all the play data is displayed here (on the right side of the screen). This also includes play data from
flavour text cards, when present (i.e. comments/attachments).
On the left side of the screen, you'll see CYOA details panel; the only difference from CYOA tab in Play mode is that
instead of the title (which is displayed in toolbar anyway), there's a build name input (which affects the build name
in panel and downloaded filename).
The toolbar display options in build tab are for the build panel.
In addition to these options, toolbar includes a copy button (selects the build panel contents and copies them into
system buffer), and a download button (which produces an HTML file with the same contents as in the build panel).
These are utilities external to the main functionality of CYOA Viewer – you probably won't need to use them if you're just here to view/play existing CYOAs. (Except if you hit your browser's storage limit, then you'll need to either clear it via browser settings or use storage manager.)
Unless you make sure to clean up the CYOA data after you're done with them ("Reset all data"), after playing/editing multiple large CYOAs you're likely to hit the storage size limit (most likely the amount of space you have available is fixed and equals 5Mb); at that point, CYOA Viewer will offer you to open the storage manager. Alternatively, you can open it using the storage button:
The storage manager dialog looks like this:
The CYOA titles in the list are ordered by amount of space they're taking up in storage. Aside from removing them, those that don't belong to a local file (i.e. fetched pages from a query) provide a link to quickly open them with; also, the list entries have their storage key (URI) as a tooltip.
The index page of CYOA Viewer hosting site; it includes a toggleable readme section (this file), links to v1/v2, and a form with URL parameters – filling those will add the parameters to those links. (Note that the "standalone" part refers to CYOA Viewer itself, page and state files remain external to it.)
"Title" is the CYOA title (displayed in the browser tab, etc.); it's taken from URL hash (part starting from #
).
"URLs" is the list of page URLs, separated by commas (,
) and newlines (linebreaks) – note that whitespaces (
) as
well as other characters are treated as parts of URLs; these are used as query parameter url
(multiple URLs are
provided via multiple &url=
). Note that URLs may contain characters that aren't supposed to be in a URL query
parameter (which means these should be URL-encoded, rather than making a resulting URL by hand); this is, in fact, the
reason why this URL generator was made.
For sake of convenience, I also added a URL counter into the field label (hidden when there's no URLs in the field).
"Prefix" is the shared prefix of all page URLs (which will be prepended to all page URLs in the list when loading);
this one is used as query parameter prefix
. Its sole purpose is shortening the resulting CYOA URL, and it's neither
required nor needed unless you actually want to make the resulting URL shorter.
It has no meaning without at least one url
parameter (and no point in using it unless there's at least two), and
will be omitted if no page URLs are provided.
"Base state" is the URL of the JSON file containing startup/reset state for v2; this one is used as query parameter
state
.
It's not used by v1 and thus omitted in its URL.
"Presets" is a dropdown containing pre-existing URL configurations (added manually by me); just select any of them to
replace contents of the generator fields with the data for new ones (and generate v1/v2 URLs). In case of state
it
will provide links relative to the location of v2.html.
This dropdown is filled with data from presets.json file, which due to a limitation imposed by the browser means
that this element won't work if you open the page as a regular file from hard drive.
You don't have to use URL generator if all you want is to browse new CYOAs in the Viewer instead of Imgur; you can simply use the gallery scraper (see below) or drag&drop single-image CYOAs. Though, it's still helpful for other cases.
Also note that places like Google Drive don't support direct external links to image files (they may work for a few minutes but then the site will reject the link because access identifier is too old, for example).
If you want to host your own index and couldn't figure out exact format of presets.json
, it goes like this:
{ "{group}": { "{title}": preset, ... }, ... }where
preset
has following fields:prefix
– a string (e.g. "https://i.imgur.com/"
);url
– a list of strings (e.g. ["eq30RpM.jpg", "3AlMdIU.jpg"]
);state
– a URL string (defaults to "presets/{title}.json"
);comment
– a string with arbitrary text.url
is required; the gallery scraper can be used for generating these as well.
The purpose of this userscript is collecting image gallery URLs for use with CYOA Viewer. It's designed for three types of pages: gallery page (e.g. Imgur gallery), URL generator and the Viewer itself (though technically it can be used with any website, there's no practical reason to enable the script on an unrelated page).
This is the menu that you're likely going to use most often. Its main item (highlighted) is for reading the gallery URLs
(three gallery hosts are supported:
imgchest.com
, imgur.com
and m.imgur.com
; the latter can be used to
circumvent Imgur login demands by pretending to use an Android browser).
The remaining menu items are operating the data of latest collected gallery; if there's none stored, only the main item
will be displayed.
This menu will be displayed on the CYOA Viewer page. The only difference is the main item, which collects the images by
parsing the page URL (thus allowing you more convenient access to this data). Works on v1 by default, but should work
with v2 just as well (state parameter will be ignored though).
And this menu is displayed on URL generator page; unlike other cases, its main item also reads the stored data rather
than write it (it fills up the form), thus it won't be displayed if there's no gallery stored.
Other menu items are:
presets.json
entry (only relevant if you're maintaining your own presets.json
)
To add alternative index/Viewer pages (like local copy or different host) you can simply include them in your script settings (use Rebase option for generated URLs). You can also include any other pages; there shouldn't be a problem in the work of the script, it simply won't show the main item on unrelated sites (unless it misdetects the site type).
The exact URL patterns for gallery sites are https://imgchest.com/p/*
, https://imgur.com/a/*
and
https://m.imgur.com/a/*
; you can try adding other gallery links from these sites (via script options), but supporting
other gallery websites would require changes in the userscript code due to differences in their layout/implementation.
Note: m.imgur.com
doesn't provide a way to access hidden pages (revealed by a "more pages" button), so you'll need to
manually ensure all pages are revealed before collecting them (additionally the script hides extra galleries below which
should also prevent Imgur from going crazy if you scroll down too low); same goes for ImageChest. Regular Imgur
galleries engine has been recently replaced so I'm not too clear on whether it has the same limitation.
This userscript is designed as a utility for preset creation/editing. It can be used to detect the most likely issues
with a v2 CYOA data (that can be recognized automatically): leftover play state from playtesting, and inaccessible page
images.
Before exporting your (new version of) base state, you may want to check if there's any problems with it using the main
item of the menu, "Check state". Aside from statistics (pages/cards/categories count), it will show you if any pages
aren't loaded yet (which means they either can't be fetched by browser, or take a long time to load for some reason),
if there's any empty categories (with configured cost but no cards remaining), and whether there's anything in-play
(e.g. leftover from playtesting, or when you accidentally write card meta into comment). Additionally, all duplicate
card titles are displayed (see editing guidelines).
Take note that since playing some CYOAs requires modifying non-play data (such as editing cost of a certain card due
to effect of another card), not all changes made during test play can be detected automatically (as non-play data
changes can just as well be normal edits). Thus, it's better to do your playtesting after you've exported the state,
thus allowing you to reset playtest data by simply re-importing it.
Other menu items will navigate the Viewer to the first card with play data, the first page that failed to load, or the
first suspiciously tiny page (when Imgur removes images, they don't fail to load, it simply sends back a different
image). In addition, you can use "Find card" (quick key F
) to navigate the Viewer to an arbitrary card by its title
(or part of it); the match is case insensitive, and repeated search will start from the position of the previous one
(if nothing is found, a message is shown and the search position is reset).
Userscript also prints build date to console, if available (this also works with v1), and when running "Check state" it prints base state creation date (also if available).
Additionally, running v2 with state analyzer will give you a couple extra REPL commands (see below).
If you use the debugger (either directly in desktop browser, or debugging a mobile browser remotely from its desktop
version), or if you decide to write/edit an userscript, you'll have access to JavaScript functions that operate v2
state. (Most of them follow internal codebase naming convention, which is the reason for all the $
s.)
$storageManager()
can be called to immediately open storage manager dialog (when the button isn't available)$copyPage(i, j=i+1)
copies cards from page #i to page #j (which is assumed to be i+1 if not provided; pages are
numbered same as in UI); this is useful when editing a large CYOA that has similar card sets on different pages.diff$()
returns a recursive diff of base state and current state of v2. If they aren't equal, it returns a tuple
of the old and new changed values; meaning that if some value foo.bar.baz
has changed between base and current
state, diff$()[0].foo.bar.baz
will include its old value, and diff$()[1].foo.bar.baz
will contain its new value
(if a value was removed, only old value will be present, and if a value was added, only new value will be in the
diff). This is useful for checking what was changed if you're creating/updating a base state, or as a more verbose
variant of state analyzis (i.e. when playtesting).diff$()
cannot detect array insertion/deletion (the output format doesn't support that either way), thus every
element that changed position will be considered an edit of the element located there previously.pformatDiff$()
returns a pretty-formatted result of diff$()
(which can be printed like this:
console.log( pformatDiff$() )
).console.log
in REPL does that as well, but width reduction isn't quite as bad).cardsInPlay$()
returns a list of cards (as titles) that are counted as being "in play".findByPoints$(name)
returns a list of cards (as titles) that have matching points in their cost or bonus.reFrame
. You can poke it around, or read the
state-analyzer userscript source to see what you can do with it; but if you can't tell how to use it after that,
chances are, you won't have a use for it anyway.No software is perfect; any program will have bugs (including browsers, incidentally). Some of them are cases of wrong application logic – those I weeded out as I encountered them; others are basically tradeoffs due to limitations of the platform (or impossibility to have your cake and eat it too).
To prevent losing scroll position when resizing the viewing area (toggling the panel, going fullscreen, resizing
browser window), the vertical scroll position is artificually persisted during such resizes (anchored to the middle
of the screen). This, however, means that other scrolling of view area doesn't work during that time; for example, if
you're using "Find …" menu items of state analyzer from browser fullscreen (that is, you're opening menu button from
the toolbar, and after picking menu item the toolbar gets hidden, thus increasing page size), it won't scroll anywhere
because it's doing the resize anchoring at that very time.
Also, the anchoring may cause the viewing area to look jerky when it's being gradually resized (because of the scroll
position being repeatedly changed by browser and restored by the app).
Card-pickers in the viewing area (the +
/−
buttons in Play mode) are rendered within the same layer as the cards
themselves; that's why even though they're normally at the top of the card, that's not the case when it's too close
to the page top (to ensure they won't become inaccessible) – this last part can be confusing if you forget about it.
("Too close" in this context is 5% of the page height.)
They're also proportional to the layer size, which means the smaller view area width is, the smaller they are (though
I had no problem using them on a smartphone in portrait mode despite their tiny size).
Since the triggers for selecting a card in viewing area and for creating a new card are essentially the same action (pressing and releasing left mouse button), it may get in the way when tryng to click on a card sometimes (usually it means you're clicking too slowly). If you're having a hard time, you can select the card from navigation panel. (The issue only happens when no card is selected, so selecting a different card first is also an option.)
Some browsers may have weird storage policies. For instance, in private mode, Firefox uses separate storage for a page that was freshly opened, and a page that was refreshed. (On the bright side, that may mean you're never going to hit a storage limit unless you do reload the Viewer page, because a freshly opened page basically has its own personal storage.)
Android support is experimental at best (and don't even bother mentioning iOS). This is partially due to touchscreens (especially the tiny smartphone ones) being a bad match with fine input like dragging (and typing to some extent), and partially due to mobile browsers having some bizarre quirks. v1 is mostly fine though.
multiple
parameter), some when you give them multiple files pass just one file
to the webapp (and even that file isn't a valid image somehow), some work fine with local files but refuse to open
files from Google Disk. Again, if that's important to you, check if it works in your browser.ResizeObserver
despite having no
proper alternative). Try to use a major browser if you want to avoid problems (Chrome in particular appears to
behave almost exactly the same as its desktop version, as far as I could tell).Mentioned before but if you missed it:
m.imgur.com
, the gallery jump is disabled by the userscript); this doesn't concern imgur.com
.diff$()
(and thus pformatDiff$()
as well) doesn't recognize insertion/deletion (any array items changing index
are considered in-place changes); so, it's not much helpful when removing cards (or adding them before already
existing ones).…And of course, there might be some errors that I missed. The web platform may be versatile (in ease-of-access and starting point sense), but it's got more holes than a sieve. (That's not even considering the multitude of quirks in all the different browsers.)