Giter VIP home page Giter VIP logo

sugarcube-3's People

Contributors

tmedwards avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sugarcube-3's Issues

Add a "popout" window

As a fix for the "long return" problem for the <<return>> macro (see issue #19), how about adding a "popout" tag which could be added to passages, and rather than them going to a new passage, it would simply pop the content over top of the current passage in a closeable window (similar to a dialog, but covers up the passage entirely).

Once you close the "popout" window, then you'll still be right where you left off. Going to a non-"popout" passage would also close the "popout" window. If you went from one "popout" passage to another, it would simply close the existing popout window, and then open the "new" popout window (same "window" but with the new "popout" passage's content). <<back>> and <<return>> would also close the "popout" window, though I'm not sure if/how you'd want to handle undoing variable changes in the <<back>> case.

You might also want to create a :popoutClose event and/or <<popoutClose>> macro (for use in "popout" tagged passages) so that they can trigger other code when the "popout" window is closed.

Baseline browser support

It's time to change SugarCube's baseline browser support.

Consider changing the baseline browser target to:

  1. Internet Explorer 11. For reference, v2's baseline target is IE 9.
  2. Browsers that support ES2015 (ES6). This pretty much means dropping ancient browsers altogether.

Improve functioning of Config.cleanupWikifierOutput

WAS: Problem: Automatic paragraph indentation is inconsistent


Problem: Automatic paragraph indentation is inconsistent

This problem is seen when using SugarCube v2.31.1 (compiled by tweego v2.1.1+81d1d71).

Since the symptoms are somewhat more complex than discussed in the IF Forum, I decided it would be appropriate to report this formally as a bug.

When a section of text consisting of multiple paragraphs is not enclosed by either a "span" or a "div", all paragraphs are properly indented.

When a section of text consisting of multiple paragraphs is enclosed by a "span", only the first paragraph is indented.

When a section of text consisting of multiple paragraphs is enclosed by a "div", none of the paragraphs are indented.

In all three cases, I believe that all paragraphs should be indented.

Here's a twee/SugarCube story which demonstrates the problem.

:: StoryData
{
        "ifid": "C31A5464-60FC-4937-A550-C7D75F7692AF"
}

:: StoryTitle
Test Paragraph Indentation

:: Story Stylesheet [stylesheet]

/* indent paragraphs (in conjunction with Config below) */
.passage p { margin-left: 1.0em;
	     margin-right: 1.0em;
	     text-indent: 2.0em;
	    }

:: Story JavaScript [script]

/* automatically indent paragraphs */
Config.cleanupWikifierOutput = true;

:: Start
!! This is the Start passage.

When simply included, all paragraphs are indented:

<<include "content">>
----
When enclosed in a "span", the first paragraph is indented:

<span id="first"> <<include "content">> </span>
----
When enclosed in a "div", no paragraphs are indented:

<div id="none"> <<include "content">> </div>

:: content

Magna illud minim ius at, pro no numquam expetendis, an eam vidit denique. No numquam detraxit eos, inani detracto te quo, ad vim tritani accommodare. Utamur insolens qui no, cum at accusata delicatissimi, unum albucius ne eam.

Magna illud minim ius at, pro no numquam expetendis, an eam vidit denique. No numquam detraxit eos, inani detracto te quo, ad vim tritani accommodare. Utamur insolens qui no, cum at accusata delicatissimi, unum albucius ne eam.

Asynchronicity and user APIs

One of SugarCube v3's, aspirational, goals is to enable the use of IndexedDB as a storage provider. Unfortunately, since IndexedDB only offers an asynchronous API, this has consequences for any SugarCube API that provides or depends on storage.

Internally, this isn't an issue. For user facing APIs, however, this could have serious consequences. For example, the recall() API would be seriously changed by this:

// Current synchronous usage.
<<set $foo to recall('foo', 'bar')>>

// Asynchronous usage directly using the returned `Promise`.
<<set recall('foo', 'bar').then(value => $foo to value)>>

That's not a change that I think most users would be happy to see—the non-technical ones, at the very least.

Try to find a solution or workaround for this that's more user friendly.

EDIT: Addendum

There's also the possibility of using await, however, that's only slightly less bad for users. Assuming it could be made to work in the context it would execute within in the first place.

// Asynchronous usage `await`'ing the returned `Promise`.
<<set $foo to await recall('foo', 'bar')>>

Something like partial application for macro aliases

