Posted June 24, 201411 yr Okay, I'm creating a "golden egg" throwable which behaves much like a regular egg -- i.e. you can throw it with chance to spawn. It all works, except that the rendering shows that the egg simply falls to the ground from my hand. However, the actual throwing works because the entity is spawned where I'm aiming. I'm only spawning on the server, and the entity does render and starts out at position of my hand, so that means that client is getting synced with the entity info. However, based on console statements I print out, the motion of the entity is not synced to the client. Here is the console debug output, and I output position and motion at the constructor, the spawning invocation, and during the render call. Also I'm testing the entity.worldObj.isRemote to determine if I'm on the client side in each section. You can see that on the server that the motion is correctly created, but it is not on the client. Constructing on client side =false Constructor: Thrown egg entity position =77.45064475603044, 69.52000000327826, 275.07749916219655 Constructor: Thrown egg entity motion =0.988977837973542, -0.09932768215581204, -1.102844910096875 Spawning on client side =false On spawn: Thrown egg entity position =77.45064475603044, 69.52000000327826, 275.07749916219655 On spawn: Thrown egg entity motion =0.988977837973542, -0.09932768215581204, -1.102844910096875 Rendering on client side =true Thrown egg entity position =77.4375, 69.5, 275.0625 Thrown egg entity motion =0.0, -0.029999999329447746, 0.0 So the positions are synced but not the motion. You can see that on the client side it only has a Y motion which is exactly what it looks like when I play the mod. Any ideas? Some code that may be of interest. Constructor of throwable golden egg. Note that the super constructor adds motion based on player's facing direction and aim point: public class EntityGoldenEggThrown extends EntityThrowable { public EntityGoldenEggThrown(World par1World) { super(par1World); } public EntityGoldenEggThrown(World par1World, EntityLivingBase par2EntityLivingBase) { super(par1World, par2EntityLivingBase); // DEBUG System.out.println("Constructing on client side ="+worldObj.isRemote); System.out.println("Constructor: Thrown egg entity position ="+posX+", "+posY+", "+posZ); System.out.println("Constructor: Thrown egg entity motion ="+motionX+", "+motionY+", "+motionZ); } The point where I spawn the egg (in an ItemGoldenEgg class that is held in the hand): @Override public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { if (!par3EntityPlayer.capabilities.isCreativeMode) { --par1ItemStack.stackSize; } par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); if (!par2World.isRemote) { entityEgg = new EntityGoldenEggThrown(par2World, par3EntityPlayer); par2World.spawnEntityInWorld(entityEgg); // DEBUG System.out.println("Spawning on client side ="+par2World.isRemote); System.out.println("On spawn: Thrown egg entity position ="+entityEgg.posX+", "+entityEgg.posY+", "+entityEgg.posZ); System.out.println("On spawn: Thrown egg entity motion ="+entityEgg.motionX+", "+entityEgg.motionY+", "+entityEgg.motionZ); } return par1ItemStack; } And the render class's doRender() method, which I copied from regular egg: @Override public void doRender(Entity parEntity, double parX, double parY, double parZ, float parIgnored1, float parIgnored2) { IIcon iicon = itemBasisForEntity.getIconFromDamage(iconIndex); if (iicon != null) { GL11.glPushMatrix(); GL11.glTranslatef((float)parX, (float)parY, (float)parZ); // DEBUG System.out.println("Rendering on client side ="+parEntity.worldObj.isRemote); System.out.println("Thrown egg entity position ="+parEntity.posX+", "+parEntity.posY+", "+parEntity.posZ); System.out.println("Thrown egg entity motion ="+parEntity.motionX+", "+parEntity.motionY+", "+parEntity.motionZ); GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glScalef(0.5F, 0.5F, 0.5F); bindEntityTexture(parEntity); Tessellator tessellator = Tessellator.instance; if (iicon == ItemPotion.func_94589_d("bottle_splash")) { int i = PotionHelper.func_77915_a(((EntityPotion)parEntity).getPotionDamage(), false); float f2 = (i >> 16 & 255) / 255.0F; float f3 = (i >> 8 & 255) / 255.0F; float f4 = (i & 255) / 255.0F; GL11.glColor3f(f2, f3, f4); GL11.glPushMatrix(); invokeTesselator(tessellator, ItemPotion.func_94589_d("overlay")); GL11.glPopMatrix(); GL11.glColor3f(1.0F, 1.0F, 1.0F); } invokeTesselator(tessellator, iicon); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glPopMatrix(); } } Anyway, I thought motion would be automatically synced! Check out my tutorials here: http://jabelarminecraft.blogspot.com/
June 24, 201411 yr Anytime I've done this, I have had to set the motion myself on both client and server. Long time Bukkit & Forge Programmer Happy to try and help
June 24, 201411 yr Author Anytime I've done this, I have had to set the motion myself on both client and server. That's what it looks like. I thought that basic entity fields would be synched automatically since presumably vanilla entities are synched. Oh well ill sync it. Check out my tutorials here: http://jabelarminecraft.blogspot.com/
June 24, 201411 yr I tried to trace out that code recently to figure out why it wasn't working and I couldn't find the error. During my efforts and such I noticed some oddities on when the entity appears on the client. For example, another player on the client originally doesn't have the right UUID. It gets fixed shortly after creation, but I haven't been able to get the sequence right. I watch on the client for the uuid of a player to change and then ask the server for certain things from its extendproperties instead of doing it when created. Minor thing, but they both tie together on how minecraft sync's the client and server (or doesn't). For anything with a trajectory, I end up setting it in the constructor (usually a custom one). Once it is moving, things seem to stay together. At one point I added some datawatchers to make sure position and motion were syncd. It was funny. The damn fireball looks liked it was having a seizure as it moved through the air. Long time Bukkit & Forge Programmer Happy to try and help
June 24, 201411 yr Author At one point I added some datawatchers to make sure position and motion were syncd. It was funny. The damn fireball looks liked it was having a seizure as it moved through the air. Syncing motion between client and servers is actually a difficult art. It is a common problem in any multiplayer action game where lag or discrepancy will cause trouble for players trying to shoot, jump, etc. It is usually considered "best" (for the visual integrity) to have the client do some prediction to fill in the intermediate points between sync. For example, for a ballistic entity you shouldn't sync the actual position but rather just sync the starting condtions (position and velocity vector) and server only sends sync when something significant happens (i.e. hit an enemy). Anyway, I appreciate your response as I was suspicious about the same potential issues regarding syncing. I'll try some experiments with making it more explicit. Check out my tutorials here: http://jabelarminecraft.blogspot.com/
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.