Yeah, it's not a lot
My (much much) simpler games are working okay with a sort of async data structure like so:
* Crafty Tanks
* ============
* [0] Packet Type
* [1] myTank xPos
* [2] myTank yPos
* [3] myTank Direction/Action Indicator
* - Bits 0-4: Direction
* - Bits 5-6: Action
* - Bit 7: Shoot/Fire indicator
* [4] Their Bullet xPos
* [5] THeir Bullet yPos
* [6] Their BulletID
* - The other client doesn't care *what* the BulletID
* is, but it can check against NULL_SPRITE to determine
* whether there is a bullet at the moment or not
* [7] My Health
Essentially - each client is responsible for their own "character" sprite and the "enemy" bullets - to keep all collision detection local basically - oh, and I'm reducing the fidelity of the sprite positions to u8 for transfer (internally, the games run on u16 for sprite positions to give me options for sub-pixel movement)
But Bomberman has a lot more going on - I guess you could compress the playfield down to 8 bytes or so? So, one frame update playfield, next update players etc? Going to get really tight, really quick.
This is what tixu came up for keeping in sync - I ended up fixing it my original way (as above basically) and might come back to this approach for more complex stuff
> Last one: I'd drop the ball handover rather than debug it. Your packets carry no step number and no owner, so during handover each side keeps applying the peer's last known state, its own position from a few frames back. That's the double bounce, and it's structural. Input lockstep removes the problem instead of managing it: each console sends only its pad for step N, neither advances without the other's, both simulate the ball. No state on the wire, no two truths, no handover. Use 2 steps of input delay (measured: 0 = 20 fps, 1 = 44 % stalled frames, 2 = 13 waiting frames out of 600) and set NGPC_LINK_RX_QUEUE to 4 or 8, at 0, two packets in one frame overwrite each other and you desync silently. Step number in every packet, integer physics, no QRandom() on the shared path. <
I struggle to understand Claude-speak, but I think that this relies on the game being completely deterministic - and you'd have to process both players based on the JOYPAD struct being passed back-and-forth - I suppose you could pre-populate the power-up locations before the round starts which is your main element of chance during gameplay?
My (much much) simpler games are working okay with a sort of async data structure like so:
* Crafty Tanks
* ============
* [0] Packet Type
* [1] myTank xPos
* [2] myTank yPos
* [3] myTank Direction/Action Indicator
* - Bits 0-4: Direction
* - Bits 5-6: Action
* - Bit 7: Shoot/Fire indicator
* [4] Their Bullet xPos
* [5] THeir Bullet yPos
* [6] Their BulletID
* - The other client doesn't care *what* the BulletID
* is, but it can check against NULL_SPRITE to determine
* whether there is a bullet at the moment or not
* [7] My Health
Essentially - each client is responsible for their own "character" sprite and the "enemy" bullets - to keep all collision detection local basically - oh, and I'm reducing the fidelity of the sprite positions to u8 for transfer (internally, the games run on u16 for sprite positions to give me options for sub-pixel movement)
But Bomberman has a lot more going on - I guess you could compress the playfield down to 8 bytes or so? So, one frame update playfield, next update players etc? Going to get really tight, really quick.
This is what tixu came up for keeping in sync - I ended up fixing it my original way (as above basically) and might come back to this approach for more complex stuff
> Last one: I'd drop the ball handover rather than debug it. Your packets carry no step number and no owner, so during handover each side keeps applying the peer's last known state, its own position from a few frames back. That's the double bounce, and it's structural. Input lockstep removes the problem instead of managing it: each console sends only its pad for step N, neither advances without the other's, both simulate the ball. No state on the wire, no two truths, no handover. Use 2 steps of input delay (measured: 0 = 20 fps, 1 = 44 % stalled frames, 2 = 13 waiting frames out of 600) and set NGPC_LINK_RX_QUEUE to 4 or 8, at 0, two packets in one frame overwrite each other and you desync silently. Step number in every packet, integer physics, no QRandom() on the shared path. <
I struggle to understand Claude-speak, but I think that this relies on the game being completely deterministic - and you'd have to process both players based on the JOYPAD struct being passed back-and-forth - I suppose you could pre-populate the power-up locations before the round starts which is your main element of chance during gameplay?