It would be nice to have the ability to fix a number of arguments to a macro in an alias, so as to reduce its arity.

This seems especially useful if arguments are pushed more heavily towards optional named arguments.

History functions/methods should not consider the current moment

Idea: The various history functions/methods should not consider the current moment.

Reasoning

Currently, the various history functions/methods—e.g., the visited family of functions and State.hasPlayed()—include the current moment in their tests/collations. This has the effect that testing for the existence of a moment based on the current passage is impossible with most of them, as it'll will be topmost moment that they check. This requires the use of visited() in many case where you simply want to know if the player had been there before, which is less than ideal as it looks at every single moment in the past+expired history.

Documentation improvements

  • Consider adding a small glossary or overview that covers some of the core terms/ideas—e.g., what's a turn—that is somewhat spread around multiple places within the current documentation. As an alternative, putting all relevant information within a single location and providing see references to others might be workable.
  • Allow the sidebar sections to be collapsible.

Other ideas?

Add scopes to temporary variables

What it says on the tin.

Have container/non-void macros automatically create a new scope for temporary variables, which is removed after the handler completes.

Likely implementation is a prototype-chain stack.

Whitespace handling

Should whitespace handling be changed? Currently, there are a couple basic mechanisms to control line breaks, but not much more than that.

Spacing control

There are no current spacing control mechanisms.

Line break control

The two basic mechanisms of line break control are (in order of implementations): line continuations and the no-break features—in order: nobr tag, <<nobr>> macro, Config.passages.nobr setting.

Line continuations: (markup-based)

  • Pros: Allow precise control over line breaks by eliding them.
  • Cons: Must be used consistently.

No-breaks: (source editing-based)

  • Pros: Do not require consistent use, being more fire-and-forget.
  • Cons: Sloppier control over line breaks by converting them to spaces.
  • Issues: Incompatible with any markup that requires line positioning—e.g., line continuations, headings, etc—and can break <<script>> code.

A potential fix for both of the issues of the no-break features would be to make them, essentially, markup-based as well by simply having them disable the lineBreak parser. The downside would be that the nobr tag could not be converted over thus and would need to be dropped, leaving only the macro and global setting.

CSS Sugarcube styling exclusion zone

Problem: When using third party widgets, like a jQuery plugin or a Vue/React App, those typically come with styling that assumes little or no prior global styling, and will generate DOM elements that end up getting undesirable styling from the sugarcube-default styling that exists for things like button, a, input, and the like.

It would be nice to have element-selectors to be prefixed with something like: :not(.sc-nostyle), so that third party widgets and the like could be placed in a div.sc-nostyle avoid avoid sugarcube changing the appearance of the widget (buttons, inputs, etc) inside that div.

References within story variables

Neither the clone() function, the delta coder, nor the serializer support maintaining relative references within story variable stores. It would be trivial to alter the clone() function to do so, however, not so much with the other two.

Look into this.

Improvement suggestions for <<numberbox>>

I have some suggestions for improvements to this macro:

  • It considers a decimal point to be an error unless it's .0 -- I think these should be configurable validation settings. Sometimes you want to real numbers, sometimes you only want integers.
    • The text is considered valid if you type in "1." -- This should be considered invalid.
  • It is inconsistent about when it reports errors. If you type "asdf" it reports it as an error when it loses focus. If you type "1.5" it reports it as an error as you are typing. -- this should be consistent, preferably errorring as you type
  • It lets you type in letters, but doesn't save the letters into the variable, preventing you from telling the user that "$var is not a number" (that would print as "0 is not a number") -- I think you should not be allowed to type or paste anything but numbers and decimal points (commas, depending on locale). That would fix a lot of these problems.
    • It would be nice to have way of knowing if the field is invalid. That way, I could prevent a continue button from being clicked. If 0 is a valid number in context, I don't know how to tell if somebody typed in zero or something invalid.
  • It doesn't let you specify a valid range -- I think more often than not, there is a valid range and an invalid range. It would be nice if the macro allowed you to specify it. You should not be able to use numbers outside of this range.
  • It saves a string into the variable, making it inconvenient to implement custom range validation. -- I think the variable should be a number type
  • When you click on the text field, it doesn't highlight the content of the field. This means, if you click and then type 3, it'll probably come out as 30 or 03. You have to click, delete/backspace (depending on which side of the number you clicked), then type what you want to enter -- clicking on the field should highlight the text
  • If you type in letters, clicking the up/down buttons doesn't do anything. I think it should clear the field and +/- the default number. -- ideally, you wouldn't be able to type in letters at all, but if you want to allow that, I think the buttons should clear the field, reset it to the default, and execute the up/down code

