*Rand values (traits) repeating twice help

The randomizer assigns traits, there are three trait slots per person. Everyone can have three traits. These traits can not repeat on the same person. Like: Compassionate, Loyal, Compassionate.

Ok, I went ahead and did a randomizer trait system. You can have as many traits as you want, as many characters as you want and as many traits for each character as you want.

This uses arrays so if you do try dwelving on the code you might need to read up on them a bit, but you can still use it without knowing about them since I tried to make the code simpler to be used.

(Most of the code is not necessary, it’s simply because I added 3 methods to show the traits of each character. You could simply pick the one you feel most comfortable with).

*title Trait randomizer
*author GS

*create implicit_control_flow true
*create repeated_traits 0
*create space " "
*create search_id 0
*create search_trait ""
*create search_result false
*create search_match_slot 0

*create trait_1 "Compassionate"
*create trait_2 "Tall"
*create trait_3 "Strong"
*create trait_4 "Pretty"
*create trait_5 "Patient"
*create trait_6 "Smart"
*create trait_7 "Diligent"
*create trait_8 "Just"
*create trait_9 "Honest"
*create trait_10 "Shy"
*create trait_11 "Young"
*create trait_12 "Greedy"
*create trait_13 "Brave"
*create trait_14 "Groomed"
*create trait_15 "Stubborn"
*create trait_16 "Fussy"
*create trait_17 "Curious"
*create trait_18 "Playful"
*create trait_19 "Quick"
*create trait_20 "Humble"

*create trait_quantity 20
*create char_quantity 10
*create allowed_traits 3

*create char_1_1 "Michelle"
*create char_1_2 ""
*create char_1_3 ""
*create char_1_4 ""

*create char_2_1 "John"
*create char_2_2 ""
*create char_2_3 ""
*create char_2_4 ""

*create char_3_1 "Kevin"
*create char_3_2 ""
*create char_3_3 ""
*create char_3_4 ""

*create char_4_1 "Erica"
*create char_4_2 ""
*create char_4_3 ""
*create char_4_4 ""

*create char_5_1 "Jackson"
*create char_5_2 ""
*create char_5_3 ""
*create char_5_4 ""

*create char_6_1 "Samuels"
*create char_6_2 ""
*create char_6_3 ""
*create char_6_4 ""
*create char_6_5 ""

*create char_7_1 "Merlin"
*create char_7_2 ""
*create char_7_3 ""
*create char_7_4 ""

*create char_8_1 "Stanley"
*create char_8_2 ""
*create char_8_3 ""
*create char_8_4 ""

*create char_9_1 "Waits"
*create char_9_2 ""
*create char_9_3 ""
*create char_9_4 ""

*create char_10_1 "Ripley"
*create char_10_2 ""
*create char_10_3 ""
*create char_10_4 ""

*choice
	#Randomize traits.
		*gosub randomizer

@{(repeated_traits > 0) Traits got repeated during randomization ${repeated_traits} times and were re-randomized|No trait got repeated during randomization}.

*label finishing

*choice
	#Show on simplest method (fixed amount of traits).
		*gosub show_chars_even_simpler
	#Show on simpler method (listed).
		*gosub show_chars_simpler
	#Show on more complex method (dynamic sentence; good luck fixing the spaces).
		*gosub show_chars
	#Quit.
		*finish

*choice
	#Search trait in a character.
		Type the ID of the character you want to search. (From 1 to ${char_quantity})
		*input_number search_id 1 char_quantity
		Now type the name of the trait to see if ${char[search_id][1]} has it.
		*input_text search_trait
		*gosub search_trait_in_character search_id search_trait
		The trait "${search_trait}" was @{search_result located for character ${char[search_id][1]} at slot ${search_match_slot-1}|NOT located for character ${char[search_id][1]}}.
	#Quit.
		*finish

*goto finishing

*comment =============SHOW CHARACTER TITLE===============
*label show_title

==================
*line_break
${char[counter][1]}'s traits (Character id: ${counter})
*line_break
==================

*return
*comment =============SHOW CHARACTERS EVEN SIMPLER===============
*label show_chars_even_simpler
*temp counter 0
*label show_chars_even_simpler_loop
*set counter + 1

*if (counter > char_quantity)
	*return

*gosub show_title

${char[counter][2]}, ${char[counter][3]} and ${char[counter][4]}.

*goto show_chars_even_simpler_loop

