Howdy, Stranger!

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

JavaScript to add a passage to the "visited" list? (In SugarCube?)

I'm displaying and parsing content from certain passages outside the normal "click link to go to passage" structure. Before I dig after this any further, is there a straightforward existing method to add a passage by title to the "already visited" list? I'm using SugarCube, if that helps.

Thanks!

Comments

  • I'm doing this, and it seems to work okay.
    var last_variables = state.history[state.history.length - 1].variables;
    var last_sidx = state.history[state.history.length - 1].sidx;
    var this_state = {
    "title": passage_title,
    "variables": last_variables,
    "sidx": (last_sidx + 1)
    };
    state.history.push(this_state);
    Assumptions:
    1. I THINK "sidx" is the number of steps in the story since its start, since it seems to increment, but I can't actually see what else that actually does elsewhere.
    2. "variables" should be the same every time unless something is added or removed, correct? I could just add an additional variable and it function the same as if I had done <<set $heard_about_topics.push("oranges")>> in the body of a passage?

    Am I about to run into a huge "gotcha"? :)
  • Reading SugarCube's History API documentation I see it contains the warning:
    [quote]In general, don't access the story history state stack's storage variable (state.history) directly, use the new API.
    It also makes suggestions about using state.active and state.peek(i)

    Does your story allow the Reader to undo their choices? (eg. use the web-browser's Back button)
    If it does then I believe you may run into issues as the last item in the stack (the top) is not always the active item if the Reader has used Undo.

    Where in the History stack are you planning to add your fake history items? Before the current (active) passage's history item, before the last (top) passage's history item? etc??
    Your example appear to be adding them after the (top) passage's history, if that is so then you may be adding future passages if it is not also the current (active) passage.

    The History API code contains an undocumented state.push() method which is what History uses internally to add an item to the top of the stack.
    note: I am not sure you should be manually adding items to the History stack but if you are going to then using the same method as it does internally may be a good idea.
  • Ahhhh, good point. Thanks for that. I had only considered how it would impact the save/restore function, not back. That's something to consider before I fall too far down this path!

    I'm adding them after the (top), but now I'm going to rethink this in the context of the back button.

    Also: rest assured I know I am doing something totally hacky, and totally agree with your suggestion that IF I am actually doing this, that I should do it the exact same way as the History API.

    ("Hey, I heard you liked passages so we put a passage in your passage...")


  • nicolem wrote:
    I had only considered how it would impact the save/restore function

    Are you aware that you can influence what happens during the loads/saves via the config.saves.onLoad and config.saves.onSave callbacks.
    If you want to modify the Reader's history, that may be a better place to do it by modifying the save object before it is saved or loaded.
  • Your example code is not cloning the variable store, so that's broken.

    That said, my very strong advice is that you rethink what you're trying to do and come up with an alternate method (i.e. do not manually modify the story state history).  The story state history is, for various unfortunate reasons, complex and attempting to jam entries into it is only going to end in pain.  SugarCube's story state history has three different modes under which it may be operating (Hash, Window, and Session), determined by the capabilities of the player's browsereach of which works, at least slightly, differently.  In particular, the state objects themselves may have different properties (e.g. the stack index, sidx, is only part of state objects in Session mode) and, since the story state history itself is only half of the picture, you are bound to cause synchronization issues between the story state history and its browser state serializations (i.e. things will break, perhaps explosively, perhaps in hard to detect ways).  There are other problems as well.  So, let me reiterate, do not manually modify the story state history.

    It's possible that if you explained what you're trying to accomplish by modifying the story state history, I, or someone else, could suggest an alternate means of achieving your goal (or maybe not, but it can't hurt to see).
  • I'm pretty sure more experienced SugarCubers just read this as:

    Me: "Hey, I really liked the cake recipe you posted. I substituted dishwashing liquid for butter. Can I ask you some questions about how it turned out?"
    TheMadExile: "uh"

    Okay, okay, I am listening. :) The more I've looked at this, the more intensely bad an idea my original plan is seeming, and that's from MY position of optimism.

    Anyway, the goal here was to present the player with an "in-person" conversation with a character and to have an intrusive cell phone conversation taking place at the same time. I just typed up a big long explanation of how this would work, but in doing so, I've realized that my overthought asynchronous conversation method is not actually important to the story.

    Just sticking this in several successive otherwise identical passages accomplishes the exact same narrative effect: <div class="phone">Phone dialogue here.</div>

    ...and of course, "why don't you explain why you want that" is a tool I use at work all the time. So thank you! :)
  • Oh, and no, Greyelf, I was not aware of that! It's not quite what I was after, and I'm not sure I'm going to need it after all, but it's good to know. Thanks.
  • It sounds to me like you were simply speaking of making your own custom visited tracking. This can be easily done using <<set>> and <if> macros.

    Example that can be placed in any passage to call a phone message that only plays after you've visited 2 passages and viewed tacked on content:

    //in one passage where you are displaying content from but that the user didn't actually visit:

    This is the content I am tacking onto another passage.<<set $stealthpassagevisit to 1>>

    //then in another passage where you want the phone call to display only if you have visited 2 passages + seen the earlier tacked on content:

    <<silently>>
    <<if visited("passage 1") gte 1>><<set $passage1visit to 1>><</if>>
    <<if visited("passage 2") gte 1>><<set $passage2visit to 1>><</if>>

    <<if $passage1visit is 1 and $passage2visit is 1 and $stealthpassagevisit is 1>><<set $phone to 1>><</if>>
    <</silently>>
    <<if $phone is 1>>You've visited both passages and a hidden secret passage you didn't actually visit, you rascal<</if>>
    And you could also make this code more efficient, by collapsing the (visited) if statements into the <<set $phone to 1>> line. But I like to super expand things at first.
  • Claretta: Not quite, but weirdly, your comment on this thread is almost exactly what I wanted to do: http://twinery.org/forum/index.php/topic,2518.0.html

    So thanks!
Sign In or Register to comment.