Howdy, Stranger!

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

Some custom macros and scripts for SugarCube 2

edited June 11 in Chit-Chat
I've made a bunch of custom macros and systems for SugarCube for my own games and for practice, and figured I might as well throw them up on the internet for others to use. The hardest part of doing that was painstakingly documenting and testing everything, but now that that's finished, I think I've whipped up a pretty nice set of scripts here.

Custom Macro Collection

A pretty large collection of macros and systems. Includes:
  • Simple Inventory: Just a real basic array-based inventory. Nothing crazy, but I tried to make is easy to understand and implement/extend.
  • Cycles System: My pride and joy. Allows you to define 'cycles,' which can be anything from day/night, to days of the week, to turns in a strategy game. You define a cycle, give it a number of values, and tell it how often you want it to change, and you can use a large collection of macros, functions, and passage tags to fine-tune everything. You can have any number of cycles running simultaneously, but I did notice a performance hit when I stress-tested it with around 50 going at once, so be reasonable.
  • Play Time: Just a simple little script and associated macro for tracking play time in hours:minutes:seconds, like in a video game.
  • Fading Macros: Macros for fading text or other elements in and out. A bit easier to implement than CSS or jQuery if you're only after a simple fade. You can set the length of the animation and an optional delay.
  • Dialog API Macros: I got sick of writing it all out with the script macros and such, so I wrote two macros to automate the process.
  • First Macro: A macro I wrote in response to a question over on the Q&A that works as a replacement for <<if visited()>> and <<switch visited()>>, and kind of works like Leon's <<once>> macro. Not necessary, but I started using it myself and figured I'd include it.
  • Message Macro: One of my first macros; I needed assistance from TME to complete it, which he graciously gave. Creates a link that shows and hides it's content on the next line; basically a toggle-able <<linkappend>>.

I also made a volume control slider macro, which controls SugarCube's audio macro volume in real-time. It can be found here. And I made a script for activating links and buttons on key press, an updated version of something I posted a few months ago--it can be found here.

Anyway, I went back and forth on whether I should post this stuff, but ultimately, with this forum closing down in a few weeks, I just went for it. I am not a great programmer--there are almost certainly bugs, head-scratching decisions, and other issues, and I'm grateful for feedback on any weirdness you see.

