tmedwards / sugarcube-3 Goto Github PK
View Code? Open in Web Editor NEWSugarCube is a free (gratis and libre) story format for Twine/Twee.
SugarCube is a free (gratis and libre) story format for Twine/Twee.
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.
It's time to change SugarCube's baseline browser support.
Consider changing the baseline browser target to:
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.
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.
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')>>
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.
Idea: The various history functions/methods should not consider the current moment.
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.
Other ideas?
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.
Should whitespace handling be changed? Currently, there are a couple basic mechanisms to control line breaks, but not much more than that.
There are no current spacing control mechanisms.
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.
<<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.
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.
Improve the naked variable markup's ability to match variable property chains.
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.
I have some suggestions for improvements to this macro:
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 }
]
<<link>>
.<<audio>>
.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).
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.
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.
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.
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>
.
Replacing non-semantic tags with custom tags on a limited basis could serve various purposes:
<sc-slider>
, <sc-volume>
, <sc-textbox>
, etc.<br>
to <p>
conversion.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.
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.
When the StoryInterface
special passage is used, ensure that references to default UI elements—e.g., #story
—do not fail to take into account that they may not exist.
Make improvements to the Debug bar.
Other suggestions?
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.
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.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.
I think SugarCube should adopt github flavored markdown, or at least most of it to the extent possible. I doubt this is particularly controversial.
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:
(macro: args...)
[macro: args]
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.
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.
Should dialogs that few, if any, are using be removed? E.g., Jump To and Share.
Might need to do a poll or something.
Where sensible, attempt to further remove circular dependencies within the codebase.
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
Does the state history really need to exist?
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.
With only a single, active, state:
Config.history.maxStates
to 1
.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.
[[Drive to the $location|$location]]
vs. the current [["Drive to the " + $location|$location]]
.[[I'll ''kill'' you!|Attack]]
.A somewhat nebulous goal, but… attempt to make the default UI better, in general.
Fullscreen
API.What it says on the tin.
dir="rtl"
.There should be an optional argument that allows one to manually specify a <<radiobutton>>
group.
ORIGINATING ISSUE: tmedwards/sugarcube-2#76
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>>
?Save
API and the Save dialog.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.
Others I'm likely not thinking of at the moment.
StorySplash
StoryIntro
Other suggestions?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.