*comment =============SHOW CHARACTERS SIMPLER===============
*label show_chars_simpler
*temp counter 0
*temp trait_counter 2
*label show_chars_simpler_loop
*set counter + 1

*if (counter > char_quantity)
	*return

*gosub show_title

*label show_chars_simpler_traits_loop
*if (trait_counter > "${allowed_traits+1}")
	*goto show_chars_simpler_loop
-${char[counter][trait_counter]}
*line_break
*if (trait_counter > allowed_traits)
	*set trait_counter 2
	*goto show_chars_simpler_loop
*else
	*set trait_counter + 1
	*goto show_chars_simpler_traits_loop

*comment =============SHOW CHARACTERS===============
*label show_chars
*temp counter 0
*temp trait_counter 2
*label show_chars_loop
*set counter + 1

*if (counter > char_quantity)
	*return

*gosub show_title

*label show_chars_traits_loop
*if (trait_counter > "${allowed_traits+1}")
	*goto show_chars_loop
${char[counter][trait_counter]}
*if (trait_counter = "${allowed_traits-1}")
	, 
*elseif (trait_counter > allowed_traits)
	.
	*set trait_counter 2
	*goto show_chars_loop
*else
	${space}and
*set trait_counter + 1
*goto show_chars_traits_loop

*comment =============RANDOMIZER===============
*label randomizer
*temp new_trait 0
*temp char_counter 1
*temp trait_counter 2
*label randomizer_loop
*temp proceed false
*rand new_trait 1 trait_quantity

*if (char_counter > char_quantity)
	*return
*else
	*gosub check_existent char_counter new_trait
	*if (trait_counter > "${allowed_traits+1}")
		*set char_counter + 1
		*set trait_counter 2
		*goto randomizer_loop
	*else
		*if (proceed)
			*set char[char_counter][trait_counter] trait[new_trait]
			*set trait_counter + 1
			*goto randomizer_loop
		*else
			*goto randomizer_loop

*comment =============CHECK EXISTENT TRAIT===============
*label check_existent
*params char_to_check trait_being_added
*temp check_counter 1
*label check_existent_loop
*set check_counter + 1
*if (check_counter = "${allowed_traits+1}")
	*set proceed true
	*return
*else
	*if ("$!!{char[char_to_check][check_counter]}" = "$!!{trait[trait_being_added]}")
		*set repeated_traits + 1
		*set proceed false
		*return
	*else
		*goto check_existent_loop

*return
*comment ===============SEARCH TRAIT IN CHARACTER=================
*label search_trait_in_character
*params character_id trait_to_search
*set search_result false
*temp search_count 1
*label search_trait_in_character_loop
*set search_count + 1
*if (search_count <= "${allowed_traits+1}")
	*if ("$!!{char[character_id][search_count]}" = "$!!{trait_to_search}")
		*set search_result true
		*set search_match_slot search_count
		*return
	*else
		*goto search_trait_in_character_loop

*return

The script uses arrays for the trait list and to store the traits each character has. The character info is stored in the array and it has 4 indexes for each character. Index 1 is the name, 2, 3 and 4 are the first, second and third traits respectively.

If you want to allow more traits on a character it’s simple and the code accomodates for it, simply add a new index for all characters like:

*create char_1_5 ""
*create char_1_6 ""
*create char_1_7 ""

This will create 3 more trait slots for character number 1, which in that preset I sent is Michelle. You need to add these _5, _6 and _7 entries for all characters so that everyone can receive new traits. After that you change the variable allowed_traits to 6, since now everyone will have 6 trait slots.

If you want to add more traits, simply add more like this:

*create trait_21 "Ambitious"
*create trait_22 "Erudite"
*create trait_23 "Trusting"
*create trait_24 "Zealous"
*create trait_25 "Pilgrim"

This will add 5 more traits to the trait pool. After this you change the trait_quantity variable to 25 and now 25 traits are possible.

For more characters it’s similar, simply add more character entries:

*create char_11_1 "Ralph"
*create char_11_2 ""
*create char_11_3 ""
*create char_11_4 ""

Make sure to create as many trait slots as the number of traits you decide each character to have. Then you change the char_quantity to reflect the amount of characters.

Now to actually make this useful, let’s see how you could check if a character has a particular trait.

The simplest way to do it would be to check each slot and see if it matches something you want to search on it, but this way would become quite long if you had a lot of trait slots. A better way to search to see if a character has a particular trait is to use a function that loops through the entire array in search of it. I added one at the very bottom of the file. To use it, you simply call:

