Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Posts posted by jabelar

  1. The event is probably technically working, but I suspect that most rendering code overwrites whatever you do there. The rendering events are good for ADDING something else to be rendered, or fully replacing what is rendered, but not really good for changing what is rendered. 

     

    It is actually usually good practice for any rendering code to sort of "reset" some of the GL stuff to a known state, exactly so other code running before it can't mess it up.

     

    Now Minecraft code is quite inconsistent so you might get lucky and find some places where a judiciously placed alpha change will affect the next thing rendered but it would be hard to count on it, as you found out.

     

    If you're really good at GL, you might be able to push/pop a matrix to apply the alpha but you'd have to take care to handle the events symmetrically so that you don't end up overflowing the matrix stack.

     

    If you're ambitious you can replace all the renderers for the vanilla entities with ones how you want, but doing it for other mobs would be tough.

     

    Sorry, maybe someone has a clever idea to do what you're looking for. Otherwise, I'd trace through the various rendering code to see if there is a place to surgically insert an alpha change.

     

     

  2. 16 hours ago, MrDireball said:

    Ah, I was looking in EntityAnimal for it, it completely slipped my mind to check inside an interface that it implements. Thanks.

    Your IDE should allow you to see all fields and methods for a class. In Eclipse it is called the Type Hierarchy. Just right-click on the class in the project hierarchy pane and select Type Hierarchy. There are a couple of "buttons" that affect the filtering of the view, I like to show everything including the inherited methods.

     

    That is a better way to scan for available methods than simply scrolling through class files themselves.

     

    In modding it is especially useful to look at the Type Hierarchy because you can actually get a lot of ideas for modding after you see some of the available methods, and at least get a really good feel for how the interfaces are organized.

  3. Yes it is a common problem in client-server games. Ideally all "game truth" is enforced by the server but in order to get smooth movement and minimize network traffic the client usually processes the immediate movement with the server just sampling it to check the validity. But the problem then is how much "tolerance" the server has in this verification. The server can and does rule out impossible movement but what about the fringes of what is possible?

     

    As an ethical mod maker you can add a barrier to using it for cheating yourself by making your mod require that it also be loaded on the server. Of course a hacker type person could still figure out a work around I'm sure, but at least you know that you have done as much as the vanilla game itself does to protect against it.

  4. The entity bounding boxes need to have the same length and width (i.e. square base). I believe this is to simplify path-finding. Similarly note that the bounding box never rotates even when the model does, so it wouldn't be that helpful even if you could specify different values.

     

    EDIT: Also the setEntityBoundingBox() method set's the actual box in the world meaning the values of the box would be related to the entity position. If the size was 2.0 wide and the entity is at x position of 300 then the bounding box would go from 299 to 301.

     

    You shouldn't ever use the setEntityBoundingBox() method as it is meant for updating the position of the bounding box based on the size and position.

    • Like 1
  5. I don't think your code will move them in a circle. It might spawn them in a circle, although the code for that looks a little weird for that too.

     

    Let's go through you update() method in the hastebin link.

     

    The first important thing is -- where is this update code? If you want to move the particles it would need to be in the particle class, but I kind of suspect you have it somewhere else like in an entity. 

     

    So your first mistake is that your code isn't moving the particles, it is just spawning them constantly. It might also be possible to used particles in fixed positions and "animate" them by killing and spawning them quickly but I don't think it would work well visually. So I think you need your particle class to remember the center of the circle and the angle, and then in the update method for the particle you would add some angle and adjust the position (not respawn) accordingly.

     

    Additionally, I think your math is still suspicious. Your code to use trigonometry to adjust the X and Z positions looks like:
         double angle = Math.toRadians(degrees);
         double vx = (pos.getX() + 0.3) * Math.cos(angle) - pos.getZ() * Math.sin(angle);
         double vz = pos.getX() * Math.sin(angle) + pos.getZ() * Math.cos(angle);

     

    I'm pretty sure the math is wrong here. The X and Z positions are the values in the world, so they can be numbers like 600 or 0 or -600. Instead I think you should be multiplying by a radius for the circle as the vx and vz fields presumably indicate the difference in position relative to the center. Also, you're mixing up the two dimensions. Sin and Cos functions already take and angle and separate it into the two dimensional components, so I think it should be something more like:

         double angle = Math.toRadians(degrees);

         double radius = 2.0D;
         double vx = radius * Math.cos(angle);
         double vz = radius * Math.sin(angle);

     

    Then instead spawning the particles again, you should just move them. Also, you shouldn't move them based on current position, but recalculate from the center of the circle. So the new positions would be something like (this is pseudo code because you need to put the code into the right place with a field for the center:  

         this.setPos(particleCenterX + vx, this.getPosY(), particleCenterZ + vz);

     

    Summary

     

    Putting it all together:

    1. The movement code needs to be in the update for the particle class which runs on the client side. You can't just keep spawning particles.
    2. I would have the particle "remember" where the center of the circle should be.
    3. You need to have a sense of "radius" for the circle.
    4. You simply update the particle position with very simple trigonometry such as center + radius * cos(angle) 
    • Thanks 1
  6. The issue is that the term "entity" usually implies a number of things (such as registration) and functionality (like AI) that is expected to also be run on the server.

     

    ESPECIALLY note that if you want to do the following then the server MUST be involved:

    • Syncing across multiple clients so that all players can see the entity.
    • Saving so that the entity persists across saves.

    There are cases though where it can make sense for an entity that exists only for each play on the client side. In that case I think your best bet for client-side "entity" behavior is to create your own system. All an entity really is is a loop of code that runs along with some rendering. So you can simply have a tick handler running the AI and some rendering that hooks into the normal rendering process. But it is somewhat of an advanced approach that would require decent programming skills and fairly high modding experience.

  7. For your original question, yes the approach of having a simple "queue" for scheduling things should work. The actual mechanics of the queue can be coded in different ways depending on how many things and how far in time you want to queue things. Unless there is a performance concern due to having a huge number of scheduled events, almost any sort of collection can be used that you cycle through.

     

    One detail is that if you're doing this for worlds that might be saved, you'll probably want the time to continue when the world is loaded again. In that case, you should also save the queue to world save data or maybe the player data depending on what sort of things you're scheduling.

  8. I think so. I think maybe you can maybe you can handle the RenderHandEvent or the RenderSpecificHandEvent. You might also want to rotate the original model. 

     

    Note that it (in order to be more gun-like) may be more important to control the rotation of the whole hand.

  9. I'm fairly aware of how all that works. However, I always thought the lighting recalculation was a fairly localized thing. In fact I optimized a massive structure generator by making my own set block method which didn't update the lighting until the end and only did so in a few specific locations rather than recursively throughout the whole structure.

     

    The weird thing that is new to me (and hence my question) is why it shows literally 50 chunk updates in conjunction with this placement. I could see why the current chunk might update (actual block placement plus lighting updates) and I could see why a neighboring chunk or two would probably update since the light can spread over 15 radius. But it seems to be way over-doing it.

  10. So I've got a mod that is fairly popular which allows moving lights. But some people have complained about frame rate drop when moving with a light source. However, the general idea is quite simple -- I'm just placing an invisible block with tile entity that has a light level. The tile entity takes care of things like removing the block if the light source moves away. At any given time there is only a couple blocks at most per light source. But if you're moving then a block gets added and old one gets deleted as you move from one position to the next.

     

    Anyway, it really shouldn't cause too much perf lag. If you're standing still, it doesn't lag, so it seems to be related to the adding of the blocks. I've gone through and commented out the code to confirm this. Furthermore I played with different flags and notifications in the setBlockState() and related methods.

     

    I don't think the light part is actually the problem, I think it is simply the placement of the block. So my question is: Why would like 40 to 50 chunk updates be triggered by placing a block in the player's location using standard World#setBlockState() method?

  11. Basically, the "payload" you put into an IMessage is up to you. It is just a series of bytes that represents something. As long as you take the bytes out in the same order as you put them in then you have successfully transmitted the data.

     

    So then it depends on how complicated the object is. If it contains collections of other objects it could get pretty complicated, but still doable if you just take your time to think about the order things get written to the buffer. If your object has simple fields then it is super easy -- just add them to the buffer and read them back in the same order.

     

    There is nothing special about IMessage really -- it just takes a buffer full of bytes and gets them on and off the network. Up to you what you do with those bytes.

     

    IMPORTANT: You're never really "sending the object" but instead you're sending enough information to recreate the object (or sync it if it already exists). Technically there are two objects, one on each side of the connection and the packets are making sure they have the same data.

  12. Okay, I stand corrected about single player mode. There are things like inventory and capabilities that persist, but modded things like tameable entity ownership can have trouble.

     

    I always test in dedicated server mode -- I highly recommend most modders should do this to avoid all those "side-only" problems people invariably run into. As you mentioned, in the dedicated server (i.e. multiplayer) mode, each new run of a client that connects will cause inventory and capabilities to disappear affecting continuity of your testing unless you force the login.

     

    In both cases, it is probably "safest" to force the login if you're doing things related to specific players.

  13. 8 minutes ago, V0idWa1k3r said:

    These are in no way related to UUIDs in single player which is where you will spend most of your time modding. Player data is stored within the level.dat file and that includes the capabilities.

     

    I don't think you understand the problem. If you don't set the run configuration, every time you run in single player you will be a new player (Player123, etc.). If you have anything in your mod that depends on this, (usually things that "remember the player" like tamed animals and such) -- for example I have tile entities which keep track of which player placed them, then anything you do in one game session will not persist in the next.

     

    Technically, the game DOES save in the dat for the previous player, but you can't really access that because you can't log in as that player again.

     

    You're not the same player each time you run from Eclipse unless you force it with the Run Configuration.

  14. Well there are some methods related to attacking in the entity, but those are for dealing the damage and only happen on the exact tick of the attack (which also might be too late for the animation to start). Animations normally progress over several ticks. I think it might make sense to trigger it using the AI classes for your custom entity. However, the AI runs on the server (I'm pretty sure) and not the client where you want the animations.

     

    I guess I would probably have the AI trigger it. If you look at the EntityAIAttackMelee class you can see what I mean. In that class, in the update() method the entity will try to close the distance to the target and then it runs the checkAndPerformAttack() method. In that method, if the distance is close enough it will perform the attack which includes the vanilla swingArm() method for the animation which updates the progress of the animation and also sends a packet to the client tracking system.

  15. 3 hours ago, desht said:

    And yet McJty's compatlayer allowed binary compatibility between mods for 1.10 and 1.11.  So it is possible, but probably more work than is worth it in the long run (as I mentioned, McJty dropped compatlayer for 1.12).

     

    Yes, it is definitely possible but as my long "essay" above notes it is rarely worth it. 1.10 to 1.11 was a rare transition with very little big things changing between them. Most versions are much more drastic.

     

    But imagine going from a version before blockstates was introduced to afterwards -- you'd need to like replicate the whole system of one of the two approaches in order to make them compatible. Or imagine going from a version before capabilities to one afterwards, and so forth.

     

    So like I said before -- you can do it but only if you "pick your battles". If your mod focuses on a specific thing like entities and that doesn't change much between versions then it might be worth a compatibility layer. 

    • Like 2
  16. Well, more accurately you can subscribe to anything that descends from Event class and is also posted on the main EVENT_BUS. There are actually events related to ore generation for example that are posted on a different bus and you have to register your listener differently because the annotation method of subscribing only works (as far as I know) for the main event bus.

×
×
  • Create New...

Important Information

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