Comments

  • This is some SCHWEET SCHTUFF! Will probably use your Inventory and Cycles and maybe Fading and Message.

    That First macro came from my question, didn't it? Now I'm wondering if it's possible to have multiple Firsts in one passage, and have them count their own 'first' states independently, but that would probably require some sort of ID registry.

    Anyway, nice work!
  • I added a consumable-style inventory system (I've been seeing a few floating around and wanted to take a crack at it) and a couple other assorted macros. I think the consumables system is pretty solid, though a bit confusing at first.
    This is some SCHWEET SCHTUFF! Will probably use your Inventory and Cycles and maybe Fading and Message.

    That First macro came from my question, didn't it? Now I'm wondering if it's possible to have multiple Firsts in one passage, and have them count their own 'first' states independently, but that would probably require some sort of ID registry.

    Anyway, nice work!

    Thanks. Yeah the <<first>> macro came from your question. I started using it myself quite a bit, and while it isn't as flexible as some other options, that's sort of the point of macros, in my opinion.

    I imagine it's possible to write a version of the macro that would allow multiple <<first>>s in one passage, but by the time the dust had settled, I feel like you'd just wind up reinventing the wheel and having a system that is literally just setting variables for you.
  • @Chapel Hey! So I've been using some of your macros, and they're awesome! I've focused more on the Dialog API ones, and I was wondering some things... (please note that I'm still relatively new at everything programming and css related).

    My question, first of all, is if it's possible to style the popup windows. As of now, they're grey boxes and I was wondering if I could do something in css, like add a tag that could be applied to them. (I tried, but was unsuccessful) -- What would I have to write in the stylesheet?

    Also, I'm using, in the popup windows, this code, in order to create sort of status bars for certain variables:
    <<set $max=10>><<print "<ul style='list-style:none; width:50%;'>" 
    + "<li style='background:green; width: " +     $npcs["barkeeper"].aff       + "%;' >" + $npcs["barkeeper"].aff + "   </li>" 
    + "</ul>" >>
    

    Now, I know this is not related to your macros exactly, but it seems that once I use it inside the popup windows, something goes wrong-- they become kind of compressed, instead of appearing as normal sized bars... I'm sorry if this is confusing... I was just wondering if there was something I should add to the code considering the specific size of the popup window...
    I'm attaching two pics with what the bars, using this code, usually look like in the rest of my game, and how they look inside of the popup windows. If you have any idea what I could be doing wrong I would be incredibly grateful.

    Also, cheers on your compilation of macros, it really is a work of beauty.
    normal.png
    3000 x 1875 - 589K
    popup.png
    1920 x 1200 - 88K
  • edited July 5
    My question, first of all, is if it's possible to style the popup windows. As of now, they're grey boxes and I was wondering if I could do something in css, like add a tag that could be applied to them. (I tried, but was unsuccessful) -- What would I have to write in the stylesheet?

    You can style the dialog system in one of three ways, based on your needs:

    Method 1:
    Style SugarCube's built-in dialog boxes. You can use the '#ui-dialog-titlebar' and '#ui-dialog-body' selectors to style all dialog boxes in your game. When I say all dialog boxes I mean it--even the SugarCube defaults, like the Saves menu.
    #ui-dialog-body { color: red; }
    

    Method 2:
    Style the dialog boxes created by my macros. The <<dialog>> macro and the <<popup>> macro always have the classes '.macro-dialog' and '.macro-popup' respectively. Changing these selectors in your CSS will change the dialog boxes created by the associated macro, but won't alter SugarCube's built-in menus.
    .macro-dialog, .macro-popup { color: red; }
    

    Method 3:
    Provide your own classes to the macros and use them for styling:
    <<dialog 'Box's Title' 'my-class' 'another-class'>>...<<dialog>>
    <<popup 'passage' 'title' 'some-class'>>
    

    In CSS:
    .my-class { background-color: white; }
    .another-class { color: black; }
    .some-class { color: pink; }
    

    Use this method if you want to boxes that perform different functions or contain different information to look different.
    Now, I know this is not related to your macros exactly, but it seems that once I use it inside the popup windows, something goes wrong-- they become kind of compressed, instead of appearing as normal sized bars... I'm sorry if this is confusing... I was just wondering if there was something I should add to the code considering the specific size of the popup window...

    I made a couple edits to your bar to make it bigger. The problem here is probably the width:X% lines--X% of a tiny dialog box is a very small space. Does this look better to you?
    <<print "<ul style='list-style:none; background-color:#000; padding:0; margin:0; '>" 
    + "<li style='padding:0 1em; margin:0; background:green; width: " +     $npcs["barkeeper"].aff       + "%;' >" + $npcs["barkeeper"].aff + "   </li>" 
    + "</ul>" >>
    
    Also, cheers on your compilation of macros, it really is a work of beauty.

    Thank you.
  • edited July 5
    @Chapel Thanks for your help, it's exactly what I needed! And the upgrade on the bars, does work much better!

    Since I got you, could I ask, visually, is there a way to make the the limits of the bar be fixed, and then the inside change with the variable? Instead of it just being a bar going up and down, with no apparent limit (even though the variable does have a limit).
  • Correction: regarding the bars, they do look much better (they are not compressed), but they don't seem proportional to they're value. It's probably something I did wrong. Do you know how I could, in this code, establish the max value for the variable, so that the bar looked accordingly? Thanks again :)
  • Jajajewels wrote: »
    Since I got you, could I ask, visually, is there a way to make the the limits of the bar be fixed, and then the inside change with the variable? Instead of it just being a bar going up and down, with no apparent limit (even though the variable does have a limit).

    You could use some division to turn the value of your bar into a percentage:
    Math.trunc($value / $maxValue * 100)
    
    Math.trunc(7 / 10 *100) /* =70 */
    

    So:
    <<print "<ul style='list-style:none; background-color:#000; padding:0; margin:0; '>" 
    + "<li style='padding:0 1em; margin:0; background:green; width: " +     Math.trunc($npcs["barkeeper"].aff / 10 * 100)       + "%;' >" + $npcs["barkeeper"].aff + "   </li>" 
    + "</ul>" >>
    

    ...or something.

    It might be easier to create a function to handle this for you:

    In JavaScript
    setup.createBar = function (val, max, loc, width) {
    	var $wrapper = $(document.createElement('ul'));
    	var $bar     = $(document.createElement('li'));
    	var actual   = (val > 0) ? Math.trunc(val / max * 100) : 0;
    	
    	$bar
    		.addClass('bar-actual')
    		.css('width', actual + '%')
    		.wiki(val);
    	
    	$wrapper
    		.addClass('bar-container')
    		.append($bar)
    	
    	if (width) {
    		$wrapper.css('width', width);
    	}
    	
    	postdisplay['create-bar-task'] = function (t) {
    		$(loc).append($wrapper);
    		delete postdisplay[t];
    	};
    };
    

    In CSS:
    .bar-container {
      list-style: none;
      background-color: #000; /* maybe? */
      padding: 0;
      margin: 0;
    }
    
    .bar-actual {
      padding: 0 1em;
      margin: 0;
      background-color: green;
      width: 0;
    }
    

    Usage:
    <span id='target'></span> /% the bar will be rendered here, into this element %/
    <<run setup.createBar(value, maxValue, '#target', [optional: width])>>
    
    For example, in your dialog/popup box, put this:
    <span id='bar-location'></span>\
    <<run setup.createBar($npcs["barkeeper"].aff, 10, '#bar-location')>>
    
    In your story (outside the dialog), put this:
    <span id='health-bar'></span>\
    <<run setup.createBar($health, 100, '#health-bar', '50%')>>
    

    This will give you one short chunk of code to use for both cases, and you don't have to use <<print>> to parse the element out.
  • edited July 9
    I've also been using the hell out of these, in particular the consumables system. So useful!! Thank you so much for posting.

    I had a few questions about altering the code tho... I found how to modify the display of <<listconsumables>> easily enough, but I'm having trouble locating the line where I can modify the display of <<usableconsumables>> to delete the colon, as I want only parenthetical numbers if possible. (see screenshot) Please ignore that I changed the text of the use-link. ;)

    I also wondered if it was possible for the item to disappear instantly from the list once the amount reaches 0 -- it looks a little strange to still have the item sitting there, waiting to be used, when there aren't any left.

    And finally, back to <<listconsumables>>. In the example on your GitHub page, the comma separator only shows up for the first two items. For me, however, the comma separator shows up for all items. (see screenshot) How can I alter the code so that the final item has no separator applied to it?

    Sorry if this is a lot to ask! I really appreciate your posting this. I can't wait to use the cycles system after this.
  • edited July 9
    litrouke wrote: »
    ...I'm having trouble locating the line where I can modify the display of <<usableconsumables>> to delete the colon, as I want only parenthetical numbers if possible. (see screenshot) Please ignore that I changed the text of the use-link. ;)

    Toward the bottom of the <<usableconsumables>> macro, there should be a chunk of code that looks like this:
    $wrapper
        .append($descr)
        .wiki(': <span id="' + itemID + '">' + item.amt + '</span> ')
        .append($link)
        .wiki('<br />');
    

    That first .wiki() method contains the colon you want to delete, right at the start, after the opening quote--it's definitely a little hard to see.
    litrouke wrote: »
    I also wondered if it was possible for the item to disappear instantly from the list once the amount reaches 0 -- it looks a little strange to still have the item sitting there, waiting to be used, when there aren't any left.

    Yeah, I've been trying to think up ways to do this without having to re-render the whole macro. Right now I just don't have a great solution. Here's a not great one, though:

    Find this section of code:
    $link
        .wiki('Use')
        .addClass('use-link macro-usableconsumables')
        .attr('id', itemID + '-use')
        .ariaClick( function () {
            // on click, fire useconsumable macro in silent mode
            new Wikifier(null, '<<useconsumable "' + item.id + '" "silent">>');
            $('#' + itemID).empty().wiki(item.amt);
        });
    

    And change it to this:
    $link
        .wiki('Use')
        .addClass('use-link macro-usableconsumables')
        .attr('id', itemID + '-use')
        .ariaClick( function () {
            // on click, fire useconsumable macro in silent mode
            new Wikifier(null, '<<useconsumable "' + item.id + '" "silent">>');
            $('#consumablemenu').empty().wiki('<<usableconsumables>>');
        });
    

    Then, in your menu (or wherever you call the <<usableconsumables>> macro), wrap it in a span like this:
    <span id='consumablemenu'><<usableconsumables>></span>
    

    There's nothing wrong with this solution per se, it's just inelegant and wasteful. Check the repository periodically; when I come up with something better, I'll post an update.
    litrouke wrote: »
    And finally, back to <<listconsumables>>. In the example on your GitHub page, the comma separator only shows up for the first two items. For me, however, the comma separator shows up for all items. (see screenshot) How can I alter the code so that the final item has no separator applied to it?

    That's a bug. Thanks for the catch. I'll update the repo with a fix soon. In the meantime, if you want, you can locate this chunk of code in the <<listconsumables>> macro:
    // check for consumables
    if (conRef.carried.length > 0) {
        // create list
        conRef.carried.forEach( function (id) {
            var item = conRef[id];
            content = content + item.name + ': ' + item.amt + sep;
        });
    } else {
        // no carried consumables
        content = setup.consumables.options.emptyMsg;
    }
    

    And change it to this:
    // check for consumables
    if (conRef.carried.length > 0) {
        // create list
        conRef.carried.forEach( function (id, idx, arr) {
            var item = conRef[id];
            content = content + item.name + ': ' + item.amt;
            // omit separator if item is last consumable
            content = (idx === arr.length - 1) ? content : content + sep;
        });
    } else {
        // no carried consumables
        content = setup.consumables.options.emptyMsg;
    }
    
    litrouke wrote: »
    Sorry if this is a lot to ask! I really appreciate your posting this. I can't wait to use the cycles system after this.

    I'm glad you're getting use out of it. Honestly, catching bugs is incredibly helpful, so keep it up and let me know if you see anything in the cycles system when you try it out or if you have any questions.

    Edited for some typos.
  • Thank you so very much! I'm so sad this forum is closing in a few days, because resources like this are a godsend (and being able to talk with the code's author directly instead of banging my head against the wall for not being able to locate a silly colon ;) ). I would love if the new Questions site also implemented a sister Resources site, or something like that.... alas. I didn't see any way to directly communicate with members on the Questions site either.

    Anyway, thank you again! You are very generous to post all these, and I really appreciate it.
  • litrouke wrote: »
    ... also implemented a sister Resources site, or something like that
    There is the Twine Wiki which could possible be used to reference resources like Chapel's custom macros and scripts, it unfortunately wouldn't allow you to converse with their developer(s) but you could use the Q/A site for that.
  • litrouke wrote: »
    ... I'm so sad this forum is closing in a few days, because resources like this are a godsend (and being able to talk with the code's author directly instead of banging my head against the wall for not being able to locate a silly colon ;) ). I would love if the new Questions site also implemented a sister Resources site, or something like that...

    I'm going to miss this forum too. The Q&A site makes sense, since 90% of the posts on this forum do tend to boil down to technical questions, but it is sad to lose this place.

    greyelf wrote: »
    There is the Twine Wiki which could possible be used to reference resources like Chapel's custom macros and scripts...

    I might just be an idiot, but I have a lot of trouble navigating the wiki. It seems like there are a lot of resources and pages that exist, but are hard to access, almost like you have to know which series of links to click on advance.
  • edited July 12
    Chapel wrote: »
    I'm going to miss this forum too. The Q&A site makes sense, since 90% of the posts on this forum do tend to boil down to technical questions, but it is sad to lose this place.

    I've found some wonderful works here that inspired me to add new features to my own stories, and I'm sad to lose that part especially. I know there are other IF gathering places, but they tend to be heavier on the parser/traditional IF side, whereas I feel like Twine games range all over the place in their inspiration and execution.

    Chapel wrote: »
    I might just be an idiot, but I have a lot of trouble navigating the wiki. It seems like there are a lot of resources and pages that exist, but are hard to access, almost like you have to know which series of links to click on advance.

    I ghostwrote this response haha. I almost always google 'twine' + story format + search term rather than trying to scour the wiki for the page I know is there. The wiki is an interactive text adventure of its own ;)
Sign In or Register to comment.