*gosub search_trait_in_character ID_OF_THE_CHARACTER TRAIT_TO_SEARCH

So let’s say you want to search if Erica (id 4 in the example I’ve made) has the trait Shy. You would use the id as the first parameter (in this case 4) and then Shy as the trait to search it.

*gosub search_trait_in_character 4 "Shy"

This will search for the trait in Erica’s trait slots and will switch a variable called search_result to either true or false if it has located something or not. You can then right under it have a conditional to do whatever you want.

*gosub search_trait_in_character 4 "Shy"

*if (search_result)
	Erica is shy!
*else
	Erica is NOT shy!

This is how to fiddle with the trait randomizer. If you have any questions or want to know how to do other things with it, let me know and I can help. If you want I suggest you add this into it’s own project or startup file so that you can try a bit of it without trying to fit it inside your game first.

Let me know if there are errors as well.

5 Likes

Maybe I’m too new to this, but that was very over my head. I feel like if I had someone personally adding code into my game where I didn’t have to deal with it - this would work fine. But because I have to personally deal with this code, not just in this one scene, but in many other scenes where traits are assigned…I don’t think I can do it.
I’m a hands on person. But I literally don’t even know what part of your code to copy into mine. It needs to have its last *goto be *label next. The traits need to be named matchtrait1, matchtrait2, matchtrait3. I need it to have no page breaks. In my code currently, as soon as you choose #Random it randomizes many different things (including traits) and the next thing it loads is the results page.

I know you broke it down into more simple code for my own sake, but I can’t even visually follow it. I don’t even see what you did to not repeat traits.

Thank you for taking all that time in putting it together. If you can make it any more adapted to my own code, that would make it much more readable for me. I need to know what exactly to copy and paste, what to rename…etc. Seriously thank you for taking the time. Feel free to ignore this, as all your hard work has gone over my head and I am sorry for that.

1 Like

I think the best thing to do here is to first of all sit back and see which traits are needed.
As these are for NPCs coding down the line would be so. Much. Worse.

The basic mechanics shown in this threat are good, but i think coding and writing wise you’ll be better off assigning traits to characters beforehand and not at random.

Take the word from someone who has the results of a cooking contest show be random each playthrough

If you still want to do this, it would probably be easiest to generate three unique numbers before assigning trait names. Solskin’s code already works for that, but if loops are giving you trouble here’s a non-looping version (assuming 20 traits):

*temp A
*temp B
*temp C

*rand A 1 20
*rand B 1 19
*rand C 1 18
*if B >= A
	*set B +1
*if (C>=B) and (C>=A)
	*set C +2
	*goto display
*elseif C>=B
	*set C +1
	*if C=A
		*set C +1
	*goto display
*elseif C>=A
	*set C +1
	*if C=B
		*set C +1
	*goto display
*else
	*goto display
	
*label display
${A},${B},${C}
*finish
2 Likes

What might be easier here is: First getting 3 random Numbers, then Check of any of them is equal to another, if there are matches Go to the beginning of the label, if not Look which traits WE got. I am at Work atm will send a Code later

1 Like

Thanks for coding this.
So what is the +1 +2 meaning? Is +1 meant to be a trait name? And how can B >= A…etc… C=A, C>=B…I’m confused. How can a letter be greater or less than or equal to?

Using MeltingPenguin’s code idea I’ve come up with a personality system consisting of setting three traits. Per personality system, there could be three trait sets under the same title. For example: The Pushover personality type is repeated three times with slightly different variations in traits. I’ve made it still random of which personality will be picked, but the traits within those personalities remain the same. If that makes sense…
Pros: It’s easy to code and fun to think of which traits might go to which personality
Cons: It’s manually done, people could get upset based on which traits go under each personality heading (like if “Ideal Partner” has certain traits that not everyone thinks are ideal).

example1

1 Like

The only things the code does is come up with three unique random numbers within 1~20, called A,B and C. The numbers can be matched up with the traits later.

Hmm alright, I’ll break the code down and try to explain how it works bit by bit. I’ll also only leave the essentials. It’s gonna be long but I’ll try my best to break it down. If you still don’t feel comfortable in using it, I don’t mind. I had fun making it.

Here is the simplified code, I removed the search and made only one type of display available. This one is 159 lines.

image

*title Trait randomizer
*author GS

*create implicit_control_flow true