Macro arguments

Issues with macro arguments currently

  • Receiver variable names have to be quoted for the invocation.
  • There's no way to specify how macro arguments should be parsed, other than to do it or not.

Ideas

  • Make receiver variable names not have to be quoted.
  • Allow/require granular specification of how macro arguments should be parsed.

Possible solution 1

A possible solution would be a new args property that's an array of positional argument objects. Each argument object would consist of three properties:

  • types ([]string, default: ['any'])
  • optional (boolean, default: false)
  • receiver (boolean, default: false)

For example:

args : [
	{ receiver : true },
	['string'],  // Could allow arrays as a shortcut for `{ types : … }`.
	{ types : ['string'], optional : true },
	{ types : ['string'], optional : true }
]

Complications

  • It's unclear how macros with multiple argument styles would fit into this—e.g., <<link>>.
  • It's also unclear how macros with named arguments would fit into this—e.g., <<audio>>.

Possible solution 2

Provide a way to specify which positional arguments are receivers—e.g., probably an array of indices receivers : [0]—and provide an explicit way to handle argument assertions—e.g., via new MacroContext method(s).

Parsing

There should be exactly one core parsing engine for SugarCube—rather than umpteen ones scattered here and there—that may be reused for various parsing needs via separate grammars—i.e., core parsing, macro argument parsing, etc.

The parser must be performant. Parsing times should either stay roughly the same or noticeably improve versus the current crop of parsers from v2.

Minor, domain specific parsers may remain where sensible.

Printing undefined/null/NaN

When printing, values like undefined, null, NaN, etc. are often elided or replaced—e.g., the naked variable markup simply reprints the variable name when encountering such values. This was done in an attempt at user friendliness, however, in hindsight it causes a not insignificant amount of confusion.

It would be better if such values either caused some kind of error—either a standard SugarCube error or something like the variable name and the value $someVar(undefined)—or simply printed a string representation of the value.

Update the documentation to show the internal StoryInterface passage

Is your feature request related to a problem?
I want to take the body of my passage and wrap it in a main HTML element. I'm already using PassageHeader, and I DON'T want its content wrapped in the main element. This way, I can easily refer to $("main") when I need to refer to the passage body. Right now, I have to refer to everything that's not the header, but at the same depth. Pretty inconvenient.

Describe the solution you'd like.
After browsing the documentation, it seems like the easiest way of doing this would be to create my own StoryInterface passage. But, I just want to modify one piece of it, not rewrite it from scratch. Unfortunately, the HTML example example is full of ....

Wouldn't it be possible to fill those in with the content that SugarCube really uses for its default StoryInterface? That way, I could just copy and paste that file and modify this one thing.

I know the documentation says that the ... is for dynamic content, but that doesn't give me enough context to understand why this can't be done; a custom StoryInterface can have dynamic content too.

Describe alternatives you've considered.
I think there is a :storystart solution here.

Custom HTML tags

Consider using custom HTML tags within SugarCube's UI where appropriate. Meaning limited to areas where I'd be temped to use Shadow DOM if I could—i.e., various control wrappers mostly—and only to replace tags with no inherent semantic meaning of their own—e.g., <div> and <span>.

Reasoning

Replacing non-semantic tags with custom tags on a limited basis could serve various purposes:

  • Custom tags would have inherent semantic meaning—e.g., <sc-slider>, <sc-volume>, <sc-textbox>, etc.
  • Custom tags would bypass some user sloppiness with their own CSS selectors—only some, however.
  • Custom tags would allow certain other features to work easier—e.g., <br> to <p> conversion.

Thoughts?

UI Bar "Footer" passage

A couple of times I've wanted a "footer" at the bottom of the UI bar to display version information, buttons, etc.. I've been doing that by using jQuery to insert another <div> into the #ui-bar element and using CSS to force it to the bottom of the UI bar.
However, this feels like a bit of a hack.

It would be nice to have another special passage you could use to easily add a "footer" to the bottom of the UI bar.

Just a thought.

#passages element

Consider removing the #passages element. It's a holdover from SugarCube's roots and unnecessary for normal functioning.

The only concern would be if it's required for some user layouts.

