Well, it is certainly laborious, and definitely a challenge for a beginner. But don’t be discouraged, it is not as difficult as it sounds.
My first advice is to break what you want to do into smaller tasks. This is, by the way, how professional developers write code. You already started doing that when you devised you needed to sort the order first. Great. Now break that into smaller pieces and then those pieces into smaller ones until it becomes something you can manage.
Getting familiar with ChoiceScript features will help a lot. You might also want to take a look at CSLIB, a collection of ready made subroutines for various purposes.
Here’s a starting solution, I’m writing it from the top of my head, so there’s bound to be bugs and improvements.
Combat System
Define Order
- Sort party members by dexterity
- Since this will be a piece of code you’ll use multiple times throughout the game, you want to keep it as a subroutine in a dedicated scene file. However, ChoiceScript does not have a way to return values from a subroutine, which means you’ll have to set up global variables to hold the value of any computation done through subroutines.
- So, first, set up the variables that’ll hold the party order. If the party number is variable, create a list (array) considering the maximum size it can ever have. You can create each variable manually or use the new command
*create_array
(keep in mind that it may not be supported by CSIDE, DashingDon and other developer tools).*comment startup.txt *create party_1 "" *create party_2 "" *create party_3 "" *create party_4 "" *comment OR *create_array party 4 ""
- Make sure the variables for each party member has consistency naming so it’ll be easier to refer to dynamically. For example:
*create mc_dex 20 *create phillipa_dex 20 *create jordan_dex 20 *create ariel_dex 20 ...
- Supposing you have many characters that could join the party at one point or another, save the id to the “active” party member in the party array, so it looks like this:
*set party_1 "mc" *set party_2 "phillipa" *set party_3 "jordan" *set party_4 "ariel"
- Then loop through the list sorting by attribute. Here’s a possible implementation. The empty comment lines inside the subroutine is to organize the code while preventing ChoiceScript from printing undesired empty lines int he output text.
*comment ====== *comment SORTBY *comment ====== *comment This subroutine will sort the values in decreasing order *comment "in-place", meaning it will swap the values from one position *comment to another in the array. *comment *comment It uses a simple selection sort algorithm adapted *comment to ChoiceScript. It loops through the array twice *comment comparing the values by reference. *comment *comment It takes 3 mandatory parameters: *comment *comment - attr (string): the name of the attribute to be checked *comment - array (string): the name of the array *comment - len (number): the length of the array, or maximum index *comment to be checked *comment *comment The array should not hold the values themselves, but a *comment reference (id) to other variables. For example, "party_1" *comment has the values "mc" and the variable "mc_dex" has the *comment actual dexterity value. *comment *comment Usage example: *comment *gosub sortBy "dex" "party" party_len *comment *comment Considering the existing variables: *comment *create mc_dex 55 *comment *create jordan_dex 40 *comment *create phillipa_dex 70 *comment *create ariel_dex 45 *comment *comment *create party_len 4 *comment *create party_1 "mc" *comment *create party_2 "jordan" *comment *create party_3 "phillipa" *comment *create party_4 "ariel" *label sortBy *params attr array len *temp i_ 1 *label sortByOuterLoop *if (i_ > len) *goto endSortByOuterLoop *comment *temp swapIndex i_ *comment *temp j_ (i_ + 1) *label sortByInnerLoop *if (j_ > len) *goto endSortByInnerLoop *comment *if ({{"${array}_${j_}"}&"_${attr}"} > {{"${array}_${swapIndex}"}&"_${attr}"}) *set swapIndex j_ *comment *set j_ (j_ + 1) *goto sortByInnerLoop *label endSortByInnerLoop *comment *if (swapIndex != i_) *temp temp_ {"${array}_${i_}"} *set {"${array}_${i_}"} {"${array}_${swapIndex}"} *set {"${array}_${swapIndex}"} temp_ *comment *set i_ (i_ + 1) *goto sortByOuterLoop *label endSortByOuterLoop *return
Combat Loop
- Now you have an array sorted by the desired attribute (dexterity) and by the previous example you can learn how to loop through an array and how to access values by reference. Write a subroutine that goes through the array and implement the specific combat mechanic you want. You don’t need a Queue or change the current order after sorting. Just loop over the array.
- Remember to skip party members which have zero HP left.