+1 vote
by (180 points)
edited by

How do I do this but in a macro format? Instead of console logging I am looking to visit a passage if the value is false. So it isn't quite there, as this just looks for a value. I realise var will be $ and to use <<>> I am meaning how do I write the function itself as a macro.

Borrowed Stackoverflow Javascript Code

var testObj = {
    test: 'testValue',
    test1: 'testValue1',
    test2: {
        test2a: 'testValue',
        test2b: 'testValue1'

function searchObj (obj, query) {

    for (var key in obj) {
        var value = obj[key];

        if (typeof value === 'object') {
            searchObj(value, query);

        if (value === query) {
            console.log('property=' + key + ' value=' + value);



I am making an object for each location, so I can assign values to it. One of them is visited: true/false. I want the object to be removed from exploration passage(s) when it's been visited. Passages where the user discovers them at random while exploring/searching.

So I'll put all these objects in an exploration array. I don't need you to give me all that code or even the specific answer, just an idea of how to translate this particular function to a macro format. I am a newbie to macros, but a trainee in javascript (so I can handle that side of things) when I better understand macros.


2 Answers

+1 vote
by (8.6k points)
selected by
Best answer

A macro isn't a good use case for functions, and your use case seems simple enough that you don't even need a function. Assuming your $passages looks something like this and you don't need a "deep" search:

<<set $passages = {
    passage1: { visited: true, name: "Something strange" },
    passage2: { visited: false, name: "Passage 2"},
    passage3: { visited: false, name: "Another Passage", value: 42 },
    passageZ: { visited: true, name: "Don't go here" },

Then you can find a random unvisited passage key like this:

<<set _passageKey = Object.keys($passages).filter(p => !$passages[p].visited).random()>>


by (180 points)
Thank you that makes sense. Just as a quick question (to either of you)

I was looking at macros as I was not sure if standard functions could be put in twine's javascript file, outside of passages. Can they?

Though for this one the passage will work fine thanks for the code.
by (8.6k points)
If you're using Twine, there's a story javascript section where you can put any random JavaScript, including your custom functions. If you want them global, put them in window.functionName (then you can run <<set $value = functionName(...)>> or setup.functionName (run via <<set $value = setup.functionName(...)>>. The "setup" method is a bit more writing, but doesn't run the risk of collisions with other global methods and objects.

If you're using TweeGo or something like that, just put them in any "js" file and let the compiler include that file in your finished game. The same notes about window.functionName and setup.functionName apply there too.
+1 vote
by (68.6k points)
  1. Have you looked at SugarCube's Macro API?  Because I'd start with that.
  2. Will your location objects' visited property be their only property whose value is a boolean?  If not, then you need to search by property name as well, which you should probably be doing anyway, elsewise you could erroneously match one of the other boolean properties.
by (180 points)
I will have a read, thanks for the tip too. I haven't done anything searching in objects themselves before, so this was more a base to work from.