Add story basic framework

This commit is contained in:
Matteo Settenvini 2024-09-01 14:28:50 +02:00
parent 7701e7119f
commit 7eec6ce4da
8 changed files with 424 additions and 307 deletions

2
.gitignore vendored
View File

@ -2,5 +2,7 @@
*.orig *.orig
*.rej *.rej
/.vscode
/node_modules /node_modules
/dist /dist

View File

@ -7,8 +7,10 @@
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
</head> </head>
<body> <body>
<div class="outerContainer"> <div class="outerContainer">
<div id="errors"></div>
<h3 class="written-in-ink"><a href="https://www.inklestudios.com/ink">WRITTEN IN INK</a></h3> <h3 class="written-in-ink"><a href="https://www.inklestudios.com/ink">WRITTEN IN INK</a></h3>
<div id="controls" class="buttons"> <div id="controls" class="buttons">

View File

@ -4,12 +4,17 @@
// Under the MIT license. // Under the MIT license.
import { Compiler } from 'inkjs/compiler/Compiler'; import { Compiler } from 'inkjs/compiler/Compiler';
import { ErrorType } from 'inkjs/engine/Error';
import "./style.scss"; import "./style.scss";
import data from '../story/main.ink'; import data from '../story/main.ink';
const story = new Compiler(data).Compile(); const story = new Compiler(data).Compile();
story.onError = (message: string, type: ErrorType) => {
document.getElementById('errors')!.innerText = `BUG: ${type}: ${message}`;
};
// Global tags - those at the top of the ink file // Global tags - those at the top of the ink file
// We support: // We support:
// # theme: dark // # theme: dark
@ -243,14 +248,12 @@ function clearStory() {
function restart() { function restart() {
clearStory(); clearStory();
story.ResetState(); story.ResetState();
setVisible(".header", true); setVisible(".header", true);
// set save point to here // set save point to here
savePoint = story.state.toJson(); savePoint = story.state.toJson();
continueStory(true); continueStory(true);
outerScrollContainer.scrollTo(0, 0); outerScrollContainer.scrollTo(0, 0);
@ -335,7 +338,7 @@ function setVisible(selector: string, visible: boolean) {
} }
// Helper for parsing out tags of the form: // Helper for parsing out tags of the form:
// # PROPERTY: value // # PROPERTY: valuedi
// e.g. IMAGE: source path // e.g. IMAGE: source path
function splitPropertyTag(tag: string) { function splitPropertyTag(tag: string) {
var propertySplitIdx = tag.indexOf(":"); var propertySplitIdx = tag.indexOf(":");

View File

@ -1,296 +1,2 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Quattrocento:wght@400;700&display=swap'); @use 'styles/global.scss';
@use 'styles/story.scss';
body {
font-family: 'Inter', sans-serif;
font-weight: 600;
background: white;
overflow: hidden;
@media screen and (prefers-reduced-motion: no-preference) {
&.switched {
transition: color 0.6s, background-color 0.6s;
}
}
}
@mixin titles {
text-align: center;
font-family: "Quattrocento", Georgia, 'Times New Roman', Times, serif;
margin: 0;
padding: 0;
}
h1 {
@include titles;
font-size: 30pt;
margin-bottom: 10px;
}
h2 {
@include titles;
font-size: 14pt;
font-style: italic;
font-family: sans-serif;
font-weight: lighter;
color: #BBB;
}
.header {
padding-top: 3em;
padding-bottom: 3em;
}
/*
Built-in class:
# author: Name
*/
.byline {
font-style: italic;
}
.written-in-ink {
z-index: 3;
font-size: 9pt;
font-family: sans-serif;
text-align: center;
font-weight: 700;
position: fixed;
display: block;
width: 100%;
background: white;
margin: 0;
padding-top: 6px;
padding-bottom: 6px;
height: 14px;
top: 0;
}
@media screen and (prefers-reduced-motion: no-preference) {
.written-in-ink {
transition: color 0.6s, background 0.6s;
}
}
/*
Enables <iframe> support work on itch.io when using mobile iOS
*/
.outerContainer {
position: absolute;
display: block;
margin: 0;
padding: 0;
-webkit-overflow-scrolling: touch;
overflow: scroll;
overflow-x: hidden;
height: 100%;
width: 100%;
top: 0;
left: 0;
margin-top: 24px;
background-size: cover;
background-repeat: no-repeat;
@media screen and (max-width: 980px) {
margin-top: 44px;
background-size: cover;
background-repeat: no-repeat;
}
}
.container {
display: block;
max-width: 600px;
margin: 0 auto;
padding: 20px;
padding-top: 4em;
background: white;
.hide {
opacity: 0.0;
}
.invisible {
display: none;
}
> * {
opacity: 1.0;
@media screen and (prefers-reduced-motion: no-preference) {
transition: opacity 1.0s;
}
}
}
@media screen and (prefers-reduced-motion: no-preference) {
.switched .container {
transition: background-color 0.6s;
}
}
p {
font-size: 13pt;
color: #888;
line-height: 1.7em;
font-weight: lighter;
}
a {
font-weight: 700;
color: #b97c2c;
font-family: sans-serif;
text-decoration: none;
&:hover {
color: black;
}
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s;
&:hover {
transition: color 0.1s;
}
}
}
.unclickable {
font-weight: 700;
color: #4f3411;
font-family: sans-serif;
text-decoration: none;
cursor: not-allowed;
}
strong {
color: black;
font-weight: bold;
}
img {
display: block;
margin: 0 auto;
max-width: 100%;
}
/*
Class applied to all choices
(Will always appear inside <p> element by default.)
*/
.choice {
text-align: center;
line-height: 1.7em;
&:first-of-type {
padding-top: 1em;
}
/*
Class applied to choice links
*/
a, span {
font-size: 15pt;
}
}
/*
Built-in class:
The End # CLASS: end
*/
.end {
text-align: center;
font-weight: bold;
color: black;
padding-top: 20px;
padding-bottom: 20px;
}
#controls {
z-index: 4;
font-size: 9pt;
text-align: center;
padding-bottom: 6px;
position: fixed;
right: 14px;
top: 4px;
user-select: none;
background: white;
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s, background 0.6s;
}
@media screen and (max-width: 980px) {
z-index: 2;
padding-top: 24px;
top: 0;
left: 0;
right: 0;
}
[disabled] {
color: #ccc;
}
> *:not(:last-child):after {
content: " | ";
}
}
/*
Dark Theme (Added in Inky 0.10.0)
# theme: dark
*/
body.dark {
background: black;
color: white;
h2 {
color: #666;
}
.container {
background: black;
}
.written-in-ink {
background: black;
}
a {
color: #cc8f1a;
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s;
}
&:hover {
color: white;
}
}
.unclickable {
color: #c4af87;
cursor:not-allowed;
}
strong {
color: white;
}
#controls {
background: black;
[disabled] {
color: #444;
}
}
.end {
color: white;
}
}