*create trait_1 "Compassionate"
*create trait_2 "Tall"
*create trait_3 "Strong"
*create trait_4 "Pretty"
*create trait_5 "Patient"
*create trait_6 "Smart"
*create trait_7 "Diligent"
*create trait_8 "Just"
*create trait_9 "Honest"
*create trait_10 "Shy"
*create trait_11 "Young"
*create trait_12 "Greedy"
*create trait_13 "Brave"
*create trait_14 "Groomed"
*create trait_15 "Stubborn"
*create trait_16 "Fussy"
*create trait_17 "Curious"
*create trait_18 "Playful"
*create trait_19 "Quick"
*create trait_20 "Humble"

*create trait_quantity 20
*create char_quantity 10
*create allowed_traits 3

*create char_1_1 "Michelle"
*create char_1_2 ""
*create char_1_3 ""
*create char_1_4 ""

*create char_2_1 "John"
*create char_2_2 ""
*create char_2_3 ""
*create char_2_4 ""

*create char_3_1 "Kevin"
*create char_3_2 ""
*create char_3_3 ""
*create char_3_4 ""

*create char_4_1 "Erica"
*create char_4_2 ""
*create char_4_3 ""
*create char_4_4 ""

*create char_5_1 "Jackson"
*create char_5_2 ""
*create char_5_3 ""
*create char_5_4 ""

*create char_6_1 "Samuels"
*create char_6_2 ""
*create char_6_3 ""
*create char_6_4 ""

*create char_7_1 "Merlin"
*create char_7_2 ""
*create char_7_3 ""
*create char_7_4 ""

*create char_8_1 "Stanley"
*create char_8_2 ""
*create char_8_3 ""
*create char_8_4 ""

*create char_9_1 "Waits"
*create char_9_2 ""
*create char_9_3 ""
*create char_9_4 ""

*create char_10_1 "Ripley"
*create char_10_2 ""
*create char_10_3 ""
*create char_10_4 ""

*choice
	#Randomize traits.
		*gosub randomizer

*gosub show_chars_simpler

*finish

*comment =============SHOW CHARACTERS SIMPLER===============
*label show_chars_simpler
*temp counter 0
*temp trait_counter 2
*label show_chars_simpler_loop
*set counter + 1

*if (counter > char_quantity)
	*return

==================
*line_break
${char[counter][1]}'s traits (Character id: ${counter})
*line_break
==================

*label show_chars_simpler_traits_loop
*if (trait_counter > "${allowed_traits+1}")
	*goto show_chars_simpler_loop
-${char[counter][trait_counter]}
*line_break
*if (trait_counter > allowed_traits)
	*set trait_counter 2
	*goto show_chars_simpler_loop
*else
	*set trait_counter + 1
	*goto show_chars_simpler_traits_loop


*comment =============RANDOMIZER===============
*label randomizer
*temp new_trait 0
*temp char_counter 1
*temp trait_counter 2
*label randomizer_loop
*temp proceed false
*rand new_trait 1 trait_quantity

*if (char_counter > char_quantity)
	*return
*else
	*gosub check_existent char_counter new_trait
	*if (trait_counter > "${allowed_traits+1}")
		*set char_counter + 1
		*set trait_counter 2
		*goto randomizer_loop
	*else
		*if (proceed)
			*set char[char_counter][trait_counter] trait[new_trait]
			*set trait_counter + 1
			*goto randomizer_loop
		*else
			*goto randomizer_loop

*comment =============CHECK EXISTENT TRAIT===============
*label check_existent
*params char_to_check trait_being_added
*temp check_counter 1
*label check_existent_loop
*set check_counter + 1
*if (check_counter = "${allowed_traits+1}")
	*set proceed true
	*return
*else
	*if ("$!!{char[char_to_check][check_counter]}" = "$!!{trait[trait_being_added]}")
		*set proceed false
		*return
	*else
		*goto check_existent_loop

*return


To start off, let’s go over the variable creation:

*create trait_1 "Compassionate"
*create trait_2 "Tall"
*create trait_3 "Strong"
*create trait_4 "Pretty"
*create trait_5 "Patient"
*create trait_6 "Smart"
*create trait_7 "Diligent"
*create trait_8 "Just"
*create trait_9 "Honest"
*create trait_10 "Shy"
*create trait_11 "Young"
*create trait_12 "Greedy"
*create trait_13 "Brave"
*create trait_14 "Groomed"
*create trait_15 "Stubborn"
*create trait_16 "Fussy"
*create trait_17 "Curious"
*create trait_18 "Playful"
*create trait_19 "Quick"
*create trait_20 "Humble"