Debug bar

Make improvements to the Debug bar.

Ideas

  • Make it into a full sidebar.
  • Add a TwineScript/JavaScript input box, which is executed within SugarCube's scope.
  • Watches should auto-update outside of navigation. Done, though I'm not 100% pleased with how.

Other suggestions?

Audio subsystem should be stateful

The audio subsystem—the SimpleAudio API and backing browser APIs—currently integrate neither the current audio configuration nor current playback state into play sessions—meaning neither page reloads nor save loads may restore the audio state.

This requires authors to either accept that audio may briefly stop playing after a page/save load or add extra code to ensure their audio is restored after such.

It would be better if the audio subsystem could handle this automatically for authors.

Issues

  • How navigating the history should affect playback state is not entirely clear.
  • It's possible to use the SimpleAudio API to create state that cannot be serialized correctly. Unfortunately, nothing can be done about this save noting the instances within the documentation—that no one will read.
  • Not an issue for v3. There is the potential to break existing code—likelihood in cases where authors have added their own restoration code.

Syntax Changes

In addition to being an extreme amount of work, a lot of users will probably have strong reactions to major syntax changes. Still, it's a good time to do it if you're going to.

Markup

I think SugarCube should adopt github flavored markdown, or at least most of it to the extent possible. I doubt this is particularly controversial.

Macro Syntax (general)

Double angle brackets are a bit awkward to type and read, though they work and you do get used to them. Ideas for potential replacements:

  • Harlowe-esque: (macro: args...)
  • BBCode style: [macro: args]
  • Most grouping-style punctuation could conceivably work, grouping meaning it uses two separate characters for opening and closing, so braces could work too. Single arrow brackets are certainly unwise given the potential confusion with HTML. Using parens or brackets will probably require an additional tell in the macro like Harlowe's colon.

Arguments

A space separated list is fine, but it introduces problems parsing expressions, necessitating the use of backticks to indicate when the result of an expression is to be passed as an argument. Harlowe uses commas to get around this (mostly). Separating arguments like this may be the lesser of two evils compared to a special syntax for expressions.

Arguments could also be passed in other ways, like in this BBCode-ish syntax:

[link passage="some passage" text="Click me!"]...[/link]

This doesn't really solve the issue of expressions directly, though it may still be possible compared to space-separated arguments. It does allow arguments to be passed in any order, however, at the cost of more typing.

Containers

SugarCube could adopt blocks (or "hooks") rather than opening and closing macros as containers. Doing this may actually open up even more possibilities for macro syntax as well, since they will be associated with elements by means other than a closing tag. Of course, this has the side effect of making child tags of some kinds quite a lot more complicated to implement as near as I can reason about it.

Lightly used dialogs

Should dialogs that few, if any, are using be removed? E.g., Jump To and Share.

Might need to do a poll or something.

Pros

  • Pruning code that few, if any, are using is good.
    • Less bloat for users' compiled projects.
    • Less surface area for things to go wrong internally.

Cons

  • Pruning code that is in common usage is bad.

Custom spinner

Dear TME,

I will keep it short,

Some people, like me and a user named Bogdan, would love to make a custom spinner.

Going through the trouble of:
html[data-init=loading] #init-loading { animation: none; background: url("icons/load.gif") no-repeat center center; background-size: contain; border: none; height: 10em; width: 10em; }

