Jump to content

Position lag on hit

open

Angezerus
2012-07-06 15:05:34
Hi there!

This is a very very old issue. This works for both monsters and players. So what the issue is:

If a monster (or player) is hit by something or someone, there is a small time defined somewhere, in which you can't move, let's call it movement delay, and on the hit, the character plays a "twitch" animation. The problem is that the animation usually lasts longer than the movement delay (as I experienced especially at slow moving monsters or players), and when the monster(or player) is able to move again and moves away, it does not cancel the animation, and because of this the character position and the sprite's position desynchronizes. This also happens when someone/something is knocked back with something that deals damage. The sprite moves twice all the way back and forward, and the positions gets totally messed up. Sometimes it doesen't even show the character moving back from the knockback.

I've seen some official videos, and there is something similar, but on officials when the character moves, it synchronizes relatively fast, and I've never seen something like a monster stading several cells away yet still hitting the player, and there is absolutely no "double movement" on knock back.

I made a short video to show the desync and the knockback issue:

http://www.youtube.com/watch?v=cwKkjNOS7LI

Ainna
2012-07-06 22:34:29
Yup, even with nagle this problem still persist.
Homunculi also have problems with this ;D
A fix for this would definitely be nice.

Angezerus
2012-07-12 09:55:41
We tried that nagle thing as well, but it did not help this problem, just like you said.

malufett
2012-07-12 11:54:47
IMO its a client-server connectivity issue..something related with PACKET_ZC_NOTIFY_TIME and I think aegis have a different interval in notifying the client..anyway it is my wild guess since I'm not that good with packet thingy

Angezerus
2012-07-12 12:00:15
Imo if it's a connectivity issue, then it's not about time, because if you got hit and you move in the same time, your char will desync, and this stays the same forever unless you move.

It's more like there is a missed "send posinfo" part somewhere.

/edit
Or maybe a missed "resume sending posinfo".

Perhaps around the "hit event during movement" part?

Another thing could be that on the server's part the caracter's movement is not interrupted by the hit, so it continues to walk, until you send another movement command (or reach the previous destination)...?

Only speculating :)

malufett
2012-07-12 12:09:03
[quote]Imo if it's a connectivity issue, then it's not about time, because if you got hit and you move in the same time, your char will desync, and this stays the same forever unless you move.[/quote]
yes it could be because time is also use as pattern for the synchronization....

Angezerus
2012-07-12 14:13:23
Found this:

http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=1851


[quote][CODE]
// Move-delay adjustment after being hit. (Note 2)
// The 'can't walk' delay after being hit is calculated as a percentage of the damage animation duration.
// NOTE: Only affects the normal delay from a single attack, not the delay added by the multihit_delay option below.
pc_damage_walk_delay_rate: 20
damage_walk_delay_rate: 0
[/CODE][/quote]

And they suggested in the thread to set the delays to 0.

That's a bit strange for me. The description says:

[quote]The 'can't walk' delay after being hit is calculated as a percentage of the damage animation duration.[/quote]

But if we set this to anything lower than 100% won't it cause the characters to be able to move instantly after being hit, and thus desyncing the server and the client? (because the client would still play the animation, while the server moves forward and stops at the target, and thus it won't be sending any more sync packets)


/edit
Similar issue that has a solution. Interesting stuff...
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=3102

It says:
[quote][CODE]
if (!unit_can_move(bl)) <---- This causes Position lag, because the mobs start walking when they are currently under skill damage too.
return 0;
[/CODE][/quote]

And currently this is how our code look now. But wait a minute. Why wouldn't we re-delay a character? If something is suffering a delay from being hit, it would be normal to re-apply another delay if it got hit again, wouldn't it? Otherwise the character would bypass every delay, suffered from hits during the first delay, while the character still plays every hit animation.

So, are we sure these code parts and delay rates are the right ones?

Angezerus
2012-11-29 08:59:46
Any thoughts about the previous post? It's been a while :)

Antares
2013-01-07 11:07:09
Any news?

Antares
2013-04-30 12:32:40
Bump?

Deimler
2013-10-19 16:42:53
bump...

Dragonis1701
2013-10-19 19:55:27
If I recall correctly, this is due to how often the server "checks" monster and player position. Standard rAthena checks mobs every 1000 ms where as official servers check every 20ms, or something really low and close to that, making position "appear" more accurate.

