Jump to content

Unexpected client/server discrepancy in entity.rotationYaw


MrCaracal

Recommended Posts

Hello all!

 

I was toodling around with a block I had made, and inserted the following code into the Block class for the purposes of figuring out how entity rotation worked. The block, when placed, outputs the raw rotationYaw value of the placing entity to the console, once for the Client and once for the internal Server. The relevant function is below, everything else is standard boilerplate for a basic block class extending Block:

 

 

@Override
public void onBlockPlacedBy(World world, int xPos, int yPos, int zPos, EntityLivingBase placingEntity, ItemStack placingItemStack) {
	float rotation = placingEntity.rotationYaw;
	if (world.isRemote) {
		System.out.println("CLIENT: Placing Entity Rotation: " + rotation);
	}
	if (!world.isRemote) {
		System.out.println("SERVER: Placing Entity Rotation: " + rotation);
	}
}

 

 

However, when run, I noticed something that struck me as odd. As I rotate my character in place, the Client rotationYaw simply increases and increases seemingly forever, whereas the Server rotationYaw seems constrained within 0-360. Logging in and out does not seem to "synchronize" these values, and eventually results in angles that are not coterminal. (The Client rotationYaw minus a multiple of 360 does not always equal the Server rotationYaw). An example log output is below:

 

 

CLIENT: Placing Entity Rotation: -83.243095
SERVER: Placing Entity Rotation: -83.243095
CLIENT: Placing Entity Rotation: -350.84305
SERVER: Placing Entity Rotation: -354.29306
CLIENT: Placing Entity Rotation: -558.8931
SERVER: Placing Entity Rotation: -198.89313
CLIENT: Placing Entity Rotation: -675.1431
SERVER: Placing Entity Rotation: -314.84314
CLIENT: Placing Entity Rotation: -437.54324
SERVER: Placing Entity Rotation: -81.14325
CLIENT: Placing Entity Rotation: -732.5933
SERVER: Placing Entity Rotation: -12.593323
CLIENT: Placing Entity Rotation: -822.1435
SERVER: Placing Entity Rotation: -101.99347
CLIENT: Placing Entity Rotation: -931.04346
SERVER: Placing Entity Rotation: -211.04346
CLIENT: Placing Entity Rotation: -1050.1434
SERVER: Placing Entity Rotation: -330.14343
CLIENT: Placing Entity Rotation: -1141.6433
SERVER: Placing Entity Rotation: -61.64331
CLIENT: Placing Entity Rotation: -1210.4933
SERVER: Placing Entity Rotation: -130.49329
CLIENT: Placing Entity Rotation: -1255.3433
SERVER: Placing Entity Rotation: -175.19324
CLIENT: Placing Entity Rotation: -1327.7931
SERVER: Placing Entity Rotation: -247.04309
CLIENT: Placing Entity Rotation: -1367.2432
SERVER: Placing Entity Rotation: -284.99316
CLIENT: Placing Entity Rotation: -1389.4431
SERVER: Placing Entity Rotation: -309.2931
CLIENT: Placing Entity Rotation: -1442.8433
SERVER: Placing Entity Rotation: -1.0432129
CLIENT: Placing Entity Rotation: -1467.5931
SERVER: Placing Entity Rotation: -27.443115

 

And the same after logging out and in again:

 

CLIENT: Placing Entity Rotation: -377.54337
SERVER: Placing Entity Rotation: -17.543365
CLIENT: Placing Entity Rotation: -411.74344
SERVER: Placing Entity Rotation: -49.043457
CLIENT: Placing Entity Rotation: -469.34338
SERVER: Placing Entity Rotation: -108.74341
CLIENT: Placing Entity Rotation: -571.1934
SERVER: Placing Entity Rotation: -211.0434
CLIENT: Placing Entity Rotation: -619.64343
SERVER: Placing Entity Rotation: -256.79346
CLIENT: Placing Entity Rotation: -677.2434
SERVER: Placing Entity Rotation: -312.89337
CLIENT: Placing Entity Rotation: -757.1934
SERVER: Placing Entity Rotation: -32.843445

 

 

I'm just curious as to how this value is set, whether the client value is at all useful and whether it's simply the convention to test for server/client if rotationYaw is needed.

 

Thank you in advance for your time! I am extremely new to modding in general so I apologize if this is a stupid line of questioning.

 

I am running FML 7.2.156.1060 for Minecraft 1.7.2 on Java 64-Bit Server VM, version 1.6.0_65 on OSX.

Link to comment
Share on other sites

I am facing the same problem, The client sided rotationyaw is increasing during an active session.