This part is creating an array of 20 elements. An array is like a list that holds objects which you can get by index. To use this, you use the name of the variable and square brackets right after it. Like this: variable[index].

(For a short explanation about arrays, check this video.) (In ChoiceScript arrays start at 1 unlike what he is using there though.)

For example, trait[3] would contain “Strong”. trait[14] is “Groomed”.

The good thing about this is that you can use variables for the index as well. Suppose I have a variable called var1:

*create var1 17

And that var1 equals 17. I could use this variable inside those square brackets too. If I used trait[var1] it would be the same as trait[17] which contains the “Curious” trait. This allows you to access things in your list more dynamically which will be very useful because it allows the code to accomodate however many traits you want and “loop” through the list when checks need to be made.

Now let’s see the character declaration:

*create char_1_1 "Michelle"
*create char_1_2 ""
*create char_1_3 ""
*create char_1_4 ""

*create char_2_1 "John"
*create char_2_2 ""
*create char_2_3 ""
*create char_2_4 ""

*create char_3_1 "Kevin"
*create char_3_2 ""
*create char_3_3 ""
*create char_3_4 ""

This one might be a little more complicated to explain but I’ll try. We are going to use multidimensional arrays (in this case two-dimensional).

What we are doing here is making a character that will contain 4 things. A name and 3 trait slots. For this it’s easier to imagine a table of sorts.

image

The “ID” is always the number inside the first brackets. char[THIS][].

The rest of the attributes (name, trait slots) would always be the things inside the second brackets. char[][THIS].

And when our “table” would be filled with traits it would be like:

image

To get things here we would need to use two square brackets. I think to better explain this you can imagine as each block of 4 things as one character. The first square brackets will be the character’s “id” and the second set of square brackets what you want to select from it (the name or the traits).

So say I want to select John’s variable that stores his name. I would need to use char[2][1]. The first square brackets will go to the character in question, which in this case all attributes of John’s is of “id” number 2. If I wanted to get Kevin’s name I would use char[3][1] and so on.

For now the traits are empty, but say I want to see what is Michelle’s second trait, I would use char[1][3] since I’m going for character of “id” 1 which is Michelle and then getting the second trait slot (which is index 3 in that example). It would be empty now but it will be randomized later.


So the actual randomization is done in the *gosub randomizer:

*comment =============RANDOMIZER===============
*label randomizer
*temp new_trait 0
*temp char_counter 1
*temp trait_counter 2
*label randomizer_loop
*temp proceed false
*rand new_trait 1 trait_quantity

*if (char_counter > char_quantity)
	*return
*else
	*gosub check_existent char_counter new_trait
	*if (trait_counter > "${allowed_traits+1}")
		*set char_counter + 1
		*set trait_counter 2
		*goto randomizer_loop
	*else
		*if (proceed)
			*set char[char_counter][trait_counter] trait[new_trait]
			*set trait_counter + 1
			*goto randomizer_loop
		*else
			*goto randomizer_loop

The code will use the arrays from both the trait list and the characters to randomize all traits from all characters in one swoop. It will be first a loop through all the traits of one character, then it will proceed to the next character and assign their traits and so on, as in looping through all available characters.

First what it’s doing is creating three variables:

  • new_trait = This is the variable that will hold the randomized trait
  • char_counter = Since we will loop through the characters, we will need a counter for the characters. This will start at 1 since the first “id” we have for our characters starts at 1.
  • trait_counter = Since we will also loop through trait slots of a character, we need a counter for them as well. This will start at 2 because the trait slots for everyone start at index 2 (since index 1 of everybody holds their name).

Alright, after making those variables it will also create a proceed variable, but let’s ignore that one as it’s not important right now.

Now we apply a *rand to our new_trait variable to randomize it to a specific number between 1 and the amount of traits possible (in the example I’ve made that would be 20). So after new_trait is randomized, it will have a value between 1 to 20.

Right after that we have a big *if chain. The first condition is to treat the character counter, but since we didn’t fiddle with it for now, we can ignore it. Since this is the first character this won’t be passed now anyways.

The code will get inside the *else and it will hit the *gosub check_existent char_counter new_trait. What this is doing is calling the *gosub called check_existent and passing our char_counter variable and our new_trait variable as parameters. From what we saw when we created them above, their current values are 1 and something between 1-20 respectively.

