I have been told that running the mouse move trigger to get the mouse location is a bad thing (lags the game), better to run it in a loop then executing new triggers. I have been trying this but i cant seam to get the new mouse location in the world unless i use that trigger its like it only update one time and that is when that trigger run so a while loop.
True, but that's not the underlying problem in his trigger.
@Sherlia
Set a local integer variable to Triggering Player at the start of your trigger's actions (or define it when you create the local variable.) Then refer to that local variable instead of (triggering player). The problem occurs when you introduce a wait function in conjunction with using (triggering player.)
I have a diablo like movement system. Unit follow mouse when left mouse btn down. I have to updating the mouse location on mouse movement but i have heard that doing this make it run the trigger like crazy and this causes lag on the server (locally its fine). So what i want to do it get the mouse move location without running the mouse move trigger over and over. Best solution so far is to limit the amount of time the trigger can run and with some testing i have set it to 0.06 real time seconds. This give me strangely enough 8 times per real time seconds (did run some test triggers to measure this) witch is in fact 0,125 per trigger and not 0.06.
To make it super simple, i want as little trigger as possible to run to reduce lag.
I understand what you say but i don't understand how to store the mouse position without using the trigger. The only way to get the mouse location is from the trigger when mouse is moved or clicked.
If you can show how to "get" the mouse location without using the value in the image then i would be very happy!
Why do you need to update the mouse coordinates only when the left mouse button is down? You can just run a trigger from any event (map initialization, for example) then use a Repeat Forever loop to set the variables to the mouse pointer coordinates. No turning triggers off, no conditions, etc.
Yes i would really like to do that but if you can make an example map of that very easy thing that i would be extremely happy because i can't do it at all.
If you can show me that one simple row on how to load a variable with the mouse coordinates then that would solve all problems. So far many have said to do just that and even i would have said it but i have not found one single way to do it.
Here i even made a sample map for you, all you have to do is fix the variable.
Ah, I see the problem. There's no function to directly refer to a player's mouse UI position. Back to the drawing board... let me see what I can dig up.
The only way i have found it to get the position is if its run in a event trigger that check if mouse is moved or clicked. I did the loop inside that trigger hoping it would update it but it only get the value of the mouse location the instant the trigger runs and not while it runs. So the only way to make this work well is if we find a way to get mouse position without running it in a trigger.
To put it plain, blizzard have not included that function as far as i know :(
Since I've recently dealt with that input stuff again, I should post the collection of my knowledge regarding mouse/button input:
On battle.net, the mouse move event will be fired 15-22 times per player per game loop (most likely not every game loop due to latency changes).
Most likely you would want the last position where the mouse has been, so you are required to save the position of the player's last event ("last event" according to A1win). To do so, you are required to save all input data as checking anything just easily adds a lot more overhead than just saving the values.
To properly use the input data, you should have one thread that processes it for each player in every game loop. Since code in a thread can run up to two times between the game updates, you would want to make sure that the input-using code runs after the new input was thrown in. So, it should run in the second code execution phase and not during the first. To push the execution from the first to the second phase, you need to add a wait of exactly 0.0 game seconds in addition to your normal wait (like 0.0625 game seconds) [yes, you are using 2 waits!].
That's what I'm currently using in my WASD shooter and it seems to run fine. But I didn't test how many players this can support. Since A1win did essentially the same and he told me that his implementation works fine for 8 players, I assume that my approach will run the equally good.
- A: In addition to that, there might be optimization possibilities. Mille25 reported that they are disabling triggers which appears to stop input events from being sent. But I don't know any details or had no chance to test that. In case this is true, it might be possible to enable/disable the bandwith usage for that system when it is not required.
- Btw, I've noticed that JademusSreg toggled the values of the saved button inputs instead of setting values to true/false based on the event. I've tested that and they do not seem to fail at all!
Setting values to true/false has problems when you double-hit a button within one game frame as the input state will be corrupted. It will process "down, down, up" resulting in a saved "no input"-state while the player is in fact holding down the button after that. -> Toggles handle that case properly and should be used.
- B: Another aspect that hasn't been researched, yet, is that if it is better to use one generic event or only the specific buttons for a player.
Also, it is possible to block button presses from being detected by the events, if you are using that button in a toggle in your game's UI. In case every normal button press is creating bandwith usage, you should be able to reduce it using these UI xml toggles.
If we would know the unclear aspects A and B, it might be possible to create the bnet-performance-wise best implementation.
Sadly there is alot of misinformation that is just plain wrong in this thread.
Mouse coordinates can just be retrieved in response to the mouse moved event, so there is no way around creating a mouse moved trigger and responding to it.
The reason why mouse move triggers can cause lag can be split into two areas.
1) CPU overhead. The mouse moved event is the most often firing event in the entire game (it can fire multiple times per game loop), and therefore every form of expensive code in response to mouse moved events must be avoided. The mouse moved trigger itself should just store the current mouse position of the triggering player in a global variable, which then can be processed by other parts of the code (less frequently, for example with a 0 time periodic or a 0 second wait loop).
2) Network lag. The network lag happens because a network query needs to be sent to all players on every input event they make (As stated in the official documentation of all player input events, such as key presses.). The best way to reduce the network lag to a minimum is to TURN OFF the mouse moved trigger WHENEVER POSSIBLE. Rapidly turning it on and off may help a little, but i rather recommend thinking about if the trigger is really constantly needed.
As an example, if the mouse tracking is just required for specific abilities or missions, the trigger should be turned off while those are not active to avoid unnecessary network traffic.
I didnt study your code in depth, but you can probably get rid of the condition in the mouse moved trigger since it shouldnt be on anyways if a player is not pressing down the mouse (Therefore the condition just adds an unnecessary check.).
I would also recommend getting rid of the turn on/off stuff and the waits in the mouse moved trigger itself. All it does is reducing the precision and it can also very well create bugs in your game.
For example, consider this scenario:
What happens if a player releases the mouse button very shortly after he pressed it? Is his mouse moved trigger on or off?
I also personally dislike the idea of splitting the mouse moved trigger into multiple instances, one for every player. While it may in theory be possible that it is more efficient, it has not yet been proven and it will be very hard to do so. However, it adds alot of duplicated code and is just by itself a very ugly design, screaming for errors. It also adds overhead to other places of code, such as the mouse key press switch cases and also map and variable initialization.
You should always put code quality prior to performance, and just if it is absolutely necessary consider further steps to optimize code.
I also personally dislike the idea of splitting the mouse moved trigger into multiple instances, one for every player. While it may in theory be possible that it is more efficient, it has not yet been proven and it will be very hard to do so. However, it adds a lot of duplicated code and is just by itself a very ugly design, screaming for errors. It also adds overhead to other places of code, such as the mouse key press switch cases and also map and variable initialization.
Yes i also do not like this at all and prefer to have it all in one trigger but how exactly is that supposed to be made? Only way to get the mouse location is by this trigger.
Regarding the quick click question, would it not just be easy to add a check that waits until the trigger is on before turning it off so it does not stay on?
You can use a player group to figure out if any player is still holding down the left mouse button. Simply add the triggering player to the group when he pressed the left mouse button down and remove him once he releases the button. If the player group is empty you can disable the global mouse moved trigger, otherwise it needs to remain on.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
I have been told that running the mouse move trigger to get the mouse location is a bad thing (lags the game), better to run it in a loop then executing new triggers. I have been trying this but i cant seam to get the new mouse location in the world unless i use that trigger its like it only update one time and that is when that trigger run so a while loop.
Any suggestions or solutions to it?
I imagine using a periodic event instead of a while loop would probably fix it.
@MaskedImposter: Go
True, but that's not the underlying problem in his trigger.
@Sherlia
Set a local integer variable to Triggering Player at the start of your trigger's actions (or define it when you create the local variable.) Then refer to that local variable instead of (triggering player). The problem occurs when you introduce a wait function in conjunction with using (triggering player.)
dont worry about the other player thing, i just want it working for one player atm, i just make one trigger for each player
I tested like in the image now but still the exact same result.
I did it like this. Now it turn the trigger off for 0.01 sec and then turn it on again. Best solution i have so far but the response is a bit slow.
I'm sorry, i dont fully understand what you mean.
I have a diablo like movement system. Unit follow mouse when left mouse btn down. I have to updating the mouse location on mouse movement but i have heard that doing this make it run the trigger like crazy and this causes lag on the server (locally its fine). So what i want to do it get the mouse move location without running the mouse move trigger over and over. Best solution so far is to limit the amount of time the trigger can run and with some testing i have set it to 0.06 real time seconds. This give me strangely enough 8 times per real time seconds (did run some test triggers to measure this) witch is in fact 0,125 per trigger and not 0.06.
To make it super simple, i want as little trigger as possible to run to reduce lag.
I understand what you say but i don't understand how to store the mouse position without using the trigger. The only way to get the mouse location is from the trigger when mouse is moved or clicked.
If you can show how to "get" the mouse location without using the value in the image then i would be very happy!
Why do you need to update the mouse coordinates only when the left mouse button is down? You can just run a trigger from any event (map initialization, for example) then use a Repeat Forever loop to set the variables to the mouse pointer coordinates. No turning triggers off, no conditions, etc.
@BasharTeg: Go
Yes i would really like to do that but if you can make an example map of that very easy thing that i would be extremely happy because i can't do it at all.
If you can show me that one simple row on how to load a variable with the mouse coordinates then that would solve all problems. So far many have said to do just that and even i would have said it but i have not found one single way to do it.
Here i even made a sample map for you, all you have to do is fix the variable.
@Sherlia: Go
Ah, I see the problem. There's no function to directly refer to a player's mouse UI position. Back to the drawing board... let me see what I can dig up.
EDIT: The best approach seems to be Progammer's mouse position library. http://www.sc2mapster.com/forums/resources/trigger-libraries/11481-library-realtime-mouse-tracking-system/?post=1
You can also check out OneTwoSC's video. http://www.sc2mapster.com/forums/resources/tutorials/11010-video-diablo-camera-movement/?post=1
Unfortunately that might be the best you're going to find. Good luck.
Thank you :)
The only way i have found it to get the position is if its run in a event trigger that check if mouse is moved or clicked. I did the loop inside that trigger hoping it would update it but it only get the value of the mouse location the instant the trigger runs and not while it runs. So the only way to make this work well is if we find a way to get mouse position without running it in a trigger.
To put it plain, blizzard have not included that function as far as i know :(
Since I've recently dealt with that input stuff again, I should post the collection of my knowledge regarding mouse/button input:
On battle.net, the mouse move event will be fired 15-22 times per player per game loop (most likely not every game loop due to latency changes).
Most likely you would want the last position where the mouse has been, so you are required to save the position of the player's last event ("last event" according to A1win). To do so, you are required to save all input data as checking anything just easily adds a lot more overhead than just saving the values.
To properly use the input data, you should have one thread that processes it for each player in every game loop. Since code in a thread can run up to two times between the game updates, you would want to make sure that the input-using code runs after the new input was thrown in. So, it should run in the second code execution phase and not during the first. To push the execution from the first to the second phase, you need to add a wait of exactly 0.0 game seconds in addition to your normal wait (like 0.0625 game seconds) [yes, you are using 2 waits!].
That's what I'm currently using in my WASD shooter and it seems to run fine. But I didn't test how many players this can support. Since A1win did essentially the same and he told me that his implementation works fine for 8 players, I assume that my approach will run the equally good.
- A: In addition to that, there might be optimization possibilities. Mille25 reported that they are disabling triggers which appears to stop input events from being sent. But I don't know any details or had no chance to test that. In case this is true, it might be possible to enable/disable the bandwith usage for that system when it is not required.
- Btw, I've noticed that JademusSreg toggled the values of the saved button inputs instead of setting values to true/false based on the event. I've tested that and they do not seem to fail at all!
Setting values to true/false has problems when you double-hit a button within one game frame as the input state will be corrupted. It will process "down, down, up" resulting in a saved "no input"-state while the player is in fact holding down the button after that. -> Toggles handle that case properly and should be used.
- B: Another aspect that hasn't been researched, yet, is that if it is better to use one generic event or only the specific buttons for a player.
Also, it is possible to block button presses from being detected by the events, if you are using that button in a toggle in your game's UI. In case every normal button press is creating bandwith usage, you should be able to reduce it using these UI xml toggles.
If we would know the unclear aspects A and B, it might be possible to create the bnet-performance-wise best implementation.
Sadly there is alot of misinformation that is just plain wrong in this thread.
Mouse coordinates can just be retrieved in response to the mouse moved event, so there is no way around creating a mouse moved trigger and responding to it.
The reason why mouse move triggers can cause lag can be split into two areas.
1) CPU overhead. The mouse moved event is the most often firing event in the entire game (it can fire multiple times per game loop), and therefore every form of expensive code in response to mouse moved events must be avoided. The mouse moved trigger itself should just store the current mouse position of the triggering player in a global variable, which then can be processed by other parts of the code (less frequently, for example with a 0 time periodic or a 0 second wait loop).
2) Network lag. The network lag happens because a network query needs to be sent to all players on every input event they make (As stated in the official documentation of all player input events, such as key presses.). The best way to reduce the network lag to a minimum is to TURN OFF the mouse moved trigger WHENEVER POSSIBLE. Rapidly turning it on and off may help a little, but i rather recommend thinking about if the trigger is really constantly needed.
As an example, if the mouse tracking is just required for specific abilities or missions, the trigger should be turned off while those are not active to avoid unnecessary network traffic.
@Mille25: Go
How about a trigger with condition? Would that just as good as turning it on/off?
Ok so the information i have got from is is in the pictures below, from what i understand this is the best solution?
As it is now, the trigger will not be on unless the player press down the mouse button.
I didnt study your code in depth, but you can probably get rid of the condition in the mouse moved trigger since it shouldnt be on anyways if a player is not pressing down the mouse (Therefore the condition just adds an unnecessary check.).
I would also recommend getting rid of the turn on/off stuff and the waits in the mouse moved trigger itself. All it does is reducing the precision and it can also very well create bugs in your game.
For example, consider this scenario:
What happens if a player releases the mouse button very shortly after he pressed it? Is his mouse moved trigger on or off?
I also personally dislike the idea of splitting the mouse moved trigger into multiple instances, one for every player. While it may in theory be possible that it is more efficient, it has not yet been proven and it will be very hard to do so. However, it adds alot of duplicated code and is just by itself a very ugly design, screaming for errors. It also adds overhead to other places of code, such as the mouse key press switch cases and also map and variable initialization.
You should always put code quality prior to performance, and just if it is absolutely necessary consider further steps to optimize code.
Yes i also do not like this at all and prefer to have it all in one trigger but how exactly is that supposed to be made? Only way to get the mouse location is by this trigger.
Regarding the quick click question, would it not just be easy to add a check that waits until the trigger is on before turning it off so it does not stay on?
You can use a player group to figure out if any player is still holding down the left mouse button. Simply add the triggering player to the group when he pressed the left mouse button down and remove him once he releases the button. If the player group is empty you can disable the global mouse moved trigger, otherwise it needs to remain on.