I want an affected entity A to be facing an other entity B, so I have to invert the entity A's facing with the facing of entity B.

        String facing[] = 		{"S", "SW", "W", "NW", "N", "NE", "E", "SE"};
        String invertfacing[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
    	double yaw = ((target.getRotationYawHead()+22.5) % 360); //target being affected entity(A)
    	if (yaw < 0) 
    		yaw = 360 + yaw;

    	System.out.println(String.format("entity A facing: %s| entity B facing: %s", invertfacing[(int)(yaw / 45)],facing[(int)(yaw / 45)])); //

When the entity is facing South, mine will be facing North. This is a very dirty way of setting a rotationyaw. If entity B turns 180 degrees outwards, entity A will do too, making them no longer face eachother. And the whole point of my conception is to make entity A look at entity B.

( I am not using the EntityLookHelper class because it is not available in EntityLivingBase and EntityBodyHelper overrides instances of the EntityLookHelper class)

 

Link to comment
Share on other sites

Hi

 

Looking at 1.6.4. code, the server handler for Packet10 (eg Packet12Look) uses Entity.setRotation

   /**
     * Sets the rotation of the entity
     */
    protected void setRotation(float par1, float par2)
    {
        this.rotationYaw = par1 % 360.0F;
        this.rotationPitch = par2 % 360.0F;
    }

The client frequently sends look update packets to the server, so I am surprised they get significantly out of sync (after you %360.0F, I mean).  You might be seeing a slight synchronisation delay between client & server?  What if you modify your code to

System.out.println("CLIENT: Placing Entity Rotation: " + rotation % 360.0F);

Does the error get bigger and bigger over time or does the server lag behind the client by a reasonably constant amount?

 

@ShaneCraft:

If you want entity B to look at entity A, you need to calculate the angle based on the difference in their positions, eg using Math.atan2(deltax, deltaz).  The rotationYaw of A is not relevant.

 

http://www.mathsisfun.com/geometry/unit-circle.html  (Entity B is at  the centre of the circle, Entity A is the point on the circle.)

 

-TGG

 

 

Link to comment
Share on other sites

Agreed that the "always increasing" versus within 360 rangs shouldn't be any issue because it is common to use modulo to keep in range as in the example TheGreyGhost gave.  In fact, if you're ever comparing angles in computing, for most purposes you should remember to put both into range before the comparison as many methods can let them get out of range.

 

The only weirdness would be the discrepancy mentioned.  Again in the example cited, it takes the rotationYaw as the value (not an increment), and similarly if you look at the sendMotionUpdates() in the EntityClientPlayer class it sends the value (not an increment).  So it seems pretty clear that the client is sending the rotationYaw value directly to server and server is directly updating (with exception of aliasing to the 360 range).  The only possible discrepancy seems like it would be due to lag of however many ticks it might be between update packets.  I do see that the messages go into a queue (rather than being sent immediately) so lag is possible.  However again, when a packet is received it should sync it fully so unless you're continuously moving the Player entity it should sync up faster than human can really notice.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Thanks for the great input!

 

I actually did try the modulo thing before, but I left it out of the OP because I was most curious about the design reason for why the client increments whereas the server is clamped. I just can't figure out why it works this way and was wondering whether anybody with more experience knew.

 

As far as the "non-coterminal" thing: I tried it again, paying closer attention, and this time noticed the only times the angles diverged by any noticeable quantity (still less than 10° usually) was when the block was placed while the player was currently moving, or immediately after a log-in. If I'm reading you right, jabelar, this can be explained by the fact that the client will have the value nearly instantly, while the server is waiting for a packet to place the block, whereupon it checks the entity's rotation?

Link to comment
Share on other sites

Regarding clamped versus non-clamped angles, it is just a style thing although obviously there is a theoretically the problem with unclamped if the game ran for so long with the player spinning in just one direction that it actually overflowed, but that is not a realistic worry since the rotation is a float (so would take over 5x10^27 years of continuous turning). 

 

But in general programming practice clamping the angle is probably more correct/safe. 

 

The one danger with clamping can be if you have to handle the difference between angles or if the direction of change is important.  For example, is going -45degrees clockwise really the same as going 315degrees counter-clockwise?  If you only care about the angle in the moment it is, but what if you had an animation where the entity looked in the direction it was rotating, in that case you'd need to know direction.  And what if you were calculating physics of angular momentum, in that case going more degrees in same time period would have higher angular momentum.

 

Yeah, both diesieben07 and I are saying that in an individual tick the server and client could easily be off by the movement that occurred in the tick, and possibly longer depending on networking delay.  Network packets are asynchronous to the ticks, so there is no guarantee that server and client could be synced on a tick by tick basis.  If the discrepancy was large I'd be worried, but 10degrees sounds quite expected.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.