303
src/styles/global.scss Normal file
View File

@ -0,0 +1,303 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Quattrocento:wght@400;700&display=swap');
body {
font-family: 'Inter', sans-serif;
font-weight: 600;
background: white;
overflow: hidden;
@media screen and (prefers-reduced-motion: no-preference) {
&.switched {
transition: color 0.6s, background-color 0.6s;
}
}
}
@mixin titles {
text-align: center;
font-family: "Quattrocento", Georgia, 'Times New Roman', Times, serif;
margin: 0;
padding: 0;
}
h1 {
@include titles;
font-size: 36pt;
margin-bottom: 10px;
}
h2 {
@include titles;
font-size: 16pt;
font-style: italic;
font-family: sans-serif;
font-weight: lighter;
color: #BBB;
}
.header {
padding-top: 3em;
padding-bottom: 3em;
}
#errors:not(:empty) {
font-family: monospace;
color: red;
background-color: rgb(230, 230, 230);
padding: 1em;
}
/*
Built-in class:
# author: Name
*/
.byline {
font-style: italic;
}
.written-in-ink {
z-index: 3;
font-size: 9pt;
font-family: sans-serif;
text-align: center;
font-weight: 700;
position: fixed;
display: block;
width: 100%;
background: white;
margin: 0;
padding-top: 6px;
padding-bottom: 6px;
height: 14px;
top: 0;
}
@media screen and (prefers-reduced-motion: no-preference) {
.written-in-ink {
transition: color 0.6s, background 0.6s;
}
}
/*
Enables <iframe> support work on itch.io when using mobile iOS
*/
.outerContainer {
position: absolute;
display: block;
margin: 0;
padding: 0;
-webkit-overflow-scrolling: touch;
overflow: scroll;
overflow-x: hidden;
height: 100%;
width: 100%;
top: 0;
left: 0;
margin-top: 24px;
background-size: cover;
background-repeat: no-repeat;
@media screen and (max-width: 980px) {
margin-top: 44px;
background-size: cover;
background-repeat: no-repeat;
}
}
.container {
display: block;
max-width: 600px;
margin: 0 auto;
padding: 20px;
padding-top: 4em;
background: white;
.hide {
opacity: 0.0;
}
.invisible {
display: none;
}
> * {
opacity: 1.0;
@media screen and (prefers-reduced-motion: no-preference) {
transition: opacity 1.0s;
}
}
}
@media screen and (prefers-reduced-motion: no-preference) {
.switched .container {
transition: background-color 0.6s;
}
}
p {
font-size: 16pt;
color: #888;
line-height: 1.7em;
font-weight: lighter;
}
a {
font-weight: 700;
color: #b97c2c;
font-family: sans-serif;
text-decoration: none;
&:hover {
color: black;
}
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s;
&:hover {
transition: color 0.1s;
}
}
}
.unclickable {
font-weight: 700;
color: #4f3411;
font-family: sans-serif;
text-decoration: none;
cursor: not-allowed;
}
strong {
color: black;
font-weight: bold;
}
img {
display: block;
margin: 0 auto;
max-width: 100%;
}
/*
Class applied to all choices
(Will always appear inside <p> element by default.)
*/
.choice {
text-align: center;
line-height: 1.7em;
&:first-of-type {
padding-top: 1em;
}
/*
Class applied to choice links
*/
a, span {
font-size: 15pt;
}
}
/*
Built-in class:
The End # CLASS: end
*/
.end {
text-align: center;
font-weight: bold;
color: black;
padding-top: 20px;
padding-bottom: 20px;
}
#controls {
z-index: 4;
font-size: 9pt;
text-align: center;
padding-bottom: 6px;
position: fixed;
right: 14px;
top: 4px;
user-select: none;
background: white;
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s, background 0.6s;
}
@media screen and (max-width: 980px) {
z-index: 2;
padding-top: 24px;
top: 0;
left: 0;
right: 0;
}
[disabled] {
color: #ccc;
}
> *:not(:last-child):after {
content: " | ";
}
}
/*
Dark Theme (Added in Inky 0.10.0)
# theme: dark
*/
body.dark {
background: black;
color: white;
h2 {
color: #666;
}
.container {
background: black;
}
.written-in-ink {
background: black;
}
a {
color: #cc8f1a;
@media screen and (prefers-reduced-motion: no-preference) {
transition: color 0.6s;
}
&:hover {
color: white;
}
}
.unclickable {
color: #c4af87;
cursor:not-allowed;
}
strong {
color: white;
}
#controls {
background: black;
[disabled] {
color: #444;
}
}
.end {
color: white;
}
}

