mostly get marble collisions working

This commit is contained in:
RandomityGuy 2024-01-30 00:06:07 +05:30
parent 42ec5701e3
commit 0a8c46b0ae
5 changed files with 64 additions and 51 deletions

View file

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

View file

@ -1028,21 +1028,23 @@ class MarbleWorld extends Scheduler {
if (!lastMoves.ourMoveApplied) {
var ourMove = lastMoves.myMarbleUpdate;
if (ourMove != null) {
marble.unpackUpdate(ourMove);
for (client => arr in lastMoves.otherMarbleUpdates) {
var lastMove = null;
while (arr.length > 0) {
var p = arr[0];
if (p.serverTicks <= ourMove.serverTicks && p.serverTicks >= ourMove.collisionToken) {
clientMarbles[Net.clientIdMap[client]].unpackUpdate(p);
if (p.serverTicks <= ourMove.serverTicks) {
lastMove = arr.shift();
} else {
break;
}
}
if (lastMove != null)
if (lastMove != null) {
if (ourMove.serverTicks == lastMove.serverTicks)
clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove);
arr.insert(0, lastMove);
}
}
marble.unpackUpdate(ourMove);
}
}
}
@ -1052,9 +1054,10 @@ class MarbleWorld extends Scheduler {
var ourLastMove = lastMoves.myMarbleUpdate;
if (ourLastMove == null)
return;
var ackLag = -1;
var ackLag = @:privateAccess Net.clientConnection.moveManager.queuedMoves.length;
var mvStored = null;
if (!lastMoves.ourMoveApplied)
ackLag = Net.clientConnection.moveManager.acknowledgeMove(ourLastMove.move.id);
mvStored = Net.clientConnection.moveManager.acknowledgeMove(ourLastMove.move.id);
else
return;
@ -1065,6 +1068,12 @@ class MarbleWorld extends Scheduler {
var advanceTimeState = timeState.clone();
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)
if (!lastMoves.ourMoveApplied) {
@:privateAccess this.marble.isNetUpdate = true;
@ -1077,36 +1086,39 @@ class MarbleWorld extends Scheduler {
for (client => arr in lastMoves.otherMarbleUpdates) {
if (arr.length > 0) {
var m = arr[0];
if (m.serverTicks <= ourLastMoveTime && m.serverTicks >= ourLastMove.collisionToken) {
m.calculationTicks = Std.int(/*ourLastMoveTime - m.serverTicks + */ ourQueuedMoves.length);
if (m.serverTicks == ourLastMoveTime) {
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
m.calculationTicks = Std.int(ackLag / 2);
marblesToTick.set(client, m);
arr.shift();
}
}
}
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
for (move in ourQueuedMoves) {
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.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors);
if (this.marble.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
for (client => m in marblesToTick) {
if (m.calculationTicks > 0) {
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;
@:privateAccess marbleToUpdate.isNetUpdate = true;
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
@:privateAccess marbleToUpdate.isNetUpdate = false;
if (marbleToUpdate.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
m.calculationTicks--;
var afterPos = @:privateAccess marbleToUpdate.newPos;
}
}
currentTick++;
@ -1122,8 +1134,6 @@ class MarbleWorld extends Scheduler {
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
@:privateAccess marbleToUpdate.isNetUpdate = false;
if (marbleToUpdate.collidingMarbles.length > 0)
this.lastMoves.addCollisionFrame(currentTick);
m.calculationTicks--;
}
}
@ -1331,12 +1341,22 @@ class MarbleWorld extends Scheduler {
fixedDt.dt = 0.032;
tickAccumulator -= 0.032;
var packets = [];
marble.updateServer(fixedDt, collisionWorld, pathedInteriors, packets);
var myMove = marble.updateServer(fixedDt, collisionWorld, pathedInteriors);
var otherMoves = [];
for (client => marble in clientMarbles) {
marble.updateServer(fixedDt, collisionWorld, pathedInteriors, packets);
otherMoves.push(marble.updateServer(fixedDt, collisionWorld, pathedInteriors));
}
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!
// var pktClone = packets.copy();
// pktClone.sort((a, b) -> {
// return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0;
// });
for (packet in packets) {
client.datachannel.sendBytes(packet);
}

View file

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

View file

@ -8,15 +8,14 @@ class MarbleUpdateQueue {
var otherMarbleUpdates:Map<Int, Array<MarbleUpdatePacket>> = [];
var myMarbleUpdate:MarbleUpdatePacket;
var ourMoveApplied:Bool = false;
var collisionFrame:Int;
public function new() {}
public function enqueue(update:MarbleUpdatePacket) {
var cc = update.clientId;
if (update.serverTicks < collisionFrame)
return;
if (cc != Net.clientId) {
if (myMarbleUpdate != null && update.serverTicks > myMarbleUpdate.serverTicks)
ourMoveApplied = true;
if (otherMarbleUpdates.exists(cc)) {
otherMarbleUpdates[cc].push(update);
} 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) {
if (m == 65535 || m == -1)
return -1;
return null;
if (m <= lastAckMoveId)
return -1; // Already acked
return null; // Already acked
if (queuedMoves.length == 0)
return -1;
return null;
while (m != queuedMoves[0].id) {
queuedMoves.shift();
}
var delta = -1;
var mv = null;
if (m == queuedMoves[0].id) {
delta = queuedMoves[0].id - lastAckMoveId;
queuedMoves.shift();
mv = queuedMoves.shift();
}
lastAckMoveId = m;
return delta;
return mv;
}
}