System slows game down

Dirac

22710180
Reaction score
147
Hello, i coded this system that allows you to get the position of a unit seconds ago, it's supposed to be very accurate. But it drops the FPS roughly. Is there a way to prevent the FPS drop?

EDIT: forgot to mention, it has a 5 second maximum storage per unit, and only indexes units that belong to player 9
JASS:
library UnitHistory uses TimerUtils,AIDS
    private struct UH extends array
    
        private static method AIDS_filter takes unit u returns boolean
            return GetOwningPlayer(u)==Player(8)
        endmethod
        
        hashtable x
        hashtable y
        timer t
        
        private static method periodic takes nothing returns nothing
            local integer i=50
            local thistype this=GetTimerData(GetExpiredTimer())
            loop
                exitwhen i<1
                call SaveReal(.x,GetUnitIndex(.unit),i,LoadReal(.x,GetUnitIndex(.unit),i-1))
                call SaveReal(.y,GetUnitIndex(.unit),i,LoadReal(.y,GetUnitIndex(.unit),i-1))
                set i=i-1
            endloop
            call SaveReal(.x,GetUnitIndex(.unit),0,GetUnitX(.unit))
            call SaveReal(.y,GetUnitIndex(.unit),0,GetUnitY(.unit))
        endmethod
        
        
        private method AIDS_onCreate takes nothing returns nothing
            local integer i=50
            local real x=GetUnitX(.unit)
            local real y=GetUnitY(.unit)
            set .t=NewTimer()
            set .x=InitHashtable()
            set .y=InitHashtable()
            call SetTimerData(.t,this)
            call TimerStart(.t,0.1,true,function thistype.periodic)
            loop
                exitwhen i<0
                call SaveReal(.x,GetUnitIndex(.unit),i,x)
                call SaveReal(.y,GetUnitIndex(.unit),i,y)
                set i=i-1
            endloop
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call FlushParentHashtable(.x)
            call FlushParentHashtable(.y)
        endmethod
        //! runtextmacro AIDS()
    endstruct
    
    function GetXSecondsAgo takes unit whichUnit,real seconds returns real
        return LoadReal(UH[whichUnit].x,GetUnitIndex(whichUnit),R2I(seconds*10))
    endfunction
    
    function GetYSecondsAgo takes unit whichUnit,real seconds returns real
        return LoadReal(UH[whichUnit].y,GetUnitIndex(whichUnit),R2I(seconds*10))
    endfunction
endlibrary

Also, how do i see the FPS ingame? i only can tell by how slow the game flows
 

tooltiperror

Super Moderator
Reaction score
231
>Also, how do i see the FPS ingame? i only can tell by how slow the game flows
/fps
 

Tom_Kazansky

--- wraith it ! ---
Reaction score
157
so you only use this for Player(8) ? and how many units does this player have?
maybe too many units => lag?

I probably won't be any helps but I just ask that, my purpose is answer the question below :p

how do i see the FPS ingame?

use /fps command

