Howdy, Stranger!

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

Creating and referencing a randomly generated $objectname, is this even possible?

A character explores and discovers a village. The name of the village is randomly generated.
<<set $Random to random(0,25)>>
<<set $Text to $Alphabet[$Random]>>
<<set $Random to random(0,25) + 26>>
<<set $Text += $Alphabet[$Random]>>
<<set $Random to random(0,25) + 26>>
<<set $Text += $Alphabet[$Random]>>
<<set $Random to random(0,25) + 26>>
<<set $Text += $Alphabet[$Random]>>
<<set $Random to random(0,25) + 26>>
<<set $Text += $Alphabet[$Random]>>
<<set $Villages.push($Text)>>

Let's say it came up with the name "Codil". I would like to be able to assign Codil with a random natural resource.
<<set $Random to random(0,14)>>
<<set $Codil.Resource to $Resources[$Random]>>

Let's say Codil has good fishing so the character wants to build a hatchery there.
<<set $Codil.Hatchery to 1>>

The character continues on and finds another village called Lidoc which has rich farmland so he plants some crops.
<<set $Lidoc.Crops to 1>>

The problem I'm running into is that I'll never know the villages are called Codil or Lidoc ahead of time. I've tried to reference them as $Villages[0].Hatchery and $Villages[1].Crops without success. If it can be helped I would prefer to avoid repeating a bunch of <<if>> statements for each action.
<<if $Villages.indexOf($Location) is 0>><<set $Village0.Resource to $Resources[$Random]>><<endif>>
<<if $Villages.indexOf($Location) is 1>><<set $Village1.Resource to $Resources[$Random]>><<endif>>
<<if $Villages.indexOf($Location) is 2>><<set $Village2.Resource to $Resources[$Random]>><<endif>>
etc...

Comments

  • edited May 2015
    What you could do instead is write your own macro using Javascript, as I am unsure that the idea you are looking to do can be achievable in pure Twine programming.

    There is a great tutorial here on creating custom macros, and here on a random generator, which includes name generation. To include that generator in your project, you will need to modify the built index.htm file and include the script line that links to that JS file, as there is no way (as far as I am concerned) to include it directly in your Twine project. (You will probably need to do this everytime you build your project as it would overwrite the script includes).

    Here is an example (which will only work in the Sugarcane format):
    var villages = [];
    var exposed = false;
    
    try {
        version.extensions['macroRandomVillage'] = { 
            major:1, minor:0, revision:0 
        };
    
        macros['RandomVillage'] = {
            handler: function(place, macroName, params, parser) {
              //Create the village object, in JSON format.
              var village = {
                  "name": chance.city(),
                  "crops": [],
                  "resources": []
              };
    
              //Generate some values to determine the wealth of this village.
              village.resources[0].name = "Fish";
              village.resources[1].amount = chance.integer({ min: 0, max: 500 });
    
              //Add this new village object to the "villages" variable.
              villages.push(village);
    
              //If you do <<RandomVillage true>> in one of the passages, this will display the results at the location of the macro.
              if (params[0] == true) {
                  var content = "Villages that now exist: ";
                  for (var i = 0; i < villages.length; i++)
                       content += "Village [" + i + "] Name: " + villages[0].name;
    
                  new Wikifier(place, content);
              }
              
              //expose the villages variable to the Twine engine, so we can do $villages
              if (!exposed) {
                  state.history[0].variables["villages"] = villages;
                  exposed = true;
              }
            },
            init: function() { },
        };
    } catch (e) { throwError(place,"macrodemo Setup Error: "+e.message);  }
    

    To access any new villages we have created, we can do:
    <<RandomVillage>>
    Name of village: <<display $villages[0].name>>
    

    It would be possible to to do the above JavaScript in Twine programming, but with difficulty, and from what I can tell the best way to achieve what you want would be to use JavaScript and call functions as necessary. You can modify your villages as necessary since we are exposing the JSON formatted variable to Twine, so we can do things like this:
    <<set $villages[0].crops[0] = { "value": 6 }>>
    

    You could even do it in a link, which would simply add 1 to the value of crops:
    [[Add some crops][$villages[0].crops[0].value++]]
    

    It's certainly something to play around with. I think either way, there will be some complex programming involved to achieve this.
  • edited May 2015
    I would separate the name of the village from its stats entirely.

    Don't attach stats to the name, but simply to the identifier like $village1, $village2. And then just use <<set $village1name to randomnamechoice>><<print $village1name>> to display the name.

    Then you could use an <either>> macro to randomise whether $village1 is good at $fishing or $mining.

    So for every village you'd have something like:
    <<print $village1location>>
    <<print $village1name>>
    <<print $village1stats>>
    
    And then you could randomise each without effecting the other stats.


    BTW, I'd use a different method of random name generation. Since there are fewer vowels in the alphabet, you're liable to come up with something like Yhjkg more often than not with your proposed method. The simplest approach would be to just predefine a list of 100-1000 names to choose between.
  • Thanks for those suggestions. I don't have any experience with Javascript so I'll have to research what those commands mean.

    I actually found a method that displays what I had in mind. I ignored all the object programing tutorials and did the opposite. Instead of treating a resource as an attribute of the village now the village it's located in is an attribute of each resource. So I look for $Farmland.indexOf($Location) to see if the current village has farm land. I have to do this every resource and improvement I plan to put in the game but at least it won't limit the number of village by how many I'm willing to prepare for.

    And, yes, the name Yhjkg is odd for a village. Though not all the inhabitants are human nor were they consulted when naming it.
  • Time to read up on json variables...
    <<set villages to {}>>
    <<generatename>> 
    <<set $village to { Name: $new_name, Fish: 1, Wood: 2 }>>
    <<set villages[$location] to $village>>
    

    Then when you arrive at a village:
    <<set $village = villages[$location]>>
    

    Any changes made to $village will be reflected in the global resource array as it's returned a live link to it rather than a pointer, so:
    <<set $village.Hatchery to 1>>
    

    will make a lasting change.
Sign In or Register to comment.