The reason rAthena went with 1000 is because 20 or 50, whichever it was, is very taxing on a server. Perhaps there can be an inbetween by having a check on the monster's position when it attacks the players but that can also be taxing on a server, especially when mobbing.

ivanyan
2013-10-19 20:14:09
I'm not exactly sure about this... But I've made some changes in this code

        /**
         * MvP mobs have no walk delay
         **/
        if( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) )
                return 0;

// all of this commented by me

// this is mine
        clif_fixpos(bl);

//      if (type) {
                if (DIFF_TICK(ud->canmove_tick, tick+delay) > 0)
                        return 0;
//      }
//      else
//      {
//              //Don't set walk delays when already trapped.
//              if (!unit_can_move(bl))
//                      return 0;
//      }



Antares
2013-10-20 09:16:04
A few months ago I solved this issue and I posted the "solution" in a similar thread. So what I found, is that if something gets hit, it always moves a cell forward on server side, while on client side it stays in place because of the damage animation. This completely desyncs the server and the client. Disabling the part wich says "if it's half way there, jump to the next cell" completely solved the problem and anything was perfect. Even hitlock. MVPs were not affected because they have endure effect, so it didn't mess them up. I suggest to examine the mentioned codepart, because it only makes position difficult.

ivanyan
2013-10-20 18:36:21
The next improvement, more natural movement without lags

int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type)
{
        struct unit_data *ud = unit_bl2ud(bl);
        if (delay <= 0 || !ud) return 0;

        /**
         * MvP mobs have no walk delay
         **/
        if( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) )
                return 0;

        if (type) {
                if (DIFF_TICK(ud->canmove_tick, tick+delay) > 0)
                        return 0;
        }
        else
        {
                //Don't set walk delays when already trapped.
                if (!unit_can_move(bl))
                        return 0;
        }


        ud->canmove_tick = tick + delay;
        if (ud->walktimer != INVALID_TIMER)
        {       //Stop walking, if chasing, readjust timers.
                if (delay == 1)
                {       //Minimal delay (walk-delay) disabled. Just stop walking.
                        unit_stop_walking(bl,4);
                } else {
                        //Resume running after can move again [Kevin]
                        if(ud->state.running)
                        {
                                add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr_t)ud);
                        }
                        else
                        {
                                unit_stop_walking(bl,2|4);
                                if(ud->target)
                                        add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
                                // this is mine
                                clif_fixpos(bl);
                        }
                }
        }
        return 1;
}



Playtester
2014-10-19 12:58:23
There are a lot of things that desync the position on hit, but the core problem is now the delay at all but rather when the client stops the unit. The issue is official and can't really be fixed.

The problem is that the aMotion value of some monster is longer or shorter than their attack animation. Say a monster has an attack animation of 400ms but the aMotion value is 900ms. Even if we send to the client "Display flinch in 900ms", the client will completely ignore that info and display the flinch after 400ms when its attack animation ended. I tried around with it and realized that the client completely refuses to wait longer than the attack animation.

Even if we synchronize the walk delay with the client, there's no point because the client starts to display the flinch at 400ms and stops the character on the cell while the server let's the character continue moving for 500ms which can be as much as 5 cells walked. It's already completely desync before the server even reacts. Same problem after the flinch. The client already sends movement commands and let's the character walk before the server even stopped the unit from the previous hit. So suddenly "stop_walking" gets called from the server but the client is determined it already stopped and will just display the character continue walking while you actually stand still on the cell you were on whenever the aMotion value had passed from the previous hit.

This basically needs to be fixed client-sided. Someone who knows how to set the animation length on the client could probably belong or shorten them so they are identical to the official aMotion values. This would solve the position lag that occurs when hit. Server-sided we can't do much since the client refuses to accept any other info.

You could do a custom change by manually set the aMotion values in the mob_db to the length of the attack animation of each monsters. For example compare position lag of official Ghoul when it hits you. Then set its aMotion value to ~200ms and try again. Position lag is a lot less. This will of course also deviate from official gameplay, so it's nothing that can't be fixed on the emulator itself.

Honestly the best solution for this seems to be to actually modify the client and fix up the animations and make a custom MOD out of that.
×
×
  • Create New...