How To: List/Array in Choicescript v4.1


#1
Alright, so you can make lists in choicescript using the *script command and whatnot, but that will make it hard/impossible to get your game published (So I've heard).
That is why I made this code. It uses just a few variables to:
-make an unlimited number of lists with unlimited length
-add items to lists
-read any item from the list, ie the first item or the twentieth item, etc
-replace an item in the list with something new, no hassle
-deleting an item in a list by index (aka deleting item one or item ten)
-a way to count the number of items in the list easily

I plan to add:
-finding which items in the list have a certain string or number, ie "apple" is the first, third, and eleventh item in the list  (will look like 1^3^11  or something)
-inserting an item bewteen two existing items
-a lot more that I forgot I'm going to add
-whatever you people suggest (reply below)

**I plan to make it so when new versions come out, your old scripts will still work 100%.**

You can use this in your own game to make lists.
So without further ado, take a look at this:

You must first place the twiger_functions file **([Get it Here](https://www.dropbox.com/s/ygmxd9tjqcm7tty/twiger_functions.txt?dl=0)v4)** in your scenes list.

---
Making lists/arrays. (one dimensional) You can use this to store strings or numbers.
All done by Twiger_Fluff aka Twig Wisp       (and the ChoiceScript makers,   Choice of Games LLC)
This is merely version 4

Time spent making so far: 12 hours

---

To create list variable (in startup.txt):
---
*create MyList "aa"
*set Mylist ""
**Does not need to be called MyList but you do need to create it with "aa"


Please also make these variables (only one of each needed, no matter how many lists you have.):

*create lists_listname "aa"
*create lists_index 0
*create lists_output ""
*create lists_replace ""
*set lists_listname ""
---
(same as the list variable, needs to be set to any two characters then to "" in order to pass quicktest

---

To add and item to the list (if you want oranges in your list) (must have a ^ and no space):
---
*set Mylist MyList & "^Oranges"
You can also add several at one time:
*set Mylist Mylist & "^Apples^Oranges^Bananas"

---
Your list should look like this (should start with a caret [the ^ symbol]):   ^Apple^Oranges^Bananas^other stuff^all the words I want^blah^blah^code by Twiger_Fluff^bleh^one^1^2^two
---
---

To count the number of items in a list:
---
*set lists_listname "mylist"
**The name of your list must be in quotes.**
*gosub_scene twiger_functions count
num of items: ${lists_output}
**The number of items will be stored in ${lists_output}
---


---
Next is how to read any item from a list, ie item one is apples, item three is bananas.
note: list name should be in quotes ( "  " )
---
*set lists_listname "mylist"
**Set this to the name of your list, does not need to be used if your list's name is already in it.**
*set lists_index 1
**Set this to the number of the item you want to refer to. ie: milk, cheese, eggs. #2 is cheese. Does not need to be set if already the right number.**
*gosub_scene twiger_functions find
**This runs the function and once it is done, the item will be named in lists_output**
You have ${lists_output}.
**This will give you the statement "You have milk." assuming your lists is ^milk^cheese^eggs**
**You must use lists_output before running the function again.**
---

To delete an item by index:
---
*set lists_listname "mylist"
**Set this to the name of your list, does not need to be used if your list's name is already in it.**
*set lists_index 1
**Set this to the number of the item you want to refer to. ie: milk, cheese, eggs. #2 is cheese. Does not need to be set if already the right number.**
*gosub_scene twiger_functions delete
**Unlike the find function, this does not have an output, it just changes the list
---
To replace an item in a list, such as making ^apples^oranges^my bad, sire^giant become ^apples^bananas^my bad, sire^giant
---
*set lists_listname "mylist"
**Set this to the name of your list, does not need to be used if your list's name is already in it.**
*set lists_index 2
**Set this to the number of the item you want to refer to. ie: milk, cheese, eggs. #2 is cheese. Does not need to be set if already the right number.**
*set lists_replace "bananas"
**This is for what you are putting in place of the previous item**
*gosub_scene twiger_functions replace
**Unlike the find function, this does not have an output, it just changes the list**

That is all for now. Check in later for updates.
I will no longer post untest/non-working versions here. All posted versions are stable.

Super Easy Checkpoint Saving [Updated]
#2

It’s a clever idea to use the string manipulation mechanics to allow for unlimited length. I’m not sure how well it will perform on longer lists/strings, but seeing as there’s no current alternative, I won’t knock it!

Only other thing I’d say is you should test it yourself as well :slight_smile:


#3

HAAAGGHHH!!!
I know you haven’t tested it nor you try it in actual “in-game” simulation, but I can see where you’re going with this snippet of code.

AWWEEE SOOOMM. :star_struck:

But, TBH, it’s pretty hard to get the motivation to try my hand on it. Not especially when you’ve this WIP where you promised everyone to be updated under 7 days :crazy_face:

:exploding_head:


IDK. I think when I have a huge sparetime, I can give your code an actual in-game simulation :wink:


#4

In under seven days, huh? Well this friday I’m leaving for a week long trip, so I’d have to work on it now.
It’s 1 AM and you know what? I’m not tired. I’m going to first test what I have so far, then add some more stuff to it, test that, and then go back to sleep at like 10 am, lol.

Edit: the problem is I’m not far enough into a game to start using list so testing it will take awhile.


#5

These scripts are so long, maybe they should be put into their own scenes.
It will be a while (if ever) before I test just how long these can be/how fast it runs. Right now I’m focused on it working, period.

@Szaal @CJW Here’s a great idea:
What if I made it so people could just copy and paste this whole script into a .txt file in their scenes folder, and all they’d have to do is something like (the ‘fun’ is short for function, since it’s just like custom functions):

*set fun_listname MyList
*set fun_item 1
*set fun_output MyVarible
*goto_scene read

(Tthat scene would have a *return command and leave the output in the MyVariable or whatever they set it as.)


#7

When I think about it, I think this code is suitable for inventory system, but using *temp instead of *create command, perhaps?

I mean, I used similar method of concatenation to make a record of “legendary deeds” of MC’s choice, but that’s about it. A string of text.

It’s not necessarily a bad code, tho. Besides, it’s much more less off-putting to code

rather to go back to startup.txt, *create several new boolean variables, and go back and*set them to true.

But with*temp command, we’ll probably have a less luxury of "permanently-saved value."
Take example of MC enchancing their weapon and have its [DMG] increased by +5. With temp, we’ll probably have to go retrack and re-*set these changes.

But IDK. I guess I’m just rambling. :crazy_face:
We’ll see when I finally can figure a proper system for it.


#8

I specifically use non-temp values because it’s supposed to last the whole game.
Edit: Or did you mean temp variables for the scenes specifically for running the function, in which case, yes, several of those could be temps, thank you.

P.S. can you help me with this problem?:

When I do something like:

*set lists_listname mylist
${lists_listname}#4

or

mylist#4

It always gives me the entire contents of that variable instead of just the 4th character.

I also get this error: Invalid expression, couldn’t extract another token: ${lists_listname}#lists_char = “^”


#9

I think it should be
${mylist#4}

But let me check back the wiki quick.
Here is the link if you want to read it yourself (Search “Text Tricks” section)


About the non-temp variables, I mean there will be these moments where the author “Oh yeah, we’ll probably need a new item. Let’s write the variables for it” and they go back to the startup.txt for etc.etc.

And when you think about it, you might as well write those new variables instead of updating the array and *set the new variables…
unless I’m missing something here?


#10

Yes, this works for that case.

However, still no idea about the token thing and *if {lists_listname}#{lists_char} = “^” doesn’t work either. nor *if ${lists_listname#lists_char} = “^”

I’m not sure what you’re saying here.


#11

I see. You can only do a conditional check with boolean variables, not string.

Your case

is actually doing a conditional check with string. ${lists_listname} don’t contain any TRUE/FALSE value, which should be the reason why you keep getting the “token error.”

Plus, you’d like to put a space between the *if and the #Option. (ex: *if (variable) #Option)
CScript seems don’t particularly fond of it.


Meeh, NVM with that. Not really a big issue, actually.
TBH, I don’t even know what was I’m saying, too :sweat_smile:


#12

But isn’t {lists_listname}#lists_char = "^" one big boolean? or at least ({lists_listname}#lists_char = “^”) should be considered a boolean.
Removing spaced did nothing.

When I change it to: (which probably ruins it anyway)

*if lists_listname#lists_char = "^"

it gives me this error instead:
functions/read line 8: Invalid expression at char 27, expected no more tokens, found: EQUALITY [=]


#13

Hmm… let’s take several steps back here and re-track everything from there.

So you want an #Option that’s only shows up when certain condition is met, right?

And in this case, the condition is (${lists_listname}#list_char = “^”…

wait…

Ah! I see where you’re going! I keep mistaking the # as #Option under *choice ! silly me :sweat_smile: :rofl:
Let me reread your code first :sweat:


#14

O-M-Gosh I forgot that’s very similar the syntax for like hidden/unavailable choice. I see how I confused you.
The full code for it is this:

*comment takes in lists_listname, lists_index, and lists_output

*temp lists_char 0
*temp lists_count 0
*temp lists_string ""
*label alpha
*set lists_char (lists_char + 1)
*if ${lists_listname}#lists_char = "^"
  *set lists_count (lists_count + 1)
  *if lists_count = lists_index
    *goto beta
  *else
    *goto alpha
*else
  *goto alpha

*label beta
*set lists_char (lists_char + 1)
*if ((${lists_listname}#lists_char = "") OR (${lists_listname}#lists_char = "^"))
  *goto endofthisone
*else
  *set lists_string (lists_string & ${lists_listname}#lists_char)
  *goto beta
  
*label endofthisone
*set ${lists_output} lists_string
*return

#15

Alright, got it all sorted.

It’ll be kinda hard to explain, so I’ll just go on with the code.
Try this one

*if ({lists_listname}#list_char = "^")

What I did is removing the $ mark and put the condition on another parentheses.


#19

Yeah. It’s odd because when you use two (maybe less even) variables to find a specific character, it counts as an entire condition, even before the ‘=’, and having two or more conditions requires parenthesis.