[SOLVED] Micro lag/Skipping; I'm at a loss.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Cluly
Prole
Posts: 2
Joined: Sun Aug 12, 2018 4:14 pm

[SOLVED] Micro lag/Skipping; I'm at a loss.

Post by Cluly »

Hi All,

Recently I've been developing a game for the low res jam and decided to use Love2d. However, I get intermittent skips and lag while moving objects around on the screen. I've scoured the forums, youtube and the rest of the internet and tried almost every possible solution I can come accross but it's still happening. I've noticed it happens with other games written in Love2d too, which lead me to believe it was my computer/setup, however this is also not the case as I've seen the same thing happening on youtube videos, rather noticable in this video :

https://www.youtube.com/watch?v=3k4CMAaNCuk&t=24s

So here I am, asking for help as I'm about ready to drop Love2d altogether because of it (yes it's that irritating >_<) here are the solutions I've tried:

- Fixed and variable timerstep with and without DT.
- Fullscreen, window, vsync on and off.
- Movement interpolation.
- Floored x,y etc.
- System spec : i7 4790, 1060 GTX 3gb, 16gb ram, Windows 10.

[SOLVED] Issues are gone and movement is now buttery smooth with the latest nVidia drivers. 399.24
Last edited by Cluly on Tue Sep 11, 2018 11:56 pm, edited 2 times in total.
User avatar
Link
Prole
Posts: 19
Joined: Tue Jun 19, 2018 4:09 am

Re: Micro lag/Skipping; I'm at a loss.

Post by Link »

I've not experienced this, and my development computer is slower than most (a Raspberry Pi 3).

Have you monitored the framerate of your game, to ensure the lag isn't due to processing the game logic? What method (mouse/keyboard/other) do you use for moving the game objects?

It's helpful if you can post a small self-contained code example, illustrating the issue.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Micro lag/Skipping; I'm at a loss.

Post by pgimeno »

Hi Cluly, welcome to the forums!

I'm not sure what kind of lag we're talking about here. I didn't notice any micro-lag in the above video. If anything, the scrolling demo (which is at 0:23:11, not at 0:0:24) skips one pixel too much once in a while, which is pretty much the opposite of lag, and is a logical consequence of the timing method used.

In the code, the presenter has defined a scrolling speed of 62 pixels per second. That's just a tad faster than 60 pixels per second, which would be 1 pixel per frame in a 60 Hz monitor. The video (the 1280x720 version) has a frame rate of 30, which is probably about in sync with the presentation's screen (every 2 frames). That means that every half a second, instead of scrolling by 2 pixels every frame, in one frame it needs to scroll by 3. I believe that justifies the small jerks we see. These jerks are more noticeable because of using nearest filtering and integral coordinates.

To do it perfect, you would need to make a game that only works on monitors with a certain refresh rate. You simply can't have a scroll of a pixelated image that looks the same in all monitors with all refresh rates.

Now, it's possible that there are other sources of trouble for your case. LuaJIT is know for having a garbage collection algorithm that isn't very up-to-speed with its lightning-fast, state-of-the-art JIT compiler. Generating garbage (or maybe even just having lots of active objects that need to be checked, even if they're not garbage, but I'm not sure about that) may cause small lag spikes of the kind you're describing every bunch of frames. Some suggestions to avoid generating unnecessary garbage:
  • Where possible, don't create one-use tables on the fly. For example, some functions expect tables as parameters and it's very common to do this:

    Code: Select all

    function love.draw()
      func(blah, {x=1, y=2})
    end
    
    which creates a one-time use object that needs to be cleaned up. It's much uglier, admittedly, but this avoids creating garbage every frame:

    Code: Select all

    local coords = {}
    function love.draw()
      coords.x = 1
      coords.y = 2
      func(blah, coords)
    end
    
    This is especially important in loops.
  • Reuse, rather than recreate, lists (I'm calling "list" a table with sequential numeric indices starting at 1). Clearing a list with a loop is typically faster than recreating it, all things considered; especially, garbage collection doesn't need to clean up the old one. Don't use table.remove to clear it, just set the elements to nil.
  • For some applications, it may even be possible to have a pool of objects, so that instead of deleting a used table, it's put into the pool, and before creating a new one, the pool is checked to see if there are any available. I'm doing some work on a library that uses this technique.
  • Don't create functions on the fly if not strictly necessary. A function is also an object, it needs to be allocated and garbage-collected.
  • Whenever possible, organize your code so that your maps are flat (1D), instead of 2D, like the one suggested in the video you linked. That reduces the number of active objects.
  • Avoid string concatenation when possible. string.format is much slower, but it will avoid creation of intermediate strings that will need to be GC'd. For example, instead of tostring(x) .. "," .. tostring(y) use string.format("%.17g,%.17g", x, y) or the equivalent ("%.17g,%.17g"):format(x, y) (there's a reason for the .17, in a nutshell it displays every possible float differently).
Something that might also help is to try to do some garbage cleaning manually every frame. Try calling collectgarbage("step", n) for some suitable n and see if that helps reducing lag spikes.

Alternatively, you can try with pure Lua and see if your game is still fast enough to run at normal speed; hopefully Lua's GC won't cause these spikes.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Micro lag/Skipping; I'm at a loss.

Post by zorg »

pgimeno wrote: Tue Aug 14, 2018 7:44 pm [*] Avoid string concatenation when possible. string.format is much slower, but it will avoid creation of intermediate strings that will need to be GC'd.
I kinda believed that .. was slower than string.format though? I'm guessing you benchmarked them?
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Micro lag/Skipping; I'm at a loss.

Post by pgimeno »

Yes I did. I don't know how many strings you have to concatenate to make string.format be faster, but it's going to be quite some.

Code: Select all

local a = "12345678"
local b = "12345679"
local c

local gettime = os.clock
--local gettime = require'socket'.gettime

local start = gettime()

for i = 1, 10000000 do
  c = ("%s%s"):format(a, b) -- around 2.4
--  c = a .. b -- around 0.6
  a = c:sub(2, 9)
end

local elapsed = gettime() - start

-- use c
print(elapsed, c:byte(2))
Cluly
Prole
Posts: 2
Joined: Sun Aug 12, 2018 4:14 pm

Re: [SOLVED] Micro lag/Skipping; I'm at a loss.

Post by Cluly »

Latest nVidia drivers solved this issue completely. (Driver version 399.24)
Post Reply

Who is online

Users browsing this forum: No registered users and 54 guests