Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

multi-pane twine game layout

xaxxax
edited January 2014 in Workshop
a while back I got the idea to try and glom together a twine setup that would let me write a game that worked in two near-completely separate panes, where it would have two passages displayed at once, and links clicked in one wouldn't even touch the other. At the time it seemed basically impossible, given the way twine is put together, but a few days ago, after hacking with the internals of l's revision macros for a while, I had a flash of insight, and the result is, well... this:

e jan 3: Here's a working demo and here's the script. Short version: use <<pane "pane" "passage">> to create sub-passages in your story, use <<link>> to link inside a pane, use <<linkTo "pane">> to target a pane anywhere on the current passage. All these macros take variable arguments.

Comments

  • Have you taken a look at Dumb Terminal stylesheet? Thanks to HarmlessTrouble, it has two separate panes. However, maybe that's different than what yours does.
  • Yeah, I looked at that earlier -- it looks like the StoryRegions macro adds information panels, right? But they still reload with the main passage, and you can't link inside them or target links to change them (except through specific coding inside whatever StoryRegion-tagged passages you're drawing). I was after something I could use to basically make two equal "main" passage containers, with content skipping back and forth between them, which it doesn't look you can do with that very easily.
  • I see. That's cool! :)
  • Xax, can you provide the twine file? This looks awesome, but I'm having trouble figuring out how to use it. I want to add a separate pane for player inventory. At the moment I'm putting <<pane "inventorypane" "inventory">> into a passage, but that's just displaying the text from the "inventory" passage in the passage I've placed it in, like the <<display>> function, rather than making a new pane. I'm sure I'm just making a dumb mistake. Thanks!
  • Here's the twee source (sorry I don't have a .tws file, but you should be able to import that into twine somehow)

    I should specify: the styling going on in the demo is all css, and you can do that without panes. In the absence of any &lt;&lt;link&gt;&gt; macros, &lt;&lt;pane&gt;&gt; will just work like display, since it doesn't have any innate styling -- it's just a display block that you can specifically target with links to get some added interactivity.

    (ideally I'd be able to extend the link syntax to make normal links work with this, rather than forcing all links into &lt;&lt;link&gt;&gt; format, but that's still beyond me codewise)

    e: oh, and if what you're looking for is a sidebar-esque passage that floats somewhere and updates on every link, then you should check out HarmlessTrouble's code, as used in Sharpe's stylesheet, because it does that way better than this would.
  • I whipped together this macro for this thread before realizing 1. it wasn't at all what was requested and 2. it probably wouldn't work in sugarcube anyway. so i figured i might as well throw it up over here, in case anyone else can get use out of it. this is a macro for selectively updating parts of a passage, to be used in conjunction with some other macro set that gives you state-altering links, like <<click>> in SugarCube or <<revise>> in L's replacement macro set.

    this macro set provides two macros -- &lt;&lt;block&gt;&gt; and &lt;&lt;endblock&gt;&gt; -- and one function, reshow. if you want a reshow macro, just make a passage called "reshow" with the contents "&lt;&lt;set reshow (parameter(0))&gt;&gt;".

    If you have a &lt;&lt;block foo&gt;&gt;, calling reshow (&quot;foo&quot;) or &lt;&lt;reshow foo&gt;&gt; will reload the tweecode inside that block. these calls happen when the tweecode containing the reshow call is parsed, so you'll want to hide them inside of a revise/cycle/click/etc etc event, rather than something that gets parsed when the passage loads (because that could possibly lead to an infinite loop, especially if the reshow call is inside the block being reshown).

    so if you're using links to update variables that are used elsewhere in the passage, just wrap &lt;&lt;block whatever&gt;&gt;...code...&lt;&lt;endblock&gt;&gt; around the code that uses them, and then add &lt;&lt;reshow whatever&gt;&gt; inside the link action (cycle code, inside the click, etc), and they'll be updated. If you want to update the entire passage, just wrap the whole thing in a &lt;&lt;block&gt;&gt;, but note the warning about infinite loops if you put code that reloads the block inside the block, since that code is run when the block loads.

    put this code in a script passage:

    function innercontent(tag, parser) {
    var
    i,
    textbegin = parser.source.indexOf(">>",parser.matchStart)+2,
    textend = -1,
    text = parser.source.slice(textbegin),
    depth = 0;
    for (i = 0; i < text.length; i++) {
    console.log (text.substr (i, tag.length+5));
    if (text.substr(i,tag.length + 5) === ("<<end" + tag)) {
    if(depth===0){
    textend=textbegin+i;
    break;
    }else{
    depth--;
    }
    } else if (text.substr(i,tag.length + 2) === ("<<" + tag)) {
    depth++;
    }
    }
    if (textend === -1) {
    throwError(place,"can't find matching end"+tag,parser.fullMatch())
    return;
    }
    return [textbegin, textend];
    }
    macros.block = {
    handler: function (place, macroName, params, parser) {
    var class_ = params[0][0] == "$"
    ? eval(Wikifier.parse(params[0]))
    : params[0];
    var block = insertElement (null, "span", null, "blockSpan " + class_.replace(" ","_");
    var inner_index = innercontent ("block", parser);
    block.tweecode = parser.source.slice(inner_index[0], inner_index[1]);
    parser.nextMatch=inner_index[1];
    place.insertBefore(block,null);
    new Wikifier(block, block.tweecode);
    }
    };
    macros.endblock = { handler: function () {}}
    window.reshow = function (name) {
    var
    rall=document.querySelectorAll(".passage .blockSpan." + name.replace(" ","_"),
    ret=false;
    for(var i=0;i<rall.length;i++){
    ret=reshowOne(rall[i]);
    }
    return ret;
    }
    function reshowOne (target) {
    target.innerHTML="";
    new Wikifier(target,target.tweecode);
    target.classList.remove("revision-span-out");
    target.classList.add("revision-span-in");
    if(target.timeout){
    clearTimeout(target.timeout);
    }
    target.timeout=setTimeout(
    function(){
    target.classList.remove("revision-span-in")
    },
    1);
    }
    if you want fancy fade-ins for updating blocks, put this into a stylesheet passage:

    .blockSpan {
    -webkit-transition: 1s;
    transition: 1s;
    }
    .blockSpanIn {
    opacity: 0;
    -webkit-transition: 0;
    transition: 0;
    }
  • Hey xax!

    Thank you so much for this macro - it is pretty close to what i'm looking for. I'm having trouble styling it though, and my sorta limited understanding of css says it is something to do with spans...but i'm not sure.

    Basically what I want to do is load a top and bottom pane, centered and with no side panel. Both panes would be a fixed size. The top pane would show images and contain a single <<set $variable ="whatever">>, and the bottom pane would display multiple choice passages. When a choice is made the top pane adds a new image (on top of the other ones, they have transparency) based on the choice, and the bottom pane shows a new set of choices.

    I can remove the side panel fine, and I have it working so that the top pane displays text based on the choices in the bottom pane, but I can't work out how to keep the sizes of the passages fixed, and get images to stack on top of another. (though at one stage I got two images to display at the same time, but the second image is physically underneath the first) I've tried creating and tagging specific stylesheets to passages with no real luck.

    Is there anything you could suggest? Or a direction you could point me?

    Cheers in advance!

    Carly
  • Does this work for anybody? Other than the demo that is.
    I get "This passage does not exist." in both the left and right panes. Attempts to create passages and change the <<pane...>> to reference them just results in the same. It seems that the macro isn't pointing to the passage name properly. I've explored using <<pane "left" passage>>, <<pane left passage>>, <<pane "left" "passage">>, and <<pane left "passage">> as the parameters not knowing how the macro works exactly but none  of these results the passage appearing (i.e. same error). I'm using the imported Twee code as posted below with the tags corrected to match the code posted here (since the import failed to tag the passages as script, stylesheet, etc. I put these in one at a time by hand). Still even with the code from below I just get this passage error. I don't have the skills to check the macro and scripting but I did verify that each section starts and ends with the same code posted here.
    Any ideas?? Or better yet, any working .tws to start from?

    Thanks,

    Aenox
  • Oh, and in the interest of getting things working here's my novice attempt at fixing the imported Twee code posted and turning it into a .tws.
  • I'm not sure what your problem is, specifically - it's working fine for me.

    The correct syntax is <<pane "pane name" "initial passage">> - quotes around both arguments.

    pane name specifies which sub-div to display the passage in.
    initial passage selects which passage to display (by referencing its tiddler element).

    For example, if you have passages titled "Plains" and "Mood", then writing
    <<pane "left" "Plains">>\
    <<pane "right" "Mood">>
    into the Start passage will make it display the contents of "Plains" in the left pane and "Mood" in the right pane.
  • carlywight wrote:

    Hey xax!

    Thank you so much for this macro - it is pretty close to what i'm looking for. I'm having trouble styling it though, and my sorta limited understanding of css says it is something to do with spans...but i'm not sure.

    Basically what I want to do is load a top and bottom pane, centered and with no side panel. Both panes would be a fixed size. The top pane would show images and contain a single <<set $variable ="whatever">>, and the bottom pane would display multiple choice passages. When a choice is made the top pane adds a new image (on top of the other ones, they have transparency) based on the choice, and the bottom pane shows a new set of choices.

    I can remove the side panel fine, and I have it working so that the top pane displays text based on the choices in the bottom pane, but I can't work out how to keep the sizes of the passages fixed, and get images to stack on top of another. (though at one stage I got two images to display at the same time, but the second image is physically underneath the first) I've tried creating and tagging specific stylesheets to passages with no real luck.

    Is there anything you could suggest? Or a direction you could point me?

    Cheers in advance!

    Carly


    Quite late to make a reply, but I'll give it a shot. I'm new to CSS, but I think I can at least point you in the right direction.

    Panes of a fixed size:
    The obvious thing, which you likely tried, is defining the size of each pane with the height and width properties. My guess is, the amount of displayed text is changing the size of the panes. I suspect this can be resolved by fiddling with the min-height, max-height, min-width, max-width, overflow-y, overflow-x, and whitespace properties.

    Not sure what you mean about positioning images, need more information.
  • lit wrote:

    Quite late to make a reply, but I'll give it a shot. I'm new to CSS, but I think I can at least point you in the right direction.

    Panes of a fixed size:
    The obvious thing, which you likely tried, is defining the size of each pane with the height and width properties. My guess is, the amount of displayed text is changing the size of the panes. I suspect this can be resolved by fiddling with the min-height, max-height, min-width, max-width, overflow-y, overflow-x, and whitespace properties.

    Not sure what you mean about positioning images, need more information.


    Thanks lit - Even though it actually wasn't all that long ago i've actually forgotten where I was going with that. You know the saying - "Code you haven't touched in 4 weeks may as well have been written by someone else!"
    Anywho, what I ended up doing for the project I was considering this for was use absolutely positioned divs. Instead of triggering an image change when certain conditions were met I've instanced them across multiple passages and killed the default fade transition, that way you don't see the image 'reload' as you go from passage to passage. I've learnt so much about css and Twine in the last 3 months; it's crazy!
  • Hi folks. Does anyone know if there's a way to get the panes macro at the start of this thread working with L's replace/revise etc macro set? I'm trying at the moment but keep getting errors when I try to wrap a pane-based link in a timed insert. Both macros independently work fine, but combining the two like this:
    <<timedinsert 30s>><<linkTo "door" "doorSlam" "The door slams shut.">><<endtimedinsert>>
    seems to be causing some problems.

    Or alternatively, does anyone have a working demo of the blocks macro here? I'm getting unexpected token errors when I try it out.

    I'm using Sugarcane, in case the format makes a difference here.
  • Is there a chance this can work with a "dynamic" number of panels, i.e. that clicking a link could change the number of panels displayed? That is, how do you change which "outer" (pane-containing) passage is being shown?
  • chrisamaphone wrote:

    Is there a chance this can work with a "dynamic" number of panels, i.e. that clicking a link could change the number of panels displayed? That is, how do you change which "outer" (pane-containing) passage is being shown?

    I got this to work by just wrapping a link in normal Twine syntax
    [[like this]]
    but it doesn't 'remember' which passages you had displayed in which panes - you have to specify them all again in the new "outer" passage.
Sign In or Register to comment.