mostly get marble collisions working

This commit is contained in:
RandomityGuy 2024-01-30 00:06:07 +05:30
parent 5e93acd6cf
commit 015588feb0
5 changed files with 64 additions and 51 deletions

View file

@ -1679,12 +1679,12 @@ class Marble extends GameObject {
// MP Only Functions // MP Only Functions
public function packUpdate(move:NetMove) { public function packUpdate(move:NetMove, timeState:TimeState) {
var b = new haxe.io.BytesOutput(); var b = new haxe.io.BytesOutput();
b.writeByte(NetPacketType.MarbleUpdate); b.writeByte(NetPacketType.MarbleUpdate);
var marbleUpdate = new MarbleUpdatePacket(); var marbleUpdate = new MarbleUpdatePacket();
marbleUpdate.clientId = connection != null ? connection.id : 0; marbleUpdate.clientId = connection != null ? connection.id : 0;
marbleUpdate.serverTicks = move.timeState.ticks; marbleUpdate.serverTicks = timeState.ticks;
marbleUpdate.position = this.newPos; marbleUpdate.position = this.newPos;
marbleUpdate.velocity = this.velocity; marbleUpdate.velocity = this.velocity;
marbleUpdate.omega = this.omega; marbleUpdate.omega = this.omega;
@ -1710,7 +1710,7 @@ class Marble extends GameObject {
return true; return true;
} }
public function updateServer(timeState:TimeState, collisionWorld:CollisionWorld, pathedInteriors:Array<PathedInterior>, packets:Array<haxe.io.Bytes>) { public function updateServer(timeState:TimeState, collisionWorld:CollisionWorld, pathedInteriors:Array<PathedInterior>) {
var move:NetMove = null; var move:NetMove = null;
if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) { if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) {
if (Net.isClient) { if (Net.isClient) {
@ -1742,21 +1742,18 @@ class Marble extends GameObject {
innerMove.d = new Vector(0, 0); innerMove.d = new Vector(0, 0);
move = new NetMove(innerMove, axis, timeState, 65535); move = new NetMove(innerMove, axis, timeState, 65535);
} }
playedSounds = []; playedSounds = [];
advancePhysics(timeState, move.move, collisionWorld, pathedInteriors); advancePhysics(timeState, move.move, collisionWorld, pathedInteriors);
for (marble in this.collidingMarbles) { for (marble in this.collidingMarbles) {
marble.collisionToken = timeState.ticks; marble.collisionToken = timeState.ticks;
} }
if (this.collidingMarbles.length != 0) if (this.collidingMarbles.length != 0)
this.collisionToken = timeState.ticks; this.collisionToken = timeState.ticks;
physicsAccumulator = 0; physicsAccumulator = 0;
return move;
if (Net.isHost) { // if (Net.isHost) {
packets.push(packUpdate(move)); // packets.push({b: packUpdate(move, timeState), c: this.connection != null ? this.connection.id : 0});
} // }
} }
public function updateClient(timeState:TimeState, pathedInteriors:Array<PathedInterior>) { public function updateClient(timeState:TimeState, pathedInteriors:Array<PathedInterior>) {

View file

@ -1029,21 +1029,23 @@ class MarbleWorld extends Scheduler {
if (!lastMoves.ourMoveApplied) { if (!lastMoves.ourMoveApplied) {
var ourMove = lastMoves.myMarbleUpdate; var ourMove = lastMoves.myMarbleUpdate;
if (ourMove != null) { if (ourMove != null) {
marble.unpackUpdate(ourMove);
for (client => arr in lastMoves.otherMarbleUpdates) { for (client => arr in lastMoves.otherMarbleUpdates) {
var lastMove = null; var lastMove = null;
while (arr.length > 0) { while (arr.length > 0) {
var p = arr[0]; var p = arr[0];
if (p.serverTicks <= ourMove.serverTicks && p.serverTicks >= ourMove.collisionToken) { if (p.serverTicks <= ourMove.serverTicks) {
clientMarbles[Net.clientIdMap[client]].unpackUpdate(p);
lastMove = arr.shift(); lastMove = arr.shift();
} else { } else {
break; break;
} }
} }
if (lastMove != null) if (lastMove != null) {
if (ourMove.serverTicks == lastMove.serverTicks)
clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove);
arr.insert(0, lastMove); arr.insert(0, lastMove);
}
} }
marble.unpackUpdate(ourMove);
} }
} }
} }
@ -1053,9 +1055,10 @@ class MarbleWorld extends Scheduler {
var ourLastMove = lastMoves.myMarbleUpdate; var ourLastMove = lastMoves.myMarbleUpdate;
if (ourLastMove == null) if (ourLastMove == null)
return; return;
var ackLag = -1; var ackLag = @:privateAccess Net.clientConnection.moveManager.queuedMoves.length;
var mvStored = null;
if (!lastMoves.ourMoveApplied) if (!lastMoves.ourMoveApplied)
ackLag = Net.clientConnection.moveManager.acknowledgeMove(ourLastMove.move.id); mvStored = Net.clientConnection.moveManager.acknowledgeMove(ourLastMove.move.id);
else else
return; return;
@ -1066,6 +1069,12 @@ class MarbleWorld extends Scheduler {
var advanceTimeState = timeState.clone(); var advanceTimeState = timeState.clone();
advanceTimeState.dt = 0.032; advanceTimeState.dt = 0.032;
ackLag = ourQueuedMoves.length;
if (mvStored != null) {
trace('ACK Lag: ${timeState.ticks - mvStored.timeState.ticks} ${ourQueuedMoves.length}');
}
// Tick the remaining moves (ours) // Tick the remaining moves (ours)
if (!lastMoves.ourMoveApplied) { if (!lastMoves.ourMoveApplied) {
@:privateAccess this.marble.isNetUpdate = true; @:privateAccess this.marble.isNetUpdate = true;
@ -1078,36 +1087,39 @@ class MarbleWorld extends Scheduler {
for (client => arr in lastMoves.otherMarbleUpdates) { for (client => arr in lastMoves.otherMarbleUpdates) {
if (arr.length > 0) { if (arr.length > 0) {
var m = arr[0]; var m = arr[0];
if (m.serverTicks <= ourLastMoveTime && m.serverTicks >= ourLastMove.collisionToken) { if (m.serverTicks == ourLastMoveTime) {
m.calculationTicks = Std.int(/*ourLastMoveTime - m.serverTicks + */ ourQueuedMoves.length); var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
m.calculationTicks = Std.int(ackLag / 2);
marblesToTick.set(client, m); marblesToTick.set(client, m);
arr.shift(); arr.shift();
} }
} }
} }
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
for (move in ourQueuedMoves) { for (move in ourQueuedMoves) {
var m = move.move; var m = move.move;
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius); // Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
@:privateAccess this.marble.moveMotionDir = move.motionDir; @:privateAccess this.marble.moveMotionDir = move.motionDir;
@:privateAccess this.marble.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors); @:privateAccess this.marble.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors);
if (this.marble.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
for (client => m in marblesToTick) { for (client => m in marblesToTick) {
if (m.calculationTicks > 0) { if (m.calculationTicks > 0) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]]; var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius); // Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
var beforePos = @:privateAccess marbleToUpdate.newPos.clone();
var mv = m.move.move; var mv = m.move.move;
@:privateAccess marbleToUpdate.isNetUpdate = true; @:privateAccess marbleToUpdate.isNetUpdate = true;
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir; @:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors); @:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
@:privateAccess marbleToUpdate.isNetUpdate = false; @:privateAccess marbleToUpdate.isNetUpdate = false;
if (marbleToUpdate.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
m.calculationTicks--; m.calculationTicks--;
var afterPos = @:privateAccess marbleToUpdate.newPos;
} }
} }
currentTick++; currentTick++;
@ -1123,8 +1135,6 @@ class MarbleWorld extends Scheduler {
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir; @:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors); @:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
@:privateAccess marbleToUpdate.isNetUpdate = false; @:privateAccess marbleToUpdate.isNetUpdate = false;
if (marbleToUpdate.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
m.calculationTicks--; m.calculationTicks--;
} }
} }
@ -1332,12 +1342,22 @@ class MarbleWorld extends Scheduler {
fixedDt.dt = 0.032; fixedDt.dt = 0.032;
tickAccumulator -= 0.032; tickAccumulator -= 0.032;
var packets = []; var packets = [];
marble.updateServer(fixedDt, collisionWorld, pathedInteriors, packets); var myMove = marble.updateServer(fixedDt, collisionWorld, pathedInteriors);
var otherMoves = [];
for (client => marble in clientMarbles) { for (client => marble in clientMarbles) {
marble.updateServer(fixedDt, collisionWorld, pathedInteriors, packets); otherMoves.push(marble.updateServer(fixedDt, collisionWorld, pathedInteriors));
} }
if (Net.isHost) { if (Net.isHost) {
for (client => othermarble in clientMarbles) { // Oh no!
var mv = otherMoves.shift();
packets.push(marble.packUpdate(myMove, fixedDt));
packets.push(othermarble.packUpdate(mv, fixedDt));
}
for (client => marble in clientMarbles) { // Oh no! for (client => marble in clientMarbles) { // Oh no!
// var pktClone = packets.copy();
// pktClone.sort((a, b) -> {
// return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0;
// });
for (packet in packets) { for (packet in packets) {
client.datachannel.sendBytes(packet); client.datachannel.sendBytes(packet);
} }

View file

@ -98,17 +98,17 @@ class SphereCollisionEntity extends CollisionEntity {
contact.penetration = radius - (position.sub(contact.point).dot(contact.normal)); contact.penetration = radius - (position.sub(contact.point).dot(contact.normal));
contacts.push(contact); contacts.push(contact);
var othercontact = new CollisionInfo(); // var othercontact = new CollisionInfo();
othercontact.collider = collisionEntity; // othercontact.collider = collisionEntity;
othercontact.friction = 1; // othercontact.friction = 1;
othercontact.restitution = 1; // othercontact.restitution = 1;
othercontact.velocity = collisionEntity.velocity.clone(); // othercontact.velocity = collisionEntity.velocity.clone();
othercontact.point = thispos.sub(normDist); // othercontact.point = thispos.sub(normDist);
othercontact.normal = normDist.clone(); // othercontact.normal = normDist.clone();
othercontact.contactDistance = contact.point.distance(position); // othercontact.contactDistance = contact.point.distance(position);
othercontact.force = 0; // othercontact.force = 0;
othercontact.penetration = this.radius - (thispos.sub(othercontact.point).dot(othercontact.normal)); // othercontact.penetration = this.radius - (thispos.sub(othercontact.point).dot(othercontact.normal));
this.marble.queueCollision(othercontact); // this.marble.queueCollision(othercontact);
} }
return contacts; return contacts;
} }

View file

@ -8,15 +8,14 @@ class MarbleUpdateQueue {
var otherMarbleUpdates:Map<Int, Array<MarbleUpdatePacket>> = []; var otherMarbleUpdates:Map<Int, Array<MarbleUpdatePacket>> = [];
var myMarbleUpdate:MarbleUpdatePacket; var myMarbleUpdate:MarbleUpdatePacket;
var ourMoveApplied:Bool = false; var ourMoveApplied:Bool = false;
var collisionFrame:Int;
public function new() {} public function new() {}
public function enqueue(update:MarbleUpdatePacket) { public function enqueue(update:MarbleUpdatePacket) {
var cc = update.clientId; var cc = update.clientId;
if (update.serverTicks < collisionFrame)
return;
if (cc != Net.clientId) { if (cc != Net.clientId) {
if (myMarbleUpdate != null && update.serverTicks > myMarbleUpdate.serverTicks)
ourMoveApplied = true;
if (otherMarbleUpdates.exists(cc)) { if (otherMarbleUpdates.exists(cc)) {
otherMarbleUpdates[cc].push(update); otherMarbleUpdates[cc].push(update);
} else { } else {
@ -29,8 +28,4 @@ class MarbleUpdateQueue {
} }
} }
} }
public function addCollisionFrame(tick:Int) {
collisionFrame = tick + 2;
}
} }

View file

@ -155,20 +155,21 @@ class MoveManager {
public function acknowledgeMove(m:Int) { public function acknowledgeMove(m:Int) {
if (m == 65535 || m == -1) if (m == 65535 || m == -1)
return -1; return null;
if (m <= lastAckMoveId) if (m <= lastAckMoveId)
return -1; // Already acked return null; // Already acked
if (queuedMoves.length == 0) if (queuedMoves.length == 0)
return -1; return null;
while (m != queuedMoves[0].id) { while (m != queuedMoves[0].id) {
queuedMoves.shift(); queuedMoves.shift();
} }
var delta = -1; var delta = -1;
var mv = null;
if (m == queuedMoves[0].id) { if (m == queuedMoves[0].id) {
delta = queuedMoves[0].id - lastAckMoveId; delta = queuedMoves[0].id - lastAckMoveId;
queuedMoves.shift(); mv = queuedMoves.shift();
} }
lastAckMoveId = m; lastAckMoveId = m;
return delta; return mv;
} }
} }