[POC] BlockAPI - Custom Blocks

Discussion in 'Plugin Development' started by Icyene, Sep 30, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Comphenix

    Hm, what version of CraftBukkit are you running? And, you might have to reload the server again. There might be a very rare bug in ProtocolLib that causes it, but I have been unable to reproduce it properly. When it does occur (rarely), I'm never able to debug it, as recompiling or reloading the server fixes it.

    In any event, I've updated BlockAPI. Had to fix some serious client crashes that were caused by the byte value overflowing into negative numbers (whoever decided to make byte signed should be shot). I've also renamed it to BlockPatcher, just like you suggested, and moved the testing code out into a separate plugin (BlockTest). That way, it won't conflict with future users of the API.

    You can get BlockPatcher here.

    In addition, I've noticed a pretty serious bug with ProtocolLib. If you're running 1.3.2, you're guaranteed to fall into the void when you log on the server. So, I guess I have to release yet another version today. You can get it here. :p
     
  2. Offline

    Megolas

    Icyene, I have to admit, I never got into your texture hack at the time - but would it be possible to stream a custom texture for each of the new blocks as well?
     
  3. No, unforunately not without replacing the normal representation as well. the client doesn't actually know that it's a custom block and simply uses the original properties of the block.

    BlockAPI didn't work for me at first as well, because it was loading before ProtocolLib. I figured that you misspelled the yaml entry for "depend" (needs to be without an s). After changing that, it worked.

    Couldn't test out the new version yet (on the phone).

    Have you thought about data values? For example disguising as colored wool or disguising differently based on data value. That adds another layer and destroys he concept of a lookup array, though, I suppose. But Would definitely be necessary to make for a complete API.
     
  4. Offline

    Icyene

    As Bone008 said, no :( However, you could add a texture to the purple blocks, and then set a wool block to a data value of <insert max wool data value here>. That's as close as you can get to a new block: wool with higher data values than the max are rendered as those empty pink things.
     
  5. Offline

    Megolas

    Icyene
    So why not do that?
     
  6. Offline

    Icyene

    Megolas Because that would only allow ONE new block, and its name would still be wool.
     
  7. Offline

    Comphenix

    I've updated BlockPatcher to now filter data values as well. It was quite the journey though.

    The data values themselves are exchanged using a two-dimensional lookup table (with manual indexing) of block ids and every possible data value (0 - 15). That way, you could, say, map the Tekkit Redpower ore blocks to colored wool blocks. This mapping also works for blocks of the same ID, so for instance, you could randomize the color of every wool block in the game.

    Unfortunately, this lookup table is relatively large (256 * 16 bytes = 4096 bytes), and the total processing time for every chunk increases on average by 200%. You can get the benchmark details here.

    A typical player logging in receives about 400 chunks (a view distance of 10 chunks in each cardinal direction), and this takes the processing time from 15 ms to 45 ms. However, on two example runs, one without the data filter and one with it, the total amount of processing time was actually 35 ms without the filter, compared to 118 ms with it enabled. It looks like the JIT compiler is causing some spikes for the initial chunks. But that would only occur for the first player logging in - the rest would require somewhere around the average time.

    In any event, the updated version of BlockPatcher (version 1.2.0) can be found on GitHub. I also fixed the "depend" problem
    Bone008 mentioned. Bit of a schoolboy error, I admit. :p

    I probably should also mention the updated API. Obviously, I had to add a function for mapping data values (where a block of a given ID and data value gets a replaced data value), but I also changed the item lookup to a general Bukkit event instead.

    Items store their data in a short instead of a nibble, yielding 2^16 possible values, which together with the increased ID space (2^15 - 1, I reckon), is simply infeasible as a lookup table. A general event handler is the best option.
    Code:java
    1. public class BlockTestMod extends JavaPlugin implements Listener {
    2.  
    3. @Override
    4. public void onEnable() {
    5. PatcherAPI api = PatcherMod.getAPI();
    6.  
    7. // Testing API
    8. api.setBlockLookup(Material.SAND.getId(), Material.GLASS.getId());
    9. api.setBlockLookup(Material.GRASS.getId(), Material.WOOL.getId());
    10.  
    11. for (int i = 0; i < 16; i++)
    12. api.setDataLookup(Material.GRASS.getId(), i, 5);
    13.  
    14. getServer().getPluginManager().registerEvents(this, this);
    15. }
    16.  
    17. @EventHandler
    18. public void onItemConverting(ItemConvertingEvent event) {
    19. for (ItemStack stack : event.getItemStacks()) {
    20. if (stack.getTypeId() == Material.SAND.getId()) {
    21. stack.setTypeId(Material.GLASS.getId());
    22. }
    23. }
    24. }
    25. }


    I forgot to remove the benchmark code in version 1.2.0, so here's a version without it.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
    Bone008 likes this.
  8. Offline

    superpeanut911

    This looks rather interesting, Keeping an eye on this thread.
     
  9. Offline

    Wolftein

    I Just saw this, you should look at my plugin!. (Check the source code in github). My plugin does this, if the client is vanilla, then it will send a fake itemID or blockID, otherwise if the client is modded it will send the real itemId or BlockID. There are a lot of thing that extend vanilla like setting the distance view of a player from the server side.

    Icyene, take a look at this: http://forums.bukkit.org/threads/wip-rocky-future-mp-modding.105885/
     
  10. Offline

    md_5

    You aren't taking the speed of sort() into the time. I could almost bet that is slower than a standard if statement.
     
  11. Offline

    Icyene

    I was. In a truly random set of data, sort() slows it down. But MC isn't truly random: 50%-ish of blocks are air, 20% stone etc, so the sort actually pays off.
     
  12. Offline

    Shiny Quagsire

    Has anyone tested this with an unknown ID? And if we set the name or data of one of these ID's to something else, could we use a standard Bukkit event to place our custom block's ID as well? Or is the itemstack in our hand simply client side and we don't even need to use any hooks?

    I'll see if I can attempt this later today. It might prove interesting.
     
  13. Offline

    Cirno

    I don't think you can set an item to an unknown ID, due to the fact that the client also keeps a copy of the Item class, which contains all the items for the game.
     
  14. Offline

    MTN

    I would love to see this work with the sub ids of blocks. Because you can set the data value/subid of a block, e.g. with worldedit and if I use McPatcher or Optifine (which a lot of people do) I can set a new texture for that specific sub id for the block, so wood:8 could be a new wood color.

    What I would love to achieve (or you can) would be that Minecraft can handle this blocks, because if I break a block with that "new" sub id I get the main textured block back (sub id =0) and it looses the name. What I would love to see is that I can destroy these blocks and get a drop with the right sub id and maybe even name (set e.g. with an anvil, but I don't think the metadata can be saved in the world file).
     
  15. Offline

    xemnes


    you can use ctm to texture blocks with metadata, we use it on our server:

    [​IMG]
    [​IMG]

    but when it comes to placing them, it will just place the block with data value 0, except blocks like stone bricks (id 98) because they already have metadata ans therefore you can place them, although stairs are an exception as their metadata depends on the direction of placement to the player. when it comes to placing the other blocks, we must use a paintbrush from toolbelt. it would be awesome to place these blocks but i dont know if the client or the server handles this.
     
  16. Offline

    MTN

    That's what I said:
    ;)
    My current state is that the item in hand does not seem to be able to use sub ids.

    I think I will create a thread for that... :D
     
  17. Offline

    xemnes

    it was more of a backup of your statement but meh lol. i did a little research and i think the item held in the inventory may be client sided
     
  18. Offline

    ryan8843

    This + Server resource packs :)

    Would be nice.
     
  19. Offline

    Cirno

    Well, 2 things (not trying to be rude or anything):
    1: I don't think you understand how this works; it works by replacing blocks in-memory. While it may be a custom block, the server still sends data that it is just a normal vanilla block. All this does is allow us to customize block behavior. In no way does this add new blocks, so server resource packs are effectively useless. (Or maybe it is? One can try to override the getName() and a() methods under Block.java and try swapping in their own names. I don't exactly know how resource packs work.)

    2: Nice necro :p
     
    Garris0n and bobacadodl like this.
  20. Offline

    Garris0n

    You can do it with sounds, but I don't think it works with textures. Perhaps it does.
     
Thread Status:
Not open for further replies.

Share This Page