I was debugging through this code and it did execute. Something I noticed when debugging is that the trigger had no events after adding one. The player[p].base.base = Orbitial Command(player 1). However, for some reason whenever anything dies GameOverFFAPlayer1_Func executes. BTW I enable the trigger at about 30 seconds into the game after the mode is picked. I have no other code that is causing the issue, everything is executing in the correct order, I have already checked everything I would think to check. I feel it has something to do with UnitRefFromVariable... Any ideas?
Must be returning a null reference. References to null are by default assumed to mean all units so will fire when any unit does.
I am guessing you have one of the triggers enabled at some stage when the referenced variable assigned to the event is null? That would cause it to fire for all deaths on the map so even a single such trigger for a player (who might not be there so have no base?) would suffice to create such an error. The solution in this case would be to either never create triggers for players who will not get a base or to not enable triggers for players without bases. Under no circumstances should you have such a trigger enabled with an event referencing a null variable.
An alternative approach for the above is to disable the null means everyone interpretation. There exists a specific native which can turn this behaviour on and off for all triggers. If you do not need the feature you can use it to solve a referenced null unit event firing for all units. If you do want to use events which fire for all units you cannot do this.
If the above is not helping check if the editor supports dynamic variable names with references. It could be that the argument is parsed quite literally rather than evaluated since some times compiler developers do hacky things like that be it for speed or simplicity.
The base variable is set at map init. And, the trigger is enabled about 30 seconds into the game. I was debugging the base variable is correct, the string is correct. However, for some reason, the unit ref is null. I am not enabling any triggers for players that arent playing.
Does not allow dynamic changing of the event unit during runtime. I assume he wants to dynamically change the event unit during run time otherwise he would be using that native already. If he uses static unit references he would then need to perform dynamic event attachment and trigger reconstruction (destroy old, create new) to change the referenced unit.
I am guessing that the "UnitRefFromVariable" function expects a qualified variable name only as the argument string. It must be lacking the capability to parse arrays or structs which is why it does not work. This is strange and must be an error present in GUI as I was able to get GUI to construct a string parameter of the same format as is not working. I did not test if it works however, something someone should do.
Just as a test, what miles said works. However, yes I want the ref set to the base variable not to an instance of the initial unit it is set to. Man if only the editor let me deal with references or pointers with full capability this would all be solved.
If the unit is not fixed I recommend using a generic "unit dies" event and a condition to check for the right unit.
While it introduces some overhead because it will trigger for all units, most of the time this is non critical and doesnt matter. If you want a "clean" solution you can do what ImperialGood suggested and reconstruct the trigger everytime the unit changes. Due to its increased complexity I would not recommend that though.
Always remember that premature optimization is the root of all evil. I personally think that even if UnitRefFromVariable worked it is a very unclean style and I would still not use it. What if you rename the variable for example? Just go for the easiest way and profile your project once you are done.
If the unit is not fixed I recommend using a generic "unit dies" event and a condition to check for the right unit.
Inefficient. In this case I would much rather recommend a hybrid data solution than that. Buff behaviour with on death dummy effect given to the specific units. Trigger then fires when the dummy effect runs and resolves for which player it is for. This reduces the number of trigger event fires from every unit death to only appropriate units.
Quote:
What if you rename the variable for example?
You could use a string constant for that declared just above the variable name. As such if you rename one you will see to rename the other.
The problem is micro optimization being the route of all evil and not "premature optimization". It is always good to plan to do something efficiently from the start rather than end up with a mess which is slow to execute. One of the biggest problems I see is people using generic events when specific target events are more appropriate.
Sure who cares if it actually has no visible performance impact, but what if it starts to? You just have to go back through all your triggers and change them to specific events, something you could have done from the start and saved all that time. Never underestimate the difference using the appropriate algorithm makes. Sure a linear search is easy to implement but if you are dealing with a list of 200-500 elements multiple times a second you would be silly to not use a faster algorithm from the start rather than go back at a later time to fix it.
I appreciate the responses. I know I am not the best at galaxy scripting and am just starting to get the hang of it. I feel ImperalGoods first solution of recreating the trigger would be most optimal and will probably do that once the rest of my map is working again. I actually am very good at optimizing code, most would call me an expert. I wrote my own guide to optimizing c code a few months ago. I am not exactly sure how galaxy events(triggers) check for conditions. So let me know if I am thinking about it wrong.
Yes, I can see how generic events could be a problem, calling function pointers over an over(that is what they would use internally), vs a condition to call it is much slower. However, in some cases a generic may be better. I feel they are in my case with the civ system. I originally had about 50 triggers for spawning units, trigger condition = unit enters region. I converted it to a single every 2.0 seconds in a loop, the first condition of the function checks if any unit is in the region. Considering it takes a bit of math to determine if a unit enters a region, it does that 50 times, 16 times a second; that would be slower than every 2 seconds check them all. Let me know if I am wrong, but I believe events in galaxy work by checking a certain condition 16 times a second right?
Thanks again everyone, but specifically ImperalGood for helping me get everything working.
Yes, I can see how generic events could be a problem, calling function pointers over an over(that is what they would use internally), vs a condition to call it is much slower. However, in some cases a generic may be better. I feel they are in my case with the civ system. I originally had about 50 triggers for spawning units, trigger condition = unit enters region. I converted it to a single every 2.0 seconds in a loop, the first condition of the function checks if any unit is in the region. Considering it takes a bit of math to determine if a unit enters a region, it does that 50 times, 16 times a second; that would be slower than every 2 seconds check them all. Let me know if I am wrong, but I believe events in galaxy work by checking a certain condition 16 times a second right?
I doubt your solution is more efficient because the game will use internal quad trees (or other such 2D positional structures) to locate appropriate regions nearby and test only those if the new unit's position is within them. If it is then it would generate the event and run the trigger. As such a region in the middle of nowhere with no units nearby probably does not consume any resources even if it has both an entry and exit event attached to it. Further more these checks for entering and exiting nearby regions are probably performed regardless of there being regions which need them since it probably shares the same positional checking system as used by data and other things.
I am a bit clueless why you had to use "50" triggers for this. You are aware that you can register more than 1 event to a trigger right? You can also get which region was entered to fire the trigger with the appropriate native. As such a single trigger would suffice with a linear search to identify the appropriate indexes in an array for a data fed system.
Didn't think of it exactly like that. Now that I think about it though, the editor added else's for all my ifs and such so yea it probably already does the checks. Yea I know I can add multiple events to a trigger. I did it this way at first because doing sunit enters any region would fire probably every frame in my map. Searching for the correct region would be even slower than 50 separate triggers. 50 separate triggers is just too long for me and feels a very crude and bad solution. Oh also, I wanted to have the delay in between to prevent from buying the wrong units. If you have a better idea let me know.
No offense, but I think you guys are way overthinking this problem.
Realistically, how many units will die during a game? How many will die per second? Probably not too many. Not to say that the unit check will be stupid fast.
Of course you can do whatever you like, I personally would still recommend going for the "easy route" here and use a generic event, unless for some reason in your game there are a ridiculous amount of dying units all over the place.
While I agree that in most cases its a good approach to make the events as specific as possible, I think one always needs to make a cost <> benefit decision, and if you are trying to create the absolute perfect code for every single thing you do you will probably never get your project done. In a perfect world every piece of code is thought out and optimized, but from my experience reality is different because it actually NEEDS to be to get stuff done in reasonable time.
You both make excellent points. I personally however tend to optimize my code as much as possible.
As cplusplus is my main language, it is built for performance and is probably the fastest, most widely supported oop language out there. I tend to write most of my projects in cplusplus, people call me crazy for doing so. Most of my recent projects have been for networking and are fairly lightweight due to the optimization I did.
Let's say I write I game in c++ with directx. Someone else writes the same game in csharp with XNA. Another, writes it in python with some windows draw functions. Everyone starts from scratch no framework or anything just the gfx API and standard libraries. Python takes 3 months, average fps is 20. Csharp takes 8 months with average fps of 40. Cplusplus takes 2 years with average fps of 80(vysnc is usually on if your smart and caps it at your monitors refreshrate, normally 60). These times and performances are a guess and theoretical only.I dont know about you, but which game would you want to play?
That being said it is a matter of productivity vs performance. Which do you value more? For games it should always be performance. In other things it depends. Personally, I write most of my code so it performs well, I often get questions about why I prefer cplusplus over csharp and I could go into that but I wont. It all comes down to how low-level you want to go. Nobody writes games in ASM or VB. ASM would take WAY too long, VB would be WAY to slow. I am used to really low level coding and thats why I prefer galaxy script over GUI.
I am also a very example-explanation oriented person. I like to know why and how things actually work and what kind of code they compile. In conclusion, in many cases some of us overthink it. But, it is my nature to do things efficently. That being said I should probably balance my time more towards productivity, but I am still leaned more towards performance.
Okay I am having problems with some triggers executing when they are not supposed to. So I have this code here:
I was debugging through this code and it did execute. Something I noticed when debugging is that the trigger had no events after adding one. The player[p].base.base = Orbitial Command(player 1). However, for some reason whenever anything dies GameOverFFAPlayer1_Func executes. BTW I enable the trigger at about 30 seconds into the game after the mode is picked. I have no other code that is causing the issue, everything is executing in the correct order, I have already checked everything I would think to check. I feel it has something to do with UnitRefFromVariable... Any ideas?
The code...
Must be returning a null reference. References to null are by default assumed to mean all units so will fire when any unit does.
I am guessing you have one of the triggers enabled at some stage when the referenced variable assigned to the event is null? That would cause it to fire for all deaths on the map so even a single such trigger for a player (who might not be there so have no base?) would suffice to create such an error. The solution in this case would be to either never create triggers for players who will not get a base or to not enable triggers for players without bases. Under no circumstances should you have such a trigger enabled with an event referencing a null variable.
An alternative approach for the above is to disable the null means everyone interpretation. There exists a specific native which can turn this behaviour on and off for all triggers. If you do not need the feature you can use it to solve a referenced null unit event firing for all units. If you do want to use events which fire for all units you cannot do this.
If the above is not helping check if the editor supports dynamic variable names with references. It could be that the argument is parsed quite literally rather than evaluated since some times compiler developers do hacky things like that be it for speed or simplicity.
@ImperialGood: Go
The base variable is set at map init. And, the trigger is enabled about 30 seconds into the game. I was debugging the base variable is correct, the string is correct. However, for some reason, the unit ref is null. I am not enabling any triggers for players that arent playing.
I found this thread http://www.sc2mapster.com/forums/development/galaxy-scripting-and-trigger-lib/40647-arrays-in-an-event-doesnt-work/ Seems it should interpret it correctly, unless structs aren't interpreted correctly.
I am confused out of my mind... Is there anything else I can try? Would seeing more code help?( I don't want to bombard you with code xD )
Try
instead.
Does not allow dynamic changing of the event unit during runtime. I assume he wants to dynamically change the event unit during run time otherwise he would be using that native already. If he uses static unit references he would then need to perform dynamic event attachment and trigger reconstruction (destroy old, create new) to change the referenced unit.
I am guessing that the "UnitRefFromVariable" function expects a qualified variable name only as the argument string. It must be lacking the capability to parse arrays or structs which is why it does not work. This is strange and must be an error present in GUI as I was able to get GUI to construct a string parameter of the same format as is not working. I did not test if it works however, something someone should do.
Just as a test, what miles said works. However, yes I want the ref set to the base variable not to an instance of the initial unit it is set to. Man if only the editor let me deal with references or pointers with full capability this would all be solved.
If the unit is not fixed I recommend using a generic "unit dies" event and a condition to check for the right unit.
While it introduces some overhead because it will trigger for all units, most of the time this is non critical and doesnt matter. If you want a "clean" solution you can do what ImperialGood suggested and reconstruct the trigger everytime the unit changes. Due to its increased complexity I would not recommend that though.
Always remember that premature optimization is the root of all evil. I personally think that even if UnitRefFromVariable worked it is a very unclean style and I would still not use it. What if you rename the variable for example? Just go for the easiest way and profile your project once you are done.
Inefficient. In this case I would much rather recommend a hybrid data solution than that. Buff behaviour with on death dummy effect given to the specific units. Trigger then fires when the dummy effect runs and resolves for which player it is for. This reduces the number of trigger event fires from every unit death to only appropriate units.
You could use a string constant for that declared just above the variable name. As such if you rename one you will see to rename the other.
The problem is micro optimization being the route of all evil and not "premature optimization". It is always good to plan to do something efficiently from the start rather than end up with a mess which is slow to execute. One of the biggest problems I see is people using generic events when specific target events are more appropriate.
Sure who cares if it actually has no visible performance impact, but what if it starts to? You just have to go back through all your triggers and change them to specific events, something you could have done from the start and saved all that time. Never underestimate the difference using the appropriate algorithm makes. Sure a linear search is easy to implement but if you are dealing with a list of 200-500 elements multiple times a second you would be silly to not use a faster algorithm from the start rather than go back at a later time to fix it.
I appreciate the responses. I know I am not the best at galaxy scripting and am just starting to get the hang of it. I feel ImperalGoods first solution of recreating the trigger would be most optimal and will probably do that once the rest of my map is working again. I actually am very good at optimizing code, most would call me an expert. I wrote my own guide to optimizing c code a few months ago. I am not exactly sure how galaxy events(triggers) check for conditions. So let me know if I am thinking about it wrong.
Yes, I can see how generic events could be a problem, calling function pointers over an over(that is what they would use internally), vs a condition to call it is much slower. However, in some cases a generic may be better. I feel they are in my case with the civ system. I originally had about 50 triggers for spawning units, trigger condition = unit enters region. I converted it to a single every 2.0 seconds in a loop, the first condition of the function checks if any unit is in the region. Considering it takes a bit of math to determine if a unit enters a region, it does that 50 times, 16 times a second; that would be slower than every 2 seconds check them all. Let me know if I am wrong, but I believe events in galaxy work by checking a certain condition 16 times a second right?
Thanks again everyone, but specifically ImperalGood for helping me get everything working.
I doubt your solution is more efficient because the game will use internal quad trees (or other such 2D positional structures) to locate appropriate regions nearby and test only those if the new unit's position is within them. If it is then it would generate the event and run the trigger. As such a region in the middle of nowhere with no units nearby probably does not consume any resources even if it has both an entry and exit event attached to it. Further more these checks for entering and exiting nearby regions are probably performed regardless of there being regions which need them since it probably shares the same positional checking system as used by data and other things.
I am a bit clueless why you had to use "50" triggers for this. You are aware that you can register more than 1 event to a trigger right? You can also get which region was entered to fire the trigger with the appropriate native. As such a single trigger would suffice with a linear search to identify the appropriate indexes in an array for a data fed system.
Didn't think of it exactly like that. Now that I think about it though, the editor added else's for all my ifs and such so yea it probably already does the checks. Yea I know I can add multiple events to a trigger. I did it this way at first because doing sunit enters any region would fire probably every frame in my map. Searching for the correct region would be even slower than 50 separate triggers. 50 separate triggers is just too long for me and feels a very crude and bad solution. Oh also, I wanted to have the delay in between to prevent from buying the wrong units. If you have a better idea let me know.
No offense, but I think you guys are way overthinking this problem.
Realistically, how many units will die during a game? How many will die per second? Probably not too many. Not to say that the unit check will be stupid fast.
Of course you can do whatever you like, I personally would still recommend going for the "easy route" here and use a generic event, unless for some reason in your game there are a ridiculous amount of dying units all over the place.
While I agree that in most cases its a good approach to make the events as specific as possible, I think one always needs to make a cost <> benefit decision, and if you are trying to create the absolute perfect code for every single thing you do you will probably never get your project done. In a perfect world every piece of code is thought out and optimized, but from my experience reality is different because it actually NEEDS to be to get stuff done in reasonable time.
You both make excellent points. I personally however tend to optimize my code as much as possible.
As cplusplus is my main language, it is built for performance and is probably the fastest, most widely supported oop language out there. I tend to write most of my projects in cplusplus, people call me crazy for doing so. Most of my recent projects have been for networking and are fairly lightweight due to the optimization I did.
Let's say I write I game in c++ with directx. Someone else writes the same game in csharp with XNA. Another, writes it in python with some windows draw functions. Everyone starts from scratch no framework or anything just the gfx API and standard libraries. Python takes 3 months, average fps is 20. Csharp takes 8 months with average fps of 40. Cplusplus takes 2 years with average fps of 80(vysnc is usually on if your smart and caps it at your monitors refreshrate, normally 60). These times and performances are a guess and theoretical only.I dont know about you, but which game would you want to play?
That being said it is a matter of productivity vs performance. Which do you value more? For games it should always be performance. In other things it depends. Personally, I write most of my code so it performs well, I often get questions about why I prefer cplusplus over csharp and I could go into that but I wont. It all comes down to how low-level you want to go. Nobody writes games in ASM or VB. ASM would take WAY too long, VB would be WAY to slow. I am used to really low level coding and thats why I prefer galaxy script over GUI.
I am also a very example-explanation oriented person. I like to know why and how things actually work and what kind of code they compile. In conclusion, in many cases some of us overthink it. But, it is my nature to do things efficently. That being said I should probably balance my time more towards productivity, but I am still leaned more towards performance.
Again, thank you everyone for your replies.