p.s: great! two minutes slower :(
 

Dirac

22710180
Reaction score
147
"Kinda" solved it myself. Now the system keeps track of EVERY position of the unit since it was created, and runs A LOT faster.
JASS:
library UnitHistory uses TimerUtils,AIDS
    private struct UH extends array
    
        private static method AIDS_filter takes unit u returns boolean
            return GetOwningPlayer(u)==Player(8)
        endmethod
        
        hashtable x
        hashtable y
        timer t
        integer time
        
        static method periodic takes nothing returns nothing
            local integer i=50
            local thistype this=GetTimerData(GetExpiredTimer())
            set .time=.time+1
            call SaveReal(.x,GetUnitIndex(.unit),.time,GetUnitX(.unit))
            call SaveReal(.y,GetUnitIndex(.unit),.time,GetUnitY(.unit))
        endmethod
        
        private method AIDS_onCreate takes nothing returns nothing
            local integer i=50
            local real x=GetUnitX(.unit)
            local real y=GetUnitY(.unit)
            set .t=NewTimer()
            set .x=InitHashtable()
            set .y=InitHashtable()
            set .time=50
            call SetTimerData(.t,this)
            call TimerStart(.t,0.1,true,function thistype.periodic)
            loop
                exitwhen i<0
                call SaveReal(.x,GetUnitIndex(.unit),i,x)
                call SaveReal(.y,GetUnitIndex(.unit),i,y)
                set i=i-1
            endloop
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call FlushParentHashtable(.x)
            call FlushParentHashtable(.y)
        endmethod
        //! runtextmacro AIDS()
    endstruct
    
    function GetXSecondsAgo takes unit whichUnit,real seconds returns real
        return LoadReal(UH[whichUnit].x,GetUnitIndex(whichUnit),R2I(UH[whichUnit].time-seconds*10))
    endfunction
    
    function GetYSecondsAgo takes unit whichUnit,real seconds returns real
        return LoadReal(UH[whichUnit].y,GetUnitIndex(whichUnit),R2I(UH[whichUnit].time-seconds*10))
    endfunction
    
    function KeepRecording takes unit whichUnit returns nothing
        call TimerStart(UH[whichUnit].t,0.1,true,function UH.periodic)
    endfunction
    
    function StopRecording takes unit whichUnit returns nothing
        call PauseTimer(UH[whichUnit].t)
    endfunction
endlibrary

Any suggestions? Are hashtables really that slow?
 

Rllulium

New Member
Reaction score
10
Keeping track of every position will hit a memory limit at some point.

Also, why do you need this? There might be other implementations to consider.
 

WaterKnight

Member
Reaction score
7
Why do you need own hashtables for each unit? They already reserve their space by integrating them in the keys. Also you can only have 255 hashtables, so this part alone allows no more than 127 registered units.
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
I think the below solution is faster than hashtables and better than your infinite data storage.

Use array variables, witch are like
JASS:
globals
    real array[][] UnitX
    real array[][] UnitY
    integer array Index
endglobals

with initial value on AIDS_OnCreate "0"
the first array is your unit's UserData or anything else AIDS uses
Also on create store the x and y of unit in every array 0-50 to avoid bugs

On periodic use this
JASS:

local integer i = GetUnitUserData(.unit)
set Index<i> = Index<i> + 1
if Index<i> &gt; 50 then
    set Index<i> = 0
endif
set UnitX<i>[Index<i>] = GetWidgetX(.unit)
set UnitY<i>[Index<i>] = GetWidgetY(.unit)
</i></i></i></i></i></i></i></i>


Its something that writes or overrides values on arrays 0-50 like this world's earth time but its year time is 5 seconds. Fast I know :D
So if we want something that happened 2,6 seconds ago, we get the current time witch is Index and get the Index-26 value.
What happens if this value is equal to -6, we haven't got any UnitX[][-6] value stored. So we get previous year's day witch is 50-6 = 44
The location of unit on 44 day. With day I mean the 0.1 seconds
So we have this.
JASS:

local integer i = GetUnitUserData(.unit)
local real x
local real y
local integer j = Index<i> - R2I(time*10)
if Index<i> &lt; 0 then
    set j = 50 + j
endif
set x = UnitX<i>[j]
set y = UnitY<i>[j]
</i></i></i></i>


Because I don't use AIDS I don't know if the units user data or number of indexed unit can be parsed directly, so I just used the local integer i to get the unit's id.
 

Sevion

The DIY Ninja
Reaction score
413
The array method will have serious drawbacks if you hit the limit (which will occur very fast since you have a jagged array).

Instead, you should use the hashtable approach. However, you only need one.

Combine it with an array and you have your method.

JASS:
local integer i = GetHandleId(unit)
local integer n

if ( not HaveSavedInteger(hashtable, i, -1) ) then
    call SaveInteger(hashtable, i, -1, 0)
endif

set n = LoadInteger(hashtable, i, -1)

if ( n &gt; /*MAX_STEPS_TO_SAVE*/ 8190 ) then
    set n = 0
endif

call SaveReal(hashtable, i, n, GetUnitX(unit))
call SaveReal(hashtable, i, n, GetUnitY(unit))


n is simply the "step".

You could then combine this script with a timer and IsUnitMoving (which can be found on Hive or WC3, can't remember which).

You could also change n to "time" via a GetGameTime script (which is another script that can be found here).
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
tell me how the heck he will reach the limit??
its something like real UnitX[8190][50]
 

Sevion

The DIY Ninja
Reaction score
413
8190*50=409500

And according to my math skills, 409500 > 8192

That will result in trigger evaluations.
 

Dirac

22710180
Reaction score
147
Thanks Sevion and Waterknight both made very helpful suggestions.

I though about the IsUnitMoving thing before too. But then i realized it makes no sense to ignore as "timeline" when a unit isn't moving, it's still spending time doing something.

Didn't know much about the jagged arrays, they don't sound very useful since [n]*[m]<8190, that's one big limitation right there. Thanks for that too there
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
ok, but I don't think you might track more than 163 units positions constantly, do you?
If you want use your hashtables but think about the idea I gave you. You just need 50 arrays for each unit.
And at the beginning save the unit's position to all arrays. 8190 instances is such a waste.
 

Sevion

The DIY Ninja
Reaction score
413
ok, but I don't think you might track more than 163 units positions constantly, do you?
If you want use your hashtables but think about the idea I gave you. You just need 50 arrays for each unit.
And at the beginning save the unit's position to all arrays. 8190 instances is such a waste.

That really depends on the context of the map... Generality is a better approach than specificity.

But then that limits each unit to 50 steps.

8190 instances isn't necessarily a waste. It really depends, again, on the context.

Thanks Sevion and Waterknight both made very helpful suggestions.

I though about the IsUnitMoving thing before too. But then i realized it makes no sense to ignore as "timeline" when a unit isn't moving, it's still spending time doing something.

Didn't know much about the jagged arrays, they don't sound very useful since [n]*[m]<8190, that's one big limitation right there. Thanks for that too there

They are useful, and the only limitation is that after 8192 instances (0 to 8191) vJASS resorts to trigger evaluations, which are slow.
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
For 5 seconds 50 he needs, if he needs 8 minutes he may use 8000 indexes.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/
  • The Helper The Helper:
    I think we need to add something to the bottom of the front page that shows the Headline News forum that has a link to go to the News Forum Index so people can see there is more news. Do you guys see what I am saying, lets say you read all the articles on the front page and you get to the end and it just ends, no kind of link for MOAR!
  • The Helper The Helper:
    Happy Wednesday!
    +1
  • V-SNES V-SNES:
    Happy Friday!
    +1

      The Helper Discord

      Staff online

      • Ghan
        Administrator - Servers are fun

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top