Lag compensation

So I’ve been working on lag compensation for like the last 5 days.
Since it’s an interesting subject that I know has to be tackled outside of graal too, I’ve put in more of my might.

I want to show my code because damn I’ve spent five days on it, rewriting it like 4 times. (and nobody will see it otherwise).

This is the weapon (the part ran individually by each player):

// NPC made by 2ndwolf
if (playerenters) {
  toweapons Dummy Thing;
//  this.loop = 10;
  timeout = .05;
}


//this is the showani weapon


if ( timeout  && isweapon ) {

  if(npcs[testnpc(1,1)].save[9] == 0){ //is travelling
    this.loop++;
    this.waittime++;

    if(this.bigsiteration != npcs[testnpc(1,1)].save[4]){
      this.waittime = 0;
  //    this.newloop = this.loop;

  //    this.lags[this.lagindex%5] = this.newloop - this.oldloop;


      this.letlag = 10;  //this shouldn't be hardcoded but oh well
  //    if(this.lagindex<5) this.letlag = 10;
  //    else this.letlag = (this.lags[0]+this.lags[1]+this.lags[2]+this.lags[3]+this.lags[4])/5;

      //this.lagindex++;

      this.difference = {(npcs[testnpc(1,1)].save[2]-npcs[testnpc(1,1)].save[0])/this.letlag,(npcs[testnpc(1,1)].save[3]-npcs[testnpc(1,1)].save[1])/this.letlag};

      this.bigsiteration = npcs[testnpc(1,1)].save[4];

  //  this.oldloop = this.newloop;

    }

    this.dx = npcs[testnpc(1,1)].save[2]-npcs[testnpc(1,1)].save[0]+this.difference[0]*this.waittime;
    this.dy = npcs[testnpc(1,1)].save[3]-npcs[testnpc(1,1)].save[1]+this.difference[1]*this.waittime;
    this.dist = (this.dx^2 + this.dy^2)^0.5;


    this.dir = getdir(this.dx,this.dy);


    if(this.dist < 1){
      callnpc testnpc(1,1),whatnext,;
      this.waittime = 0;
    }
    else {

      this.showanicoords = {npcs[testnpc(1,1)].save[0]+this.difference[0]*this.waittime,npcs[testnpc(1,1)].save[1]+this.difference[1]*this.waittime};
      showani 387,this.showanicoords[0],this.showanicoords[1],this.dir,bartender#v(npcs[testnpc(1,1)].save[5])#v(npcs[testnpc(1,1)].save[6]),;//0,;

      this.textwidth = textwidth(1,arial,,#s(bartender.words));

      showtext 388,this.showanicoords[0]-(this.textwidth/16)/2+1.5,this.showanicoords[1]-1.5,arial,,#s(bartender.words);
      showtext 389,this.showanicoords[0]-(this.textwidth/16)/2+1.5+3/16,this.showanicoords[1]+1.5+3/16,arial,bold,#s(bartender.words);

      changeimgvis 387,1;
      changeimgvis 388,2;
      changeimgvis 389,1;
      changeimgcolors 389,0,0,0,1;

    }




  } else {  //is idle and waiting

    this.showanicoords = { npcs[testnpc(1,1)].save[0] , npcs[testnpc(1,1)].save[1] };
    showani 387,this.showanicoords[0],this.showanicoords[1],this.dir,bartender#v(npcs[testnpc(1,1)].save[5])#v(npcs[testnpc(1,1)].save[6]),;

    this.textwidth = textwidth(1,arial,,#s(bartender.words));

    showtext 388,this.showanicoords[0]-(this.textwidth/16)/2+1.5,this.showanicoords[1]-1.5,arial,,#s(bartender.words);
    showtext 389,this.showanicoords[0]-(this.textwidth/16)/2+1.5+3/16,this.showanicoords[1]+1.5+3/16,arial,bold,#s(bartender.words);

    changeimgvis 387,1;
    changeimgvis 388,2;
    changeimgvis 389,1;
    changeimgcolors 389,0,0,0,1;
  }

  timeout = .05;
}

It can also wait and speak! (Haven’t tested the part where he waits, but since he starts by waiting and has no problem, I assume it works (I know I shouldn’t).

Ok so vbulletin wouldn’t parse my french comment and I hsd to leave, will post the full script once I’m back home.

The part ran by the level’s leader: (It’s placed at coordinates 0,0 since the weapon looks for an npc that is at 1,1)

// NPC made by 2ndwolf
if (playerenters) {

this.step = 0;
this.coords = {19,19,19,29,29,29,29,19};
this.speed = 2;

save[0] = 19;      //last synched position (x)
save[1] = 19;      //last synched position (y)
save[2] = save[0]; //next position to synch with (x)
save[3] = save[1]; //next position to synch with (y)
save[4] = 0;       // this script's quantity of iterations
save[5] = 0; //gani - 0 = idle, 1 = walk...
save[6] = 0; //hasbeer

save[9] = 20;  //sleep

timeout = .05;
}

if ( (timeout || whatnext) && isleader) {


  if(save[9]>0){
    //Place npc at given coordinates and make it wait as long as supposed
    save[0] = this.coords[this.step*2];
    save[1] = this.coords[this.step*2+1];
    save[2] = save[0];
    save[3] = save[1];

    save[9]--;

  } else {

    if( this.dist < 1 || whatnext ) {


      if(this.step == arraylen(this.coords)/2-1){
        save[6] = 0;
        this.goingback = 1;
      } else if (this.step==0){
        this.goingback = 0;
        save[6] = 1;
      }

      if(this.goingback==0)this.step++;
      else this.step--;

    }

  }

  if(save[9]<1){
    save[5] = 1;
  //next destination
    this.dx = this.coords[this.step*2] - save[0];
    this.dy = this.coords[this.step*2+1]- save[1];
    this.dist = (this.dx^2 + this.dy^2)^0.5;

    save[0] = save[2];
    save[1] = save[3];

    if(this.dist<this.speed+1){;

      this.dist = 0;
    } else {
      save[2] += (this.dx/this.dist)*this.speed;
      save[3] += (this.dy/this.dist)*this.speed;
    }

//    setplayerprop #c,#v(save[2]),#v(save[3]);


    save[4] += 1;
  }


  timeout.time = save[9] > 0 ? .05 : .5;
  timeout = timeout.time;
}

This morning I tested with Wocky on my level and it seems his npcw desynched after a moment, sending the character in a straight line out of the level.

I got super confused before I realized half the script was missing from last post. Or maybe tapatalk is crapping out on me. What exactly is this suppose to do?

Compensante lag? Basically make the game less shittier for people that have high latency, and shittier for people that have good connection.

wow it’s like socialism for internet quality

Yeah, I had a problem with the forums and needed to leave before I could get around it.

For some reason, when a showcharacter npc walks… it becomes erratic if a player in the level has a slow connection.

This chunk of code makes the level’s leader run a script that gives destinations to each player’s npcw that displays a showani. That way, the character is displayed client side and shows at the same place for everyone on the level.

I’d explain further but I don’t have the right words.

I get it. I kinda had to do the same thing to get multi-player events to not act shitty.

Good implementation. This is what I was talking about with you, but instead of saves, I mentioned level variables.