Coding Efficiency Question

I’m working on a game that is getting very close to an early-demo release. In this game, I’m implementing a mechanic that allows the player to select two npc’s (out of a large selection) to join their squad for any particular ‘mission’ the player encounters.

Every possible squad member will have their own skill-set, so choosing one member over another makes a real difference in the field.

I’ve done most of the head-work to make this system work, and have reached one conundrum:

Is it more efficient to have a different subroutine for each possible squadmate, or to have one subroutine with an *if statement for every possible squadmate?

Here’s how that might look:

(different subroutine for every possible squadmate):
Who do you want to join your squad?
#Bob
*gosub bob
#Sue
*gosub sue
#Meep
*gosub meep

*label bob
*set squadmate1 “Bob”
*set squadmate1_skill1 20
*set squadmate1_skill2 40
*set squadmate1_skill3 10
*return
*label sue
*set squadmate1 “Sue”
*set squadmate1_skill1 40
*set squadmate1_skill2 10
*set squadmate1_skill3 20
*return
*label meep
*set squadmate1 “Meep”
*set squadmate1_skill1 10
*set squadmate1_skill2 20
*set squadmate1_skill3 40
*return

or

(if statement for every possible squadmate):
Who do you want to join your squad?
#Bob
*set squadmate1 “BoB”
*gosub squadmate1
#Sue
*set squadmate1 “Sue”
*gosub squadmate1
#Meep
*set squadmate1 “Meep”
*gosub squadmate1

*label squadmate1
*if (squadmate1 = “Bob”)
*set squadmate1_skill1 20
*set squadmate1_skill2 40
*set squadmate1_skill3 10
*if (squadmate1 = “Sue”)
*set squadmate1_skill1 40
*set squadmate1_skill2 10
*set squadmate1_skill3 20
*if (squadmate1 = “Meep”)
*set squadmate1_skill1 10
*set squadmate1_skill2 20
*set squadmate1_skill3 40
*return

Yes, I know these lines don’t have the correct spacing for them to actually work, this is just an example.

Anyways, let me know which one y’all think would be better.

1 Like

The two don’t seem to have that much difference efficiency-wise, so it ultimately depends on which one is easier for you personally to code and understand.

2 Likes

If you’re looking for efficiency, utilizing the { } and tokens could help. So that the code can be condensed into something like this. In the code, I’ll be assuming there’s more than one mission and you can choose a different companion.

*comment This would be startup.txt
*comment Companions labeled for convenience.
*create current_companion ""

*label Bob
*create skill1_bob 10
*create skill2_bob 20

*label Sue
*create skill1_sue 20
*create skill2_sue 10

What companion do you want?
*fake_choice
   #Bob
      *set current_companion "bob"
   #Sue
      *set current_companion "sue"

And then you can use the variables in later files with more efficiency.

What is my companion's skill one?
*print skill1[current_companion]

*comment "*print skill1_{current_companion}" should also work.

What is my companion's skill two?
*print skill2[current_companion]

At least, it should work. I can’t test it right now. Difference between { } and. is that adds an _ to the front.

2 Likes

Why not include the code into the choice itself? But if you really need to separate it into a sub-routine, then I believe the first option is best. But, really, there isn’t much of a difference in terms of efficiency—unless you mean something else by that, because I’m thinking about computational efficiency.

However, if you decide to go with the if statements, you should consider using else-if statements for the following conditionals instead.

2 Likes

I’d like to point out that *print is deprecated command. You’re encouraged to do ${skill1[current_companion]} instead.

To OP, both version seems fine. What is the most important in the end is the clarity and readability itself. The most efficient code is the most unreadable code.

5 Likes

Organizational purposes, mostly. Plus, doing so would mean I’d need to copy and paste the same code over and over potentially hundreds of times. It’s just more logical to have it as a subroutine at that point.

As for if vs elseif statements, there isn’t any functional difference using one or the other, given the particular context that this code appears in, so it’s marginally easier for me to just use *if. Though you wouldn’t know that from the content of this post alone. But I appreciate the advice nonetheless!