That *gosub is where the trait is checked to make sure it’s not a trait the character already has.

*comment =============CHECK EXISTENT TRAIT===============
*label check_existent
*params char_to_check trait_being_added
*temp check_counter 1
*label check_existent_loop
*set check_counter + 1
*if (check_counter = "${allowed_traits+1}")
	*set proceed true
	*return
*else
	*if ("$!!{char[char_to_check][check_counter]}" = "$!!{trait[trait_being_added]}")
		*set proceed false
		*return
	*else
		*goto check_existent_loop

*return

It starts by assigning both our parameters as char_to_check and trait_being_added in the same order we called them. So this *gosub will make these two variables in its scope:

  • char_to_check = This is the char_counter we passed before, which equals to 1.
  • trait_being_added = This is the new_trait variable we randomized before, which is somewhere between 1 and 20. For easier to explain purposes, let’s assume the random result was 6, which equals “Smart” in our list.

Now what we need to do is to check all the trait slots of this character to see if the character already has this trait that was just randomized. (Since this is the first trait that we are going to assign to Michelle, we could just have assigned it instead of checking but I forgot to account for that, oops! But the code will work and check it either way.)

Since we are going to be looping through the character trait slots, we need a counter for that, so we create a check_counter. It starts at 1 because it will be added right after +1 after our loop label, so that it starts at 2 for the first check, with 2 being the index of first slot traits for everyone.

Now we get to the first condition, *if (check_counter = "${allowed_traits+1}"), this will not be triggered now because this is a condition to see if we reached the number of available slots for our characters with our counter. Since we did not yet reach that (as our counter is 2 and the allowed_traits+1 is 4, we can still run this a few times).

Since that condition will fail, we get to the *else, and this is where the important part is at. The following condition:

*else
	*if ("$!!{char[char_to_check][check_counter]}" = "$!!{trait[trait_being_added]}")
		*set proceed false
		*return
	*else
		*goto check_existent_loop

Is where we check if the trait exists in a trait slot. Let’s break it down to parts:

  1. "$!!{char[char_to_check][check_counter]}" = What we are getting here is the content of the variable that would be of the character, in this case we are still checking Michelle, so char_to_check is 1. So what we have now would be like char[1][check_counter]. check_counter is what we made in this *gosub, that starts at 1 and then receives +1.
*temp check_counter 1
*label check_existent_loop
*set check_counter + 1
  1. (cont) So this means our variable would be char[1][2] right now. This means that what’s on the left of the condition on the first run would be char[1][2]. So the first thing being checked in our *if would be this: "$!!{char[1][2]}". This is the content of Michelle’s first trat slot. Which now is empty but there will be something there in the next runs.

(OBS: You may notice there is a $!!. This is to make sure the trait being compared is in ALL CAPS. This is better for comparisons as if a trait is typed as “Smart” or “smART” they will all be made into caps to make sure the upper or lower case doesn’t matter, but this isn’t really necessary for this code, just a little bonus.)

Now we need to decipher the second part of this *if condition, the "$!!{trait[trait_being_added]}".

  1. "$!!{trait[trait_being_added]}" = Now we are messing with the trait list, which we have 20 elements. The trait_being_added is a variable that we got from passing the new_trait as a parameter, which is our randomized one between 1 to 20. Like I said before we will consider the result of the randomization as 6. So this would be "$!!{trait[6]}". If we go into our trait list and we check what trait[6] is, it would be “Smart”.

So, in all, our condition during runtime would be:

*if ("" = "Smart")

The “” is because the first trait slot of Michelle (char[1][2]) is currently empty. So this means our condition would fail and go to the *else.

Now let’s see what happens after this *if has its result.

*if ("" = "Smart")
	*set proceed false
	*return
*else
	*goto check_existent_loop

If the result is:

  • true = This means that the character already has the trait we randomized. The code will enter what is below the *if. It will set a variable called proceed as false and then *return (break out of the *gosub it’s in) to go back to the previous *gosub.
  • false = This means that this trait slot we checked does NOT have the current trait we randomized. Beware that this is the trait SLOT, not the entire character. Since we only checked the first trait slot, we need to go back to the loop, which adds +1 to the check_counter so that the next slot is checked this time (as in char[1][3] is checked). This will make the code check the same condition again but with all traits.

