Is it any good idea to put 600+ "if branches" (no casting just for some simple variables) on 1 custom event ?

Hi guys,

I have a skill tree and there are some elements connecting those skills. I want to change the material of each connecting pipe that connects this skills. Basicly purchasing a skill lights 1 of those connecting pipes. And it awso depends where you go from which direction to reach the skills and there are multiple of them. So the only idea i came how to do it is to check if skill 1 is active and skill 2 is purchased then the “pipe” element connecting those two will then light up. The problem is that there are around 300 connecting pipes and those need to check even multiple times if i go around to skill 2 which pipe to light up exactly. So i think they may even be more then 600-700+ if branches with multiple conditions depending on the way you reach to the next skill. And now i’m not sure if this is a good idea or the right way to do it. Do someone know or maybe can give me a better advice how this can be properly done ? Something that can be efficient for this type of stuff would be nice. thx

1 Like

If you end up with 600 of almost anything, it probably means there’s a better way of doing things :slight_smile:

It might be better to represent this in some sort of data structure.

While it might be tempting to use structs, I would advise against that. Structs can be a bit of a nightmare, and would make the situation worse.

What you basically have here are skills ( on or off ) and connections with cost.

You could do the whole thing with just a set of arrays:

  1. Skill array ( possibly enums )
  2. Bool array ( true if a skill is enabled )
  3. Connections, which could be done using a map ( dictionary )
  4. Something for the costs also, I’m not sure how that fits in right now ( I don’t get where the cost is in the structure )

Then you need to re-write your algorithm to cope with the new structure. Loops could pop up quite a lot.

This is just one way of doing it, there are many I assume. Very possible, but you’d need to be quite neat :slight_smile:

1 Like

It sounds pretty good unfortunatly im not sure how to do this. From those methods above i like the bool array but i’m unsure how to make it. And i don’t know which one is the best solution for me.

Here is a small example where im unsure how this can be done with the methods above (lack of skill on my side to grasp the logic needed for this). Let’s say there are 4 skills. Skill 2 is in the middle which can be reached from 4 directions like on this image

So comming from skill 1 to 2 in the middle will light this red connection but IF comming from skill 3 to 2 or 4 to 2 then this other one will light up.

Can you show me a simple example how this can be done with any of the above methods? If i would have to pick one i like the bool array lol. My skills do use struct and data table btw.

It’s all one idea :slight_smile:

I’ve already moved on to just enums and maps, but it’s really up to you

Skills

image

Enabled

image

and connections

image

So to check 4 is enabled

image

to discover the connection between 4 and 2

image

and to enable 2

image

It’s just a vague idea right now…

Will this method still requiere to do the 600 if branches ?

I’m not sure if this enumarator will work for me because my skills are awready in a data struct where the info is stored. Can i maybe use the struct info somehow but then i will end up again with those 600+ branches or do i need to make in this case an array of all my connection pipes and then some bool array and then something like for loop with break and compare the index numbers of the array maybe?

You mentioned something about a cost… i do have some variable in my data struct an integer which i don’t use. it was some quantity integer… Maybe i can transform"quantity" integer for a cost to “purchase” a connection pipe just like i purchase a skill… Maybe thats a good idea ? Better to say i push all those 300 connection pipes in the struct/data table and then when i purchase a skill it unlocks some conncetion pipe that is connecting the skills. something along those lines

It’s a recursive concept, you see. You don’t need to have 5000 IFs trailing off over the horizon, because if I have a function that tells me if there’s a path from A to B

path( A, B ) = true

then it doesn’t matter if B is a node or whole tree, it will still work.

Not easy to write, guaranteed, people do go to college to do this kind of thing :slight_smile:

1 Like

You could do it in a way that represents a tree.

Skill 1 { id = “Skill1”, bIsEnabled = false, required [ ] }
Skill 2A { id = “Skill2A”, bIsEnabled = false, required [ “Skill1” ] }
Skill 2B { id = “Skill2B”, bIsEnabled = false, required [ “Skill1”] }

You can check IDs in a loop until the requirement isn’t met. This way you only make checks until they’re not needed anymore.

You can also invert this concept and store the connections in the skill:

Skill 1 { id = “Skill1”, bIsEnabled = false, connections [ “Skill2A”, “Skill2B” ] } and have a list of starting points (the first element of each skill-tree) and make the checks from those, either with for loop or recursively.

Also, ifs (branches) and nesting are very bad things when done in big quantities. IF statements are the arch-enemy of CPUs, so any method you can find to reduce the number of branches/IFs is good.

1 Like

Is this the enumerator method from above ? Sounds really good if it works like this. I’m pretty sure i can make it otherwise with a whole bunch of branches maybe even put all the connection pipes in a struct and give them an integer value pipe 1 value 1 and so and then compare the branches if skill2 is active but not 3 then light up 1 to 2 and so on. But this will be for sure not only a lot of work but very inefficient way to do it i guess performance wise. I intendet to put all this branches on the skill button so every time i purchase a skill it will cycle over 600+ branches… I guess this is bad idea on my side and if i understand this correct the enumarator one sounds way better.

Is for loop with 600 values in it more performance friendly then 600 if branches ?
I will have to think about this and will try later and see if i can manage to create something that works. Ty for the help and ideas so far. I will post later how far i get with this.

At some point, when all 300 traits are activated, you will check them all. But this way if you have no traits active, you only have 1 check.

Also, you could save the data of enabled/active traits and read it directly instead of recalculating every time. Depends on preference. This kind of thing shouldn’t be done every time the user opens the traits menu, it should be checked on load, stored, and updated on the widget so its always ready, and only change the necessary values when the user interacts with the skill-tree.

At least that’s a simple performance-friendly approach. Most of things that are complex or performance intense of data checks that can be done during game/map load are done like this usually, at the time when the user knows things are meant to take time and load.

Ultimately it’s up to you what kind of game you want to make, what approach you want to take and what’s an acceptable or unacceptable performance impact.

No matter what, at least once you’ll have to run through all skills to set the icon and state properly on the interface unless you have them set manually. Even then you’ll have to use some method to look through the skill list to “enable” necessary skill points. That’s why I suggest the “calculate on start-up/load and update only when necessary what is necessary” approach.

1 Like

didn’t read previous replies so apologies if repeating something already mentioned, but…

the reason you dont want 600 branches isn’t because of performance problems, but because of maintenance.
imagine you want to change prioritization or something, or remove a skill, add another. you don’t want to have to find things in a web like that.

if you have an array of structs or some sort of data, you have the computer loop through it. You can have whatever data you want in there. An int for prioritization. A gameplay tag for categorization.
Then you only write a formula for various kinds of checks if you want to choose one skill over another. But the computer actually looks through the big list - not you.

Then if you want to make changes, all you have to do is update the data. Data tables and csv files are very handy for this sort of thing.

1 Like