Coder Social home page Coder Social logo

ludonarrative / storyassembler Goto Github PK

View Code? Open in Web Editor NEW
52.0 10.0 3.0 12.97 MB

StoryAssembler: a dynamic choice-based narrative generation engine

License: Other

HTML 8.75% JavaScript 88.57% CSS 2.67%
narrative-generation narrative narrative-game

storyassembler's Issues

refactor dynamic scene selection to be more user-friendly

This currently lives in Coordinator.getNextScene()

Right now you'd have to manually insert your logic in there on a per-project basis. It'd be better if:

  1. We establish as a convention that State variables with the "sys_" prefix are for StoryAssembler (add to documentation)
  2. We automatically set "sys_nextScene" in StoryAssembler code to the scene id of the next one in the array before running any fragments (by default it goes to the next one in the list)
  3. In Coordinator.getNextScene(), change it so that it uses that value for next scene
  4. Put in docs that the way you conditionally control that is by setting "sys_nextScene"

Is that all for the demo?

Was expecting to see some cool dynamic story but instead got a dialog with "go left" or "go right" the end. Did I miss something here?

De-couple scene id needed for "begin" link from text entered on scene description

Currently, if you want to start a scene in timeline view, you have to make sure in the scene's config field "descriptionText" you have a link like this:

<a href='#' class='beginScene' id='begin-testScene2'>Begin Scene</a>

At the very least, we should only require that a link with 'beginScene' class is in it...setting the id of the scene to begin off the text value of the link's id (Display.js:606) is...horrible.

Add Template to allow "choices" as in-line hyperlinks

Template should be written as _link/1/, which should display in that spot the display text of choice 1. Choice 1 should then be hidden from being shown, and all clickEvents registered to clicking that choice should instead fire when the hyperlink is clicked.

Wishlists can have longer length than actual length??

To reproduce:

  1. Play through a full scene (Example2) by clicking the scene link (not Begin)
  2. Return to main menu

In populateKnobs() when it checks length of wishlist for if (sceneSpec.wishlist[x].condition.includes("[")) the length is 19 but there's only 14 entries???

Refactor / consolidate per-scene data into one scene JSON file

Where the data live now

(getStorySpec)

id
year
characters (dictionary with props "name", "nickname", "gender")
wishlist (array)
dataFiles (array)
startState (string array)
UIvars (obj array, props: varName, label, characters, affectedBy, range)
mode (obj, props: type, initiator, responder) -this might only be used when we say we want to label speakers and that's buggy???

(loadNoPathFallback)

id
text (fallback text to display if scene can't continue but we're in release mode)

(loadSceneIntro)

id
text (intro text for each scene)

(loadBackground)

id
src (location of background image for scene)

(loadAvatars)

sceneId
characters
-id
-graphics (which graphics pack to use)
-age (actually just used to delineate graphics pack)
-states (state conditions paired with avatars for those conditions)

we should probably get rid of graphics and age, and instead use an explicit "src" prop in states with the full filename

Click functions should be bound in timeline view for shimmer text.

var setUISceneContent in Display.js is the function I'm primarily looking at...

...essentially it looks like a bunch of the timeline functions got mutated into graphView, then when graphView got ripped out it ripped out the stuff that made timeline stuff work.

Use the canonical version or go back in history of Display.js to figure out best way to re-factor this to preserve the stuff we want (shimmerText, possibly config knobs???) but not get all the other graph stuff.

Expose max_depth as a Coordinator parameter

All the code is in there to route it correctly, we just don't mess with it. Update docs and tell people that setting it high can result in choices taking a long time, etc etc.

Formalize state cleanup between scenes

Currently there are lots of state variables from playthrough initialization (scenes, etc) that don't get cleared out or reset between scenes. We need to formalize our approach and add in that functionality (was custom-coded in Emma's Journey and then ripped out when we pulled the library out).

  1. We should add in syntax for state variables to persist between scenes or even between playthroughs
  2. What should be the default? What is the least likely to cause subtle bugs that are hard for authors to figure out?

