Random engine for people who like to use Squiffy as possible while tending to avoid Javascript

Other people have already figured this out. But sure would have made my earlier games a lot easier to write if I'd known it sooner. I hope it will help somebody who wants an easy way to handle random selections.

You just paste the [[random]] section anywhere in your game and then follow the pure-Squiffy examples to declare new random choices.

@start start

Unfortunately, this only works with one random per section.

[[start]]:
@set random = friend:Alice Liu| Bob| Cindy| Dan| Ebert| Flor| Grant| Hanna

You want some I cream. You choose a friend to [[call]](random, next=two) at random.

[[two]]:
{@random=flavor: chocolate| taro| vanilla| strawberry banana| mango}
{friend} picks up the phone.

"Sure, I could go for some ice cream. What [[kind]](random, next=three) do you want?"

[[three]]:
"I'm having {flavor} today. [[You]](random, next=You)?"

@set random = flavor1: chocolate| taro| vanilla| strawberry banana| mango

[[You]]:
@set random = flavor2: chocolate| taro| vanilla| strawberry banana| mango
@set next = You1

    squiffy.story.go("random");
    

[[You1]]:

"Uh... {flavor1}, I guess? Or{if [email protected]:... No. Yeah. {flavor2}.}{else: maybe {flavor2}?}"

[[random]]:
    var random = squiffy.get("random");
    var attribute = random.split(":")[0];
    var choice = random.split(":")[1];
    var choice = choice.split("|")[(Math.floor(Math.random()* choice.split("|").length))];
    squiffy.set(attribute, choice);

    var next = squiffy.get("next");
    squiffy.story.go(next)

Hmm... Can't figure out why it won't work inside a [[]] master section.


Oh...

I just stumbled on this post from mrangel, which appears to do this much more effectively. I can't get it to work at the moment, but I probably pasted something wrong.


I just stumbled on this post from mrangel, which appears to do this much more effectively. I can't get it to work at the moment, but I probably pasted something wrong.

(edit: typos)

I'm not sure if I tested all of that. I included some rough code off the top of my head as an example of what it could do, but I was focusing more on the means of loading code reliably in a different context. Maybe I messed something up.

I think your version has the advantage of being a lot less code :)

Hmm... Can't figure out why it won't work inside a [[]] master section.

How are you trying to include it? Could be something in the order of execution. If I remember correctly, the order is:

  1. master section @sets
  2. master section javascript
  3. master section text
  4. current section @sets
  5. current section javascript
  6. current section text

So if you're putting the JS in the master section, it will run before any attributes are set by the current section.

Hmm…

Off the top of my head, perhaps you could have the master section look at the variables set for the current section. So something like:

[[]]:
    if (squiffy.story.section.attributes) {
        var regex = /^random:\s*(\w+)\s*=\s*(.+)/i;
        var matches, attr, options;
        squiffy.story.section.attributes.forEach (line => {
            if (matches = regex.exec(line)) {
                options = matches[2].split("|");
                squiffy.set(matches[1], options[Math.floor(Math.random() * options.length)]);
            }
        });
    }

[[some random section]]:

@set random:flavor = lime|orange|cherry|roast pork and blue cheese

“Ooh, there's an ice cream shop!” Jade shrieks excitedly. “I wonder if they have {flavor} sorbet, it's my favourite!”

If you don't mind tweaking javascript, you could edit your story.js file after compiling the game; or even change this in whichever file in the Squiffy compiler contains this, so you can use it in all your games. Find this section and add piece to one line:

    squiffy.story.run = function(section) {
        if (section.clear) {
            squiffy.ui.clearScreen();
        }
        if (section.attributes) {
            processAttributes(section.attributes.map(line => line.replace(/^random\s*:\s*(\w+)\s*=\s*(.+)/i, (line, attr, options) => (options = options.split("|")) ? attr + " = " + options[Math.floor(Math.random() * options.length)] : line)));
        }
        if (section.js) {
            section.js();
        }
    };

Then you can use stuff like @set random:colour = red|green|blue|fuchsia whenever you want.
It's shorter code, and more efficient, but a little ugly.


Log in to post a reply.

Support

Forums