Skip to content

Commit 87aa5d8

Browse files
committed
fix: server/client blocks getting out of sync during frame move
1 parent c9a8502 commit 87aa5d8

File tree

3 files changed

+131
-60
lines changed

3 files changed

+131
-60
lines changed
Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,70 @@
11
package mrtjp.projectred.api;
22

3-
import net.minecraft.core.Direction;
43
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
55
import net.minecraft.world.level.Level;
66

77
/**
88
* Interface for an object that manages the movement of blocks and tiles that are
99
* registered to it. This class should be registered through the {@link IExpansionAPI}.
10+
* <p>
11+
* The order of calls are:
12+
* <ol>
13+
* <li>Server receives {@link #canMove(Level, BlockPos)} </li>
14+
* <li>Server receives {@link #move(Level, BlockPos, Direction)}</li>
15+
* <li>Client receives {@link #move(Level, BlockPos, Direction)}</li>
16+
* <li>Client receives {@link #postMove(Level, BlockPos)}</li>
17+
* <li>Server receives {@link #postMove(Level, BlockPos)}</li>
18+
* </ol>
1019
*/
1120
public interface BlockMover {
21+
1222
/**
1323
* Used to check if the block at the given position can move. This
1424
* method is only called if the specified block is tied to this
1525
* handler, so there is no need to check if the block is valid
1626
* for this handler. This is called before actually moving. If
1727
* everything is able to move, an animation will start.
1828
* <p>
19-
* Called server-side only when determining what to move.
29+
* Called server-side only.
2030
*
21-
* @param w The world.
22-
* @param pos The position of the block to move.
31+
* @param w The world.
32+
* @param pos The position of the block before movement.
2333
* @return True if the block at the given position is able to move.
2434
*/
2535
boolean canMove(Level w, BlockPos pos);
2636

2737
/**
2838
* Method used to actually move the tile. Called after the animation
29-
* has run. This is where you should tell the tile that it is time
30-
* to move, and peform any extra checks or calls. This should also
31-
* move the block and tile as well. This is called
32-
* on every block in the moving structure sequentially.
39+
* has run. This is where you should tell the tile that it is time
40+
* to move, and perform any extra checks or calls. This should also
41+
* move the block and tile as well. This is called on every block in
42+
* the moving structure sequentially.
3343
* <p>
34-
* Called on both server and client.
44+
* Called on server then client. Note that after server call, block
45+
* positions of client/server are out of sync. Do not send packets
46+
* to client referencing blocks by position, update neighbors, mark
47+
* chunk for re-render, etc.
3548
*
3649
* @param w The world.
37-
* @param pos The position of the block to move.
50+
* @param pos The position of the block before movement.
3851
* @param dir The ForgeDirection the structure is moving in.
3952
*/
4053
void move(Level w, BlockPos pos, Direction dir);
4154

4255
/**
43-
* Called after all blocks in the group have moved to their
44-
* new locations. This is where you would reload your tile,
45-
* tell it to refresh or reacknowledge its new position.
56+
* Called after all blocks in the group have moved to their new locations.
57+
* This is where you would reload your tile, tell it to refresh or
58+
* re-acknowledge its new position. No need to update neighbors, since
59+
* they are batch-notified after all blocks (moved and adjacent to moved)
60+
* get postMove call.
4661
* <p>
47-
* Called on both server and client.
62+
* Called on client then server. At this point, both client and server
63+
* blocks are in sync at new positions. It is safe to send packets
64+
* with position references.
4865
*
49-
* @param w The world.
50-
* @param pos The position of the block to move.
66+
* @param w The world.
67+
* @param pos The position of the block after movement.
5168
*/
5269
void postMove(Level w, BlockPos pos);
5370
}

api/src/main/java/mrtjp/projectred/api/MovementDescriptor.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,30 @@ public interface MovementDescriptor {
1313

1414
enum MovementStatus {
1515
/**
16-
* Failed to begin movement (collision, unmovable block in structure, etc)
16+
* Movement pending start. Default state when first created
1717
*/
18-
FAILED,
18+
PENDING_START,
1919
/**
20-
* Movement in progress
20+
* Movement animation in progress while block remains in initial position
2121
*/
2222
MOVING,
2323
/**
24-
* Movement finished successfully
24+
* Movement animation has completed but still awaiting execution of movement.
25+
* Block is still in initial position.
26+
*/
27+
PENDING_FINALIZATION,
28+
/**
29+
* Movement finished successfully and block is in final position
2530
*/
2631
FINISHED,
2732
/**
2833
* Movement cancelled before completion (chunk was unloaded, etc)
2934
*/
3035
CANCELLED,
36+
/**
37+
* Failed to begin movement (collision, unmovable block in structure, etc)
38+
*/
39+
FAILED,
3140
/**
3241
* Unknown status
3342
*/

0 commit comments

Comments
 (0)