Inside modules/spinner.css and then calling it with call tweego -o export/index.html --module=modules src is a lot of trouble, and requires both tweego and undocumented things (I couldn't find it on the github/motoslave), thanks to lovely Cyrus and your older posts in the discord we were able to build it! But I would love to be able to either change it from the story css or maybe even a macro.

This is my first "issue" ever, sorry if it didn't fit the format!

Yours sincerely,
Bogdan and Sjoerd

Reconsidering the state history

Does the state history really need to exist?

Reasoning

The state history is a holdover from the original two story formats, Jonah and Sugarcane. There it existed to allow players to back up and revisit previous decisions and/or scenes as those formats did not have the ability to truly save the playthrough state—the path taken was reflected within the URL fragment identifier, but that failed to record anything else.

All versions of SugarCube, by default, have the ability to save playthrough state, so a separate system to allow players to revisit previous decisions and/or scenes is not really necessary.

Pros & Cons

With only a single, active, state:

Pros

  • There would be no need for moment to moment cloning, which would alleviate many pain points for developers—e.g., broken references for one, though serialization would still need to be modified to handle that.
  • There would be no need for delta coding the serialized state.
  • The serialized state, as seen in sessions and saves, would become smaller—much smaller for anyone not having set Config.history.maxStates to 1.
  • [Maybe?] The saved state could possibly become the active state, so sessions and saves would reflect the current game state at the moment the save was made. Thus, interactive sections would become persistent.
  • Several of the other items on this list would help speed up games that currently experience slowdowns—both while playing and saving/loading.

Cons

  • If the player didn't make a save, they can't simply revisit a previous moment. That's fairly common in other games, however, and some developers set their games up that way anyway, so that's not a huge issue.
  • [Maybe?] If the saved state were made the active state, sessions and saves would reflect the current game state at the moment the save was made. This is different from what developers are used to, so it has the potential to be a tripping hazard—e.g., a scene written with assumptions about variable state could find those assumptions invalidated.

Square bracketed markup component makeup

Reconsider the makeup of the non-setter components of the square bracketed markup—i.e., whether they should accept markup rather than plain text or a TwineScript expression.

Reasoning

  • The current situation where non-setter components may be either plain text or a TwineScript expression causes issues that cannot be resolved. In particular, accidental leakage of globals/auto-globals is possible—currently, a flawed workaround is employed to mitigate this specific issue.
  • A TwineScript expression being required to concatenate a variable is often somewhat surprising to new users, especially to those who have not read the docs—which is all of them, frankly.
  • Even basic markup is not currently allowed.

Pros

  • Accidental identifier leakage would virtually disappear and require no workaround to mitigate.
  • Could be easier for the less technically inclined—i.e., [[Drive to the $location|$location]] vs. the current [["Drive to the " + $location|$location]].
  • Basic markup would be available—e.g., [[I'll ''kill'' you!|Attack]].

Cons

  • Different from what users are used to currently.
  • Need to make use of profiles/restricted grammars to ensure that markup/macros that have no business within a link or image are allowed, and different components would need different restrictions—e.g., the link component would need to be very heavily restricted. Unsure how to restrict HTML markup here, other than completely.

Default user interface (general)

A somewhat nebulous goal, but… attempt to make the default UI better, in general.

Ideas

  • Attempt to simplify the markup and CSS where possible.
  • Add new optional features. E.g.,
    • A control for master audio mute & volume.
    • A control for the Fullscreen API.
    • Simple toast notifications?

Add support for RTL languages

What it says on the tin.

  • Add an RTL config property to the I18n API and language files.
  • Enable HTML content attributes based on the RTL config—e.g., dir="rtl".
  • Investigate what additional programmatic changes may be necessary to support RTL.

Rethink problematic macros

Rethink—rework, repurpose, or remove—problematic macros.

  • <<actions>> – Either confusing or a poor fit for what most want to do with it.
  • <<back>> – Name is confusing to some. Possibly rename to <<undo>>?
  • <<choice>> – Either confusing or a poor fit for what most want to do with it.
  • <<return>> – Name is confusing to some and doesn't currently work for long return cases.
  • <<silently>> – Macro is fine, I just dislike the name. Possibly rename to <<silent>>?

Saves (API and dialog)

Todo

  • There should be a way to export and import the save slots via the Save API and the Save dialog.
  • Some people have been confused as to what the Save to Disk… and Load from Disk… buttons actually do—e.g., thinking they export the save slots to disk. They should probably be moved to a separate section within the dialog, distinct from the slots.
  • UI work: Compact the slots a bit by changing fully to icons, if I can pull together a set that makes sense.
  • UI work: Allow authors greater freedom in what can be displayed.
  • UI work: Allow players the ability to name saves—probably author configurable.

Ideas

  • Make slots user nameable or remove the static slots altogether in favor of user nameable entries—e.g., like saves in many PC games. The latter would still need to be limited in number, due to limited storage resources, so maybe the former would be best.

Intro/splash screen special passage

A special passage that is shown to players before the normal starting passage and does not become part of the history. Essentially, an introduction or splash screen.

My current idea on how it should work is that it would simply require any player interaction to move past—basically, the whole viewport would get the equivalent of an […].ariaClick() event handler.

Reasoning

  • To remove user-made screens from the story history.
  • As a workaround for user activation requirements for media playback.

Others I'm likely not thinking of at the moment.

Possible Names

  • StorySplash
  • StoryIntro

Other suggestions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.