1 Like

I hadn’t considered using that at all… huh.

This might be really useful to me, actually.

Thank you!!

I guess for the purpose of keeping it clear (and thus easier to edit/adjust) the first option would make more sense.

Thanks for the insight!

I can see what you mean here. In that case I think I’m going with the first option, since it’d be a little more clear what I’m looking at if/when I need to go back and change something in it.

I think its easier code wise to have a single file where the player chooses their partner. Then you can use *gosub_scene character_select

then you can send players to it whenever you need them to choose.

That’s how its coded in UnNatural. Ditto for the weapon choice a separate file for the weapon options then I use *gosub_scene to send players there.

1 Like

Way ahead of you on that :wink:

I only had it all on the same page here to make it clearer to see what the code was doing. Otherwise, I keep all my subroutines on a separate page/scene.

Still, very good advice! Definitely helps keep things neat and tidy.

2 Likes

Another way I can think of is if you use two dimensional arrays to store all stats of a character, and then you can use the same gosub to set squadmate 1 and squadmate 2 by sending parameters of the current slot you wanna fill and the companion id.

I haven’t tested this but its just to give an idea:

Suppose you have their stats on arrays like this:

*create ally_1_1 "Bob" //This is the name
*create ally_1_2 20 //This is skill 1
*create ally_1_3 40 //This is skill 2
*create ally_1_4 10 //This is skill 3

*create ally_1_1 "Bob"
*create ally_1_2 20 //This is skill 1
*create ally_1_3 40 //This is skill 2
*create ally_1_4 10 //This is skill 3

*create ally_1_1 "Bob" //This is the name
*create ally_1_2 20 //This is skill 1
*create ally_1_3 40 //This is skill 2
*create ally_1_4 10 //This is skill 3

But you only have 2 squad slots, which you can fill like this:

*create squadmate_1_1 ""
*create squadmate_1_2 0
*create squadmate_1_3 0
*create squadmate_1_4 0

*create squadmate_2_1 ""
*create squadmate_2_2 0
*create squadmate_2_3 0
*create squadmate_2_4 0

For the setSquadmate gosub it will receive the current squadmate array you are filling (if its squadmate_1 or squadmate_2) and the “id” of the ally (the first number of their arrays).

It will loop and add each attribute you have for characters (assuming they all have a name and 3 skills, it will run the loop 4 times and set each squadmate array all of the attributes of the ally with that id).

*label setSquadmate
*params squadSlot allyId
*temp attribute_count 0
*label setterLoop
*set attribute_count + 1

*if (attribute_count > 4)
  *set currentSquadmateSlot + 1
  *return

*set squadmate[squadSlot][attribute_count] ally[allyId][attribute_count]

*goto setterLoop

To select a companion to be assigned to each of the squadmate arrays you just need to pass the current slot you wanna fill and their id like I said before.

This screen should proceed only if you selected 2 people and then it should show their names.

*hide_reuse
*temp currentSquadmateSlot 1
*label setSquadmateChoices

Who do you want to join your squad?

*choice
  *selectable_if (currentSquadmate < 3) #Bob.
    *gosub setSquadmate currentSquadmateSlot 1
  *selectable_if (currentSquadmate < 3) #Sue.
    *gosub setSquadmate currentSquadmateSlot 2
  *selectable_if (currentSquadmate < 3) #Meep.
    *gosub setSquadmate currentSquadmateSlot 3
  *selectable_if (currentSquadmate >= 3) #Continue.
    *goto companionsSelected

*goto setSquadmateChoices

*label companionsSelected

Your current squadmates are: ${squadmate[1][1]} and ${squadmate[2][1]}.
3 Likes

So if I’m understanding you right, the code will loop back to the choice until you’ve picked a first and second ally?

I can see how that’d be more efficient than having 2 separate choice blocks… maybe I’ll give it a try!

1 Like