Howdy, Stranger!

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

Sugarcube: Macros and music!

All right, amateur user of Twine here. I just implemented Sugarcube and I am trying to learn the ins-and-outs of it. But what I do not understand is how macros work. I've looked at about two pages of Google search results and nothing seems to work.

The instructions seem clear. Open up a new script passage, paste the text, and it should work. Yet it never works for me. Or at the very least, the macro to have YouTube music playing in the background.

L's sound macro is a bit complicated for me since it does require the actual mp3 files, not to mention once I put my game up on the internet on a free website I'm gonna have to work a bit to have the music or sound work for the game.

So, can anyone explain in a simple step-by-step way how to implement this macro into my (Sugarcube) game, and how to get it working?

And no, links to other posts won't do as a reply. I've seen a lot of them. Spent an entire day looking for simple comprehensible directions but none work.

Help will be greatly, greatly appreciated!

Comments

  • In theory, all you should have to do is change line 17 from this:

    div = document.getElementById("storeArea").firstChild,
    To this:

    div = document.getElementById("store-area").firstChild,
    You'll also have to host the file someplace as the as the Flash player restricts calls between locally loaded files and the internet.
  • Actually, that script has a few issues.  Here's one that should work for both the vanilla headers and SugarCube.  Just create a new script passage and dump this into it:

    (function () {
    "use strict";
    version.extensions['youtubeAudioMacros'] = {
    major : 3
    , minor : 0
    , revision : 0
    };
    if (window.location.protocol !== "file:")
    {
    var ytplayers = {}
    , videocount = 0
    , readyBuffer = {}
    , swfscript = document.createElement("script")
    , isSugarCube = ("title" in version && version.title === "SugarCube");
    swfscript.src = "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js";
    swfscript.onreadystatechange = swfscript.onload = function () {
    function newPlayer(hash)
    {
    var id = "YouTube-" + hash;
    insertElement(document.body, "object", id);
    swfobject.embedSWF("http://www.youtube.com/apiplayer?version=3&enablejsapi=1&playerapiid=" + hash
    , id, "0", "0", "8", null, null
    , {
    allowScriptAccess : "always"
    , wmode : "transparent"
    , modestbranding : "1"
    , version : "3"
    }
    , { id: "ytplayer-" + hash }
    );
    }

    var re = new RegExp("(?:play|loop)bgm\\s+([\"']?)([\\w-]+)\\1", "gi")
    , store = document.getElementById(isSugarCube ? "store-area" : "storeArea").firstChild
    , done = []
    , match;
    while (store)
    {
    if (store.getAttribute("tags").search(/(?:script|stylesheet)/i) === -1)
    {
    while ((match = re.exec(store.textContent)) !== null)
    {
    var ytid = match[2];
    if (done.indexOf(ytid) === -1)
    {
    newPlayer(ytid);
    done.push(ytid);
    }
    }
    }
    store = store.nextSibling;
    };
    };
    document.head.appendChild(swfscript);
    window.onYTAudioError = function (eid) {
    var errmsg = "There is a problem with the YouTube video";
    switch (eid)
    {
    case 2:
    errmsg += ": The video ID is invalid";
    break;
    case 100:
    errmsg += ": The requested video was not found";
    break;
    case 101:
    /* FALL-THROUGH */
    case 150:
    errmsg += ": The requested video cannot be embedded";
    break;
    }
    errmsg += ".";
    console.log(errmsg);
    window.alert(errmsg);
    };
    window.onYouTubePlayerReady = function (hash) {
    var yt = ytplayers[hash] = document.getElementById("ytplayer-" + hash);
    yt.style.visibility = "hidden";
    yt.addEventListener("onError", "onYTAudioError");
    yt.mute();
    yt.loadVideoById(hash, 0);
    yt.LOAD = true;
    videocount++;
    window["onYTAudioStateChange_" + videocount] = function (newState) {
    if (newState === 1 && yt.LOAD)
    {
    yt.pauseVideo();
    yt.unMute();
    yt.LOAD = false;
    while (readyBuffer[hash].length > 0)
    {
    readyBuffer[hash].shift()(yt);
    }
    }
    if (newState === 0 && yt.LOOP)
    {
    yt.playVideo();
    }
    };
    yt.addEventListener("onStateChange", "onYTAudioStateChange_" + videocount);
    };
    ["playbgm", "loopbgm", "stopbgm", "pausebgm", "unloopbgm"].forEach(function(name) {
    macros[name] =
    {
    handler: function (place, macroName, params, parser)
    {
    if (params.length === 0)
    {
    throwError(place, "<<" + macroName + ">>: missing youtube video ID argument", isSugarCube ? null : parser.fullMatch());
    return;
    }

    var yt
    , fn
    , ytid = params[0]
    , seek = (params.length > 1) ? params[1] : false;

    if (ytid)
    {
    yt = ytplayers[ytid];
    switch (macroName)
    {
    case "playbgm":
    case "loopbgm":
    fn = function(yt) {
    yt.LOOP = (macroName === "loopbgm");
    if (seek) { yt.seekTo(seek); }
    yt.playVideo();
    };
    break;
    case "stopbgm":
    fn = function(yt) { yt.stopVideo(); };
    break;
    case "pausebgm":
    fn = function(yt) { yt.stopVideo(); };
    break;
    case "unloopbgm":
    fn = function(yt) { yt.LOOP = false; };
    break;
    }
    if (fn)
    {
    if (!yt || yt.LOAD)
    {
    readyBuffer[ytid] = readyBuffer[ytid] || [];
    readyBuffer[ytid].push(fn);
    }
    else
    {
    fn(yt);
    }
    }
    }
    }
    };
    });
    }
    else
    {
    ["playbgm", "loopbgm", "stopbgm", "pausebgm", "unloopbgm"].forEach(function(name) {
    macros[name] = { handler: function () { /* noop */ } };
    });
    console.log("Apologies, YouTube audio is not supported for locally loaded files and has been disabled for this session.");
    window.alert("Apologies, YouTube audio is not supported for locally loaded files and has been disabled for this session.");
    }
    }());
    Macro usage is the same as in Leon's version.

    Well, this version also allows you to quote the YouTube ID's if you wished to.  For example:

    <<playbgm "jb3CbInIPYw">>
    <<playbgm 'jh3_LtaOxqQ'>>
    <<playbgm DDQfCGb-iOw>>
    Other than that though, they're the same usage wise.

    The same restrictions apply:
    • The player will have to have flash installed and enabled in their browser.
    • Local usage is verboten, so you'll have to host the compiled Twine game/story file someplace.
  • You're a saint, thank you so much.
  • Hmm... If the YouTube thing doesn't work out, I should use mp3 files instead. But I have no idea how they work when you're trying to host them on a site like, say, Neocities or something.
Sign In or Register to comment.