For my game I have 64 areas, each area has three slots for a commander with their own respective troop numbers, morale and special ability.
I want to make it possible to remove or assign commanders to each area, as well as assign or remove troops or influence their individual morales through a general management screen.
What I currently did (which is most likely extremely messy) is assign each area with a number and then have each area have it's own variables for each commander (area1commander1, area1commander 2, area2commander 1 etc.)
The only way I can think of to change this would be by using a lot of if statements in the management screen.
Example:
<<if $area is 1>><<set $area1commander1 to $chosencommander1>><</if>>
This will be extremely inefficient and messy though. Is there a better way to do this?
Thanks in advance
Comments
$area will be an array containing all 64 areas. $commander is an object containing keys for troops, morales, and special abilities.
The last three lines show how you would call it. You can call any area using:
Sorry in advance if you already know about Index 0, but just in case it's important to know that in many coding languages, calling the index of an array starts at 0. So if an array is:
$array = [1, 2, 3]
Then $array[0] would return a value of 1. $array[2] would return a value of 3. So if you want Area 64, you'd call $area[63], and for Commander 3 of Area 64, you'd have $area[63][2].
After that, use the dot operator (just a period) and then the key you want to return. The keys are troops, morale, and special. Calling those will return the corresponding values you set up in the <<set $commander[_i] = {troops: 0, morale: 100, special: "none"}>> line.
Beyond what I've shared here, I'm not sure what to recommend in terms of managing it. If you share a bit more info about how you'd like the data to flow in your game I can try at a few more ideas/tips, but I don't want to ramble about ways to work with this setup and risk making it all more confusing than it needs to be.
You can have a few other variables like and that are changed often throughout the game depending on what the user is doing.
So let's say the user has 64 buttons to choose their area, and 3 buttons to choose their commander. Each button would cause the value of $areaNumber and $commanderNumber to change. If they click Area 45, that click would set $areaNumber to (45 - 1) (to compensate for Index 0) or you could just tell the button to set $areaNumber to 44 when button 45 is clicked. Up to you.
The same goes for the 3 commander buttons. Clicking them will change the value of $commanderNumber.
You can also use some CSS and an if statement to highlight whichever button they choose by changing the color.
Then, when it's time to make changes, you have:
<<set $area[$areaNumber][$commanderNumber].special = "Grenades">>
Or something to that effect. You can also set up buttons or links for the different types of special attacks in order to set a $specialAttack variable as a string that matches the desired special attack.
I hope that helps! If not, let me know what you have in mind in terms of managing this information during gameplay and I'll see if I can help more.
If the whole "index of array" thing was confusing, think of it like this: An array is a series of elements containing numbers, variables, objects, or other types of data. You can use something called bracket notation to assign or get any specific element by its index.
To use bracket notation on $array, we simply add square brackets after it like this: $array[x]
The 'x' would be replaced with the index of the element we want to work with.
Given <<set $array = ["blue", "red", "green", "black", "olive", "cake"]>>, we can see that "blue" is first, "black" is fourth, and "cake" is sixth.
But that doesn't mean we'd replace 'x' with those exact numbers. "blue" might be first, but its index is 0.
This is because arrays start indexing elements at Index 0 instead of Index 1.
That's it. Using that logic, any element we want to use in an array will have "an index that is one less than its actual placement in the series of elements". So, "blue" looks like it's first, but its index is 0. "black" looks like it's fourth, but its index is 3 (because 4 - 1 = 3). "cake" is sixth, which means its index is 5.
Bringing this back to our $array[x], we simply replace x with the index in order to work with it.
$array[0] is equal to "blue"
$array[3] is equal to "black"
$array[5] is equal to "cake"
Bracket notation can be used to work with nested arrays which is just a succinct way of saying "arrays within arrays". If we <<set $array to [ ["blue", "green"], ["cake", "pie"] ]>>, we have two small arrays inside of one large array.
Notice how the smaller arrays are still separated by a comma. That's important!
To use the above array, we would have $array[x][y] where 'x' is equal to the index we're calling for the larger array, and 'y' is equal to the index we're calling on the smaller array.
For <<set $array to [ ["blue", "green"], ["cake", "pie"] ]>>
$array[0] is equal to ["blue", "green"] (because we called the entire array since we only used one set of brackets)
$array[0][0] is equal to "blue" (because it's at index 0 of the array that's at index 0 of $array)
$array[1][0] is equal to "cake" (because it's at index 1 of the array that's at index 0 of $array)
$array[1][1] is equal to "pie" (because it's at index 1 of the array that's at index 1 of $array)
I hope that helps! There's plenty of awesome stuff to read online about it. I'd recommend checking out the Mozilla Developer Network. Specifically, the JavaScript section: https://developer.mozilla.org/en-US/docs/Learn/JavaScript
Because for the commanders my idea is that you can hire or find a commander which then gets a name randomly picked from a pre defined list (depending on the unit type).
The ability is then already pre defined based on unit type (for example all villager units would have the ability to mine or farm).
This new commander is then assigned to a barracks where it has no function other than be there.
When a player then has a territory with an empty spot he can click that territory, and add that specific commander to that territory, where it will start out with 0 troops.
Afterwards he can then assign or remove troops to it, troops may die during battle or get bribed, or the commander may fall in battle.
What this means is that each of these variables exists only for a short while so to say.
Another thing is that I made sort of portrets for each commander, which based on unit type also need to be loaded to the correct commander.
Can arrays actually switch variables this often?
You'll want to know when it's best to use arrays versus objects since they are handled differently.
An array is best when you have a list of something and you don't mind referring to them by index using bracket notation.
An object is best when you have something with multiple parameters that you'll want to call by name.
Arrays are set up using square brackets [ and ]
Objects are set up using curly brackets { and }
The way objects are set up is like this:
An object is like an array of "keys" and "values". After it's made, you'll use the keys to access or change the corresponding values.
You can use these just like any variable.
The code above will output "Greater than 80"
The code above will output "true"
Resetting variables for arrays and objects can be done on the fly.
Now the value for key3 is false, and would print "false" in the code above.
Another question now though.
If I make each of the 64 areas an object with the following keys (Defences, Conquered, Commander1, Commander2, Commander3). Is it then possible to somehow make those commander keys an object?
So I could get the following situation for example
<<set $Area1 = {Defences: 100, Conquered: False, $Commander1: true, $Commander2: true, $Commander3: false}>>
<<set $Commander1 = {image: (image link if that's even possible), attack: 10, defence: 10, ability: none}>>
Or will it then get confused with Area2 which ideally would also have a Commander 1, 2 etc?
SUGGESTION: Pick a casing style and stick with it. Generally, in JavaScript and TwineScript, camelCase is preferred for most user code, while PascalCase is reserved for classes, singletons, modules and the like. You don't have to adhere to that if you don't wish to, however, I'd still advise consistency within your own code.
Yes. The following is a way to do so all at once: Though you could also do the following, if you'd prefer to assign the sub-objects separately: Note that in both examples, you do not add commander properties for commanders that the area does not have.
To test if an area had a particular commander, you may do it similarly to how you would if you were assigning booleans to the properties. For example:
EDIT: As an additional example. Here's how you'd write the image markup for a commander's image—assuming the image property is a valid URL:
One last question, which might be quite difficult.
Normally to chance one variable to another I was able to just say <<set $variable to $variable>>.
Is there a way to do this for objects as well? Where I can take an object such as $commander1 and use another object to immediatly transfer all keys and values to that object?
I already know that I can do them one by one by going
<<set $commander1 ={Attack: $commanderA.Attack, Defence: $commanderB.Attack}>>
If it's possible to do all in one go that would simplify things a lot though.
Once again thanks so much for all the help