5
src/styles/story.scss Normal file
View File

@ -0,0 +1,5 @@
.disclaimer {
font-variant: small-caps;
font-style: italic;
text-align: justify;
}

View File

@ -1,18 +1,85 @@
# author: Matteo Settenvini # author: Matteo Settenvini
-> intro VAR stat_assertiveness = 0
VAR stat_empathy = 0
-> disclaimer
=== disclaimer ===
This is a work of fiction. Names, characters, businesses, places, events, locales, and incidents are either the products of the authors imagination or used in a fictitious manner. Any resemblance to actual persons, living or dead, or actual events is purely coincidental. # CLASS: disclaimer
+ [Understood] # CLEAR: -> intro
=== intro === === intro ===
We were thinking that. And again, and again. The alarm clock rings hell's bells.
+ Maybe yes -> ending * Be nice. -> ending
+ Maybe not -> intro ~ stat_empathy++
* Be naughty. -> ending
-> ending
=== ending === === ending ===
Goodbye then. You have reached the end.
{ print_stat("{~empathy|love}", stat_empathy) }
-> END -> END
// ------------ HELPER functions ------------------
=== function print_stat(name, stat) ====
You {~have used|decided to employ} the power of {name} {print_num(stat)} time{stat != 1:s}.
=== function print_num(x) ===
{
- x >= 1000:
{print_num(x / 1000)} thousand { x mod 1000 > 0:{print_num(x mod 1000)}}
- x >= 100:
{print_num(x / 100)} hundred { x mod 100 > 0:and {print_num(x mod 100)}}
- x == 0:
zero
- else:
{ x >= 20:
{ x / 10:
- 2: twenty
- 3: thirty
- 4: forty
- 5: fifty
- 6: sixty
- 7: seventy
- 8: eighty
- 9: ninety
}
{ x mod 10 > 0:<>-<>}
}
{ x < 10 || x > 20:
{ x mod 10:
- 1: one
- 2: two
- 3: three
- 4: four
- 5: five
- 6: six
- 7: seven
- 8: eight
- 9: nine
}
- else:
{ x:
- 10: ten
- 11: eleven
- 12: twelve
- 13: thirteen
- 14: fourteen
- 15: fifteen
- 16: sixteen
- 17: seventeen
- 18: eighteen
- 19: nineteen
}
}
}

View File

@ -0,0 +1,29 @@
{
"folders": [
{
"name": "Ink Story",
"path": "story"
},
{
"name": "WebPack Sources",
"path": "src"
},
{
"name": "Toplevel",
"path": "."
}
],
"extensions": {
"recommendations": [
"ban.spellright"
]
},
"settings": {
"spellright.language": ["en-US"],
"[plaintext]": {
"editor.wordWrap": "bounded",
"editor.wordWrapColumn": 80
}
}
}