textClickFuncs should be moved to its own file

Currently textClickFuncs lives ~line 295 in Display.js, and contains all the click functions bound to shimmer wishlist text. Instead it should live in its own file.

We can keep the syntax of {shimmer|shimmerFunctionName|initialValue} inline for scene descriptions...that's pretty good.

refactor so non-determinism assembly is exposed as config

Currently StoryAssembler picks the first item in the list of valid items returned, which makes it 100% deterministic (which is good for debugging).

Factor it out though, so it can be exposed as a scene config. It's an easy way to make the system way more dynamic.

Re-enable automatic speaker selection

Essentially deactivated for now (if not present in config, defaults to monologue, which doesn't really do anything currently) but there's a deactivated StoryAssembler to automatically pick fragments based on who the speaker is as well. This feature was implemented back in...2017? 2016? Then it was abandoned and drifted into "deactivation-by-code-never-executed" over time. It used to have three different modes (narration, monologue, dialogue) and would prioritize fragments that allowed the normal exchange to continue.

Currently you'd need to add

"mode" : {			//what mode dialogue exchange takes place in for the scene
   "type": "dialogue",		//can be dialogue or monologue
   "initiator": "friend1",
   "responder": "protagonist"
},

to your config file, and make sure each fragment has a speaker.

This could probably also come back integrated in with the avatar stuff, as that seems to be where a lot of character logic-y stuff is now.

Add onClick capability to templates

Currently hacked into Display.js, but render should be changed from returning just a string to returning
{ text: "some text", onClicks: [{id:"span1", onClick:function deedle() } ] }

and then appending the onClick functions to a placeholder in processTemplate().

Then at the very end, it should by default replace the text with .text property, but should check for onClicks and if the array has stuff, cycle through searching and add them to the elements?

Clean up localstorage usage

Right now there are a lot of straggling localstorage/State keys that aren't being used. Once we split out the repo, need to remove the chaff.

Re-architecture: get rid of require.js / streamline includes

The whole "mapping a json file to a string alias and then putting that alias in an array of strings at the top of Coordinator in the proper order" is a total nightmare.

We might be able to do away with this and re-factor it using ES6 classes (probably most hygienic way?)

Key requirements:

  1. Doesn't introduce weird loading bugs for long file parsing, etc (test with large scenes)
  2. Doesn't require you to type strings in multiple places in the correct order.

Refactor hooks for dynamically changing wishlist items before scenes start

Currently there are two approaches:

Display.createKnobs() : makes HTML elements (sliders)
Display.populateKnobs() : actually put in values and binder functions based on dynamic wishlist DSL
Display.processWishlistSettings() : process knob values and do string replacements on dynamic wishlist items

Display.createShimmers() : makes HTML elements (shimmerSpan) and sets values in localStorage
Display.processWishlistShimmers() : takes localStorage values and does string replacements on dynamic wishlist items

I propose that we should re-factor so that we use a #2 approach, and for #1 roll createKnobs() and populateKnobs() together into createKnobs(), and change their function so that they're writing to localStorage. Then we use processWishlistShimmers() approach for finalizing in both cases. This way we can demonstrate two UI approaches to hooking into dynamic wishlists.

re-architecture: Coordinator.startScene(), StoryAssembler.continueScene() should be abstracted

We need to further separate (MVC-style) the module dependencies so that all the stuff specific to our displays is done independently of the data structures of Coordinator, etc.

Ideally, it should probably go like:

  1. Coordinator.init()
  2. do stuff with data properties now set in Coordinator for scene title screens
  3. Coordinator.startScene(_Coordinator, playGameScenes[0], true); is called
  4. Some kind of JS object is returned from that
  5. kick off stuff with that, keying off StoryAssembler.handleChoiceSelection() ????

Use cases we need to handle:

  1. Our two display templates retaining all functionality
  2. It being as painless as possible to create new templates (piping in choices, etc)
  3. It being as painless as possible to run StoryAssembler headless, to facilitate the testing harness, data viz, and any other shenanigans.

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.