If at any time in the loop this true condition is never reached (eventually the check_counter will be higher than the allowed_traits so we need to stop it as we checked all trait slots), this means that the character we checked does not have the trait we randomized. This means that we are now free to assign this trait. If the true is reached, the character already has this trait and it needs to be re-randomized again.

*if (check_counter = "${allowed_traits+1}")
	*set proceed true
	*return

The proceed variable is the key here, it will be set to true when we verify that this trait is not located in any of the slots.

Now we will have *returned to the randomizer *gosub carrying the value of our proceed variable.

	*gosub check_existent char_counter new_trait
	WE ARE NOW HERE <--------------------------------
	*if (trait_counter > "${allowed_traits+1}")
		*set char_counter + 1
		*set trait_counter 2
		*goto randomizer_loop
	*else
		*if (proceed)
			*set char[char_counter][trait_counter] trait[new_trait]
			*set trait_counter + 1
			*goto randomizer_loop
		*else
			*goto randomizer_loop

The check there is to see if we already went over the amount of traits for a character by checking this *gosub's trait_counter, but we have not since this is still slot 2 (which there are 4). This means this condition will not yet be triggered so we enter the *else

	*else
		*if (proceed)
			*set char[char_counter][trait_counter] trait[new_trait]
			*set trait_counter + 1
			*goto randomizer_loop
		*else
			*goto randomizer_loop

So this is when we check our proceed variable. If proceed is:

  • true = It means that this randomized trait was not found in the other trait slots of this character, therefore we can now safely assign this trait to the slot we are currently working with and then continue the randomizer loop to do all this over again to the next trait slot of this character. Therefore we assign the trait[new_trait] (with new_trait being the randomized variable we got, in this case 6) to the current slot *set char[char_counter][trait_counter] with char_counter still being 1 for Michelle and the trait_counter being 2 since it’s our first slot. So we have *set char[1][2] trait[6] which would be *set char[1][2] "Smart". This menans now that “Smart” is Michelle’s first trait.
  • false = It means that the character already has the trait we randomized. So we need to go back to the loop without adding anything as it will re-do all the work for this same trait slot. It will re-randomize it again and compare if the char already has it until it manages to randomize something that the char doesn’t have.

So after all the trait slots for this character are done, then it will go to the next character and start the process again in the:

*if (trait_counter > "${allowed_traits+1}")
	*set char_counter + 1
	*set trait_counter 2
	*goto randomizer_loop

By adding 1 to char_counter and resetting the trait_slot to randomize to 2 (which is everyone’s first trait slot). So then it would go with (char[2][2]) which are John’s slots and after he finishes move on to the next character.

Since this code uses loops and stuff it can fit whatever changes you want by altering those control variables (trait_quantity, char_quantity and allowed_traits).

This is pretty much it, hopefully I could explain it well but I do understand it’s quite complex since it’s a lot of loops with other more complicated stuff. There is a section to list all characters but it’s pretty much a loop like the previous ones; I can still explain it if anyone wishes. I can also explain the search and add it back to the code if you want (it functions very similarly with the check to see if a character already has a trait that was randomized).

9 Likes

Do you know if ChoiceScript supports removing an element from the middle of an array and shortening the array?

1 Like

Ah…I think I see.

1 Like

I’m not sure?

1 Like

Probably not; you’d have to do that manually. There’s also no “array_length” feature, which is why I added those trait, character and slot size variables.

Asking again:
Are thd random assigned traits for npcs absolutely necessary for plot or gameplay?

1 Like

They’re necessary for the player, as to not be predictable. My game has a lot of randomization, so even I as the creator won’t be bored easily. Other randomization is much easier. Thank you for your input on the code because that has been the simplest version for me.

1 Like

I think I’ll have to read through this several times, but thank you again. You’re the kind of coder I’d love to collaborate with, because you can turn complicated coding into an easy past time. I feel like I’ve missed many lessons on Choicescript coding in my research. I don’t think I’ve ever come across tutorials that teach everything you just wrote.

1 Like

You will hate yourself.
As you’ll have, if I understood this correctly, this for all npcs. Meaning it’d have an influence on how they talk and react?
Which in combination would mean a ton if different dialogue bits unrelated to the story or the choices.
Not to forget the combination of the traits with those choices.

2 Likes

Not how they talk. Just randomized scenes based on their traits.

1 Like

A post was merged into an existing topic: [CSIDE] The ChoiceScript IDE (v1.3.0 Now Available — 18/06/2019)