Blueprint format/API?

    • English

    We've posted a status update with some first screenshots of the new terrain generation. There is also a new update available for the Java version!

    • Blueprint format/API?

      Hello. My question is regarding the blueprint format/API. Is there a reference someone can point me to?

      There was a post last year

      red51 wrote:

      Well, unfortunately you can't edit the file directly by opening it with a texteditor for example. The blueprint files contain compressed bytes, but basically there is no magic in converting it. You just have to decompress the file, and then read the single bytes. If desired, I can give further information about how to convert the bytes into actual construction elements :)

      that seems to be open unless I missed a response somewhere else. I was so glad when I found the post but then I couldn't find the final answer..

      Any help is greatly appreciated. Thank you --
      • Why is someone interested in changing a blueprint format?
      • If someone would change my house into another model by changing a few bytes I would not appreciate that very much.
      • If you would change something like that why with blueprints?
      And why opening a blueprint file to change things and not build a new model?

      Or trying to put parts together into half data size? A program with such a feature would be very much appreciated. ;)
    • Deirdre wrote:


      • Why is someone interested in changing a blueprint format?
      • If someone would change my house into another model by changing a few bytes I would not appreciate that very much.
      • If you would change something like that why with blueprints?
      And why opening a blueprint file to change things and not build a new model?

      Or trying to put parts together into half data size? A program with such a feature would be very much appreciated. ;)
      1) Say I build a house and I want to have multiple copies of the same house but with different floor textures, roof textures etc. so instead of building the same house again I would go in the blueprint and change the things that I want to change. Maybe not for a simple house but for something more complicated that takes a lot of time to rebuild I would prefer to have that option.

      2) I understand and I would be annoyed too, but by uploading a blueprint on the web it technically becomes public property, there is no copyright law that covers items created in games as far as I am aware of in most countries in Europe. I would be annoyed too if someone changed a bit my blueprint and passed it on as their own but they can do that eitherway by downloading it and changing it in game (the byte changing process would make it easier yes I agree with you on that). It all comes down to the other person's character. Further to that when I upload a blueprint here I hope that someone will take it and either use it as it is or make some changes to personalise it and then use it so long as they don't say they made it from scratch.

      3) I don't have a good answer for that I could as easily blueprint the house once then make the changes and blueprint it again so that I have the two versions as two separate blueprints to place.

      Eitherway Red said he was willing to provide us with a way to read the bytes in blueprints so I personally would like to know how to do that.
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals

      The post was edited 1 time, last by Minotorious ().

    • @Minotorious I totally agree with your arguments. There is no copyright, thats true, and it's needless to say not to change other buildings and to present them as their own. But I'm trying to understand why things are wished, if they are really needful, but mostly why people want it. I like to discuss, I admit it. ^^ It's my favorite game and I'm very interested in other people's imagination or thoughts how they see things which I look at in contrast to them.
      I often tried to change buildings, to separate them from others but to keep the same style .
      It doesn't work. Better to build a new one, costs less time, than to change the old one.
      There are some thoughts we could repaint our buildings in the very far future. But nethertheless I'm still interested in to know why to change blueprint's bytes and so on. :D
    • I too am open for discussion in every topic and I will say it as well that RW is one of my favourite games at the moment. I will give an example where I would like to change the texture for a functional reason rather than an aesthetic one.

      I want to build something that I want to be made completely out of black plaster planks/beams, when I try to position one black plaster element on the other elements I cannot really see where I am placing it because they are all fully black (I have tried and even with the debug light on it is really hard to see them). In this case I would like to build my construction out of some other texture that I can clearly see the features of and position things easier and then go to the .blueprint file and change the texture to the black plaster one to obtain the result I wanted. This way I can do it faster than tying to position one black element on the other black elements and spend hours misplacing/removing and repositioning them.

      Back to the aesthetic reasons:

      I don't know if you have seen it but I recently posted a blueprint of a beer glass bar, it is not the most complicated construction I have created but I would like to have a copy of it in green and black plaster textures and rebuilding the whole thing would take me a few hours. On the other hand writing a short python or bash script that would change the texture (once I know how to decode the bytes in the .blueprint file) would take me a few minutes. It is just a matter of my time being spent creating new things rather than recreating old ones that I decided I wanted to change a few textures in.

      At least this is the way I see it, if I have created the thing once why not be able to reproduce similar but not same copies of it. If this can be achieved without Red or any other member of the developing team spending extra time or effort I don't see why not have the feature and whoever wants it they can use it.

      Another thing I just though of is if I download a blueprint from this forum and I don't like one texture the owner has chosen for some part of it and I don't know exactly how he/she placed the specific construction element at that position it is much safer to go find the element in the .blueprint file and change it rather than knock it out and try to replace it by myself.
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals
    • Basically the first step would be to read the bytes of the blueprint file and decompress it (the game uses GZIP for compression). Once you have the decompressed byte buffer/array, you can start reading the single bytes. This is the structure of every blueprint (I hope I didn't miss anything - if you have any questions, don't hesitate to ask):


      BytesInfo
      1blueprint version
      2blueprint size x
      2blueprint size y
      2blueprint size z
      8creation date (timestamp, amount of milliseconds passed since 1st of January 1970)
      4name length (String bytes)
      xxblueprint name (byte length see previous 4 bytes)
      4author name length (String bytes)
      xxauthor name (byte length see previous 4 bytes)
      4world name length (String bytes)
      xxworld name (byte length see previous 4 bytes)
      4terrain data length
      xxterrain data (see below)
      4block data length
      xxblock data (see below)
      4object data length
      xxobject data (see below)
      4construction data length
      xxconstruction data (see below)
      4vegetation data length
      xxvegetation data (N/A)
      4preview image data length
      xxpreview image data



      Compression information

      The blueprint data is compressed using GZIP. Java provides a class "GZIPInputStream" for decompression (and GZIPOutputStream for compression). Java example for decompression:

      Java Source Code

      1. public static byte[] decompress(byte[] input, int length) throws IOException{
      2. try(ByteArrayInputStream in = new ByteArrayInputStream(input); ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPInputStream gzip = new GZIPInputStream(in)){
      3. //create a temp buffer/array to read the data from the stream.
      4. //length describes the length of the temp array (e.g. 2048)
      5. byte[] tmpBuffer = new byte[length];
      6. //once the end of stream has been reached, the read() method returns -1,
      7. //so while the number of read bytes is >= 0, we continue to read to our
      8. //temp buffer/array
      9. int n;
      10. while((n = gzip.read(tmpBuffer)) >= 0){
      11. //write the content of the temp buffer/array to the output stream
      12. out.write(tmpBuffer, 0, n);
      13. }
      14. //store the content of the output stream in a new byte array
      15. return out.toByteArray();
      16. }
      17. }
      Display All

      Block data information

      Block arrays are short arrays (i.e. every index consists of 2 bytes). Block arrays are 3-dimensional arrays (blueprint size x * size y * size z) which are flattened (i.e. it is 1-dimensional). To access a particular index, you have to calculate it (x + y*sizex + z*sizex*sizez), e.g. instead of blocks[x][y][z] (which would be the regular way of accessing a 3d array) you have to access it like blocks[x + y * sizey + z * sizex * sizez)].
      Java way to read the blocks:

      Java Source Code

      1. //assumed the blueprint bytes are stored in a
      2. //ByteBuffer called "buffer"
      3. //get the block data length (4 bytes == int)
      4. int blen = buffer.getInt();
      5. byte[] blockdata = new byte[blen];
      6. //fill the blockdata array with buffer data
      7. buffer.get(blockdata );
      8. //create a new short array (to hold the actual block data)
      9. short[] blocks = new short[blockdata.length / 2];
      10. //easiest way to fill the short array is to use a ByteBuffer
      11. //it would be faster if you read the single bytes and convert
      12. //them to shorts (big-endian), but this way is by far more convenient
      13. ByteBuffer.wrap(blockdata).asShortBuffer().get(blocks);
      Display All

      Terrain data information

      Terrain data is stored as byte array, i.e. a particular byte represents the actual terrain id. Similar to block arrays, the terrain array is flattened, so you have to access it in the same way (see above).


      Object data information

      Objects (furniture, doors etc) are represented by a special object which holds information about the typeid (short), the variation (byte), position x y and z (float) and rotation x y z (short). The first 4 bytes in the encoded blueprint bytes hold information about the actual amount of objects in this blueprint. Java way to read the objects:

      Java Source Code

      1. //assumed the blueprint bytes are stored in a
      2. //ByteBuffer called "buffer"
      3. //get the total amount of bytes (4 bytes == int)
      4. int olen = buffer.getInt();
      5. byte[] objectdata = new byte[olen];
      6. //fill the object byte array
      7. buffer.get(objectdata);
      8. //easiest way is to create a new ByteBuffer, although
      9. //it would be faster to work with the blueprint buffer
      10. //directly. However, we will take the easiest way here:
      11. ByteBuffer objects = ByteBuffer.wrap(objectdata);
      12. //get the amount of objects (4 bytes == int)
      13. int amount = objects.getInt();
      14. //create all objects. It's recommendable to create a
      15. //separate class to hold the particular object information.
      16. //Maybe create a new ArrayList or something like that to
      17. //store the objects
      18. ArrayList<BlueprintObject> list = new ArrayList<>(amount);
      19. for(int i = 0; i < amount; i++){
      20. BlueprintObject obj = new BlueprintObject();
      21. obj.typeid = objects.getShort(); //short (2 bytes)
      22. obj.variation = objects.get(); //1 byte
      23. obj.posx = objects.getFloat(); //float (4 bytes)
      24. obj.posy = objects.getFloat();
      25. obj.posz = objects.getFloat();
      26. obj.rotx = objects.getShort(); //short (2 bytes)
      27. obj.roty = objects.getShort();
      28. obj.rotz = objects.getShort();
      29. list.add(obj);
      30. }
      31. //////////////////////////////////////////
      32. //our individual object class to hold blueprint objects:
      33. public class BlueprintObject{
      34. public short typeid;
      35. public byte variation;
      36. public float posx;
      37. public float posy;
      38. public float posz;
      39. public short rotx;
      40. public short roty;
      41. public short rotz;
      42. }
      Display All

      Construction data information

      Construction data is very much like the object data, only the information per construction element is different. Every construction element holds information about the typeid (short), the texture (int), position x y z (float), rotation x y z (short), size x y z (short), horizontal repetitions (byte), vertical repetitions (byte), gap (byte). Java way to get the construction elements (only rough information, since it's mostly the same as for object elements [see above]):

      Java Source Code

      1. //assumed the blueprint bytes are stored in a
      2. //ByteBuffer called "buffer"
      3. //get total amount of bytes
      4. int clen = buffer.getInt();
      5. byte[] constructiondata = new byte[clen];
      6. //fill byte array
      7. buffer.get(constructiondata);
      8. //easiest way is to create a new ByteBuffer
      9. ByteBuffer constructions = ByteBuffer.wrap(constructiondata);
      10. //get the amount of construction elements (4 bytes == int)
      11. int amount = constructions.getInt();
      12. //create all constructions. It's recommendable to create a
      13. //separate class to hold the construction information.
      14. ArrayList<BlueprintConstruction> list = new ArrayList<>(amount);
      15. for(int i = 0; i < amount; i++){
      16. BlueprintConstruction con = new BlueprintConstruction();
      17. con.typeid = constructions.getShort(); //short (2 bytes)
      18. con.texture = constructions.getInt(); //int (4 bytes)
      19. con.posx = constructions.getFloat(); //float (4 bytes)
      20. con.posy = constructions.getFloat();
      21. con.posz = constructions.getFloat();
      22. con.rotx = constructions.getShort(); //short (2 bytes)
      23. con.roty = constructions.getShort();
      24. con.rotz = constructions.getShort();
      25. con.sizex = constructions.getShort(); //short (2 bytes)
      26. con.sizey = constructions.getShort();
      27. con.sizez = constructions.getShort();
      28. con.repetitionsh = constructions.get(); //1 byte
      29. con.repetitionsv = constructions.get(); //1 byte
      30. con.gap = constructions.get(); //1 byte
      31. list.add(con);
      32. }
      33. //////////////////////////////////////////
      34. //our individual construction class to hold blueprint
      35. //construction elements:
      36. public class BlueprintConstruction{
      37. public short typeid;
      38. public int texture;
      39. public float posx;
      40. public float posy;
      41. public float posz;
      42. public short rotx;
      43. public short roty;
      44. public short rotz;
      45. public short sizex;
      46. public short sizey;
      47. public short sizez;
      48. public byte repetitionsh;
      49. public byte repetitionsv;
      50. public byte gap;
      51. }
      Display All

      Additional information about object elements and construction elements

      To convert the rotation to a world rotation or the size (of construction elements) to the world size, you have to multiply the short values with a conversion factor. For rotations, it is currently 0.025, for the size, it is 0.01. Example:

      Java Source Code

      1. short rotationx = ...;
      2. short sizex = ...;
      3. //convert to world rotation (in degree)
      4. float worldrotation = rotationx * 0.025f;
      5. //convert to world size (world units)
      6. float worldsize = sizex * 0.01f;

      The post was edited 2 times, last by red51: Updated for new blueprint format (including terrain data now) ().

    • ok @red51 thank you very much for all this information. A few questions now again if you don't mind :)

      1) The byte format of the decompressed .blueprint files is hexadecimal correct?

      2) If the answer to the above was yes then I am getting different texture numbers for construction elements (beams, planks, logs) in the files than the numbers in the game. The block texture numbers on the other hand are correct in the decompressed files. I will post an example test blueprint I created to explain and maybe you can help me out if I am calculating something wrong. So this blueprint is of one plank with texture number 21 (i.e. the simple stone texture). Just in case it matters I decompressed the .blueprint file using the Ubuntu 16.04 shell by "gunzip < name.blueprint > out.txt" then I am reading it with the HxD hex editor. I have omitted the preview image bytes

      Source Code

      1. 03 00 01 00 01 00 01 00 00 01 5B 5E 89 9C 2B 00 00 00 0C 77 6F 6F 64 70 6C 61 6E 6B 20 32 31 00 00 00 0B 4D 69 6E 6F 74 6F 72 69 6F 75 73 00 00 00 0E 41 72 74 69 73 61 6E 73 20 52 65 61 6C 6D FF FF FF FF FF FF FF FF 00 00 00 25 00 00 00 01 00 02 00 00 00 00 3F 00 00 00 3F 00 00 00 3F 00 00 00 00 00 00 00 00 00 00 64 00 64 00 05 00 00 00
      According to the information you gave above I should translate this into:

      Source Code

      1. 03 - blueprint version
      2. 00 01 - sizex
      3. 00 01 - sizey
      4. 00 01 - sizez
      5. 00 00 01 5B 5E 89 9C 2B - timestamp
      6. 00 00 00 0C - blueprint name length
      7. 77 6F 6F 64 70 6C 61 6E 6B 20 32 31 - blueprint name (I checked this corresponds to "woodplank 21" the name I gave the blueprint)
      8. 00 00 00 0B - player name length
      9. 4D 69 6E 6F 74 6F 72 69 6F 75 73 - player name (again checked this and it corresponds to "Minotorious")
      10. 00 00 00 0E - world name length
      11. 41 72 74 69 73 61 6E 73 20 52 65 61 6C 6D - world name (this corresponds correctly to "Artisan's Realm")
      12. FF FF FF FF - block data length (I assume only "FF" bytes means no blocks since my blueprint had no blocks in it)
      13. FF FF FF FF - object data length (same as above)
      14. 00 00 00 25 - construction data length
      15. 00 00 00 01 - number of elements (1 plank so correct)
      16. 00 02 - typeid
      17. 00 00 00 00 - texture (why are there only 0s here? shouldn't the last one be 15 in hex i.e. 21 in dec?)
      18. 3F 00 00 00 - positionx
      19. 3F 00 00 00 - positiony
      20. 3F 00 00 00 - positionz
      21. 00 00 - rotationx
      22. 00 00 - rotationy
      23. 00 00 - rotationz
      24. 00 64 - sizex
      25. 00 64 - sizey
      26. 00 05 - sizez
      27. 00 - repetitionsh
      28. 00 - repetitionsv
      29. 00 - gap
      Display All
      and here is the example of a blueprint of 1 block with texture 21.

      Source Code

      1. 03 - blueprint version
      2. 00 01 - sizex
      3. 00 01 - sizey
      4. 00 01 - sizez
      5. 00 00 01 5B 5E 5F BE 39 - timestamp
      6. 00 00 00 08 - blueprint name length
      7. 62 6C 6F 63 6B 20 32 31 - blueprint name (I checked this corresponds to "block 21" the name I gave the blueprint)
      8. 00 00 00 0B - player name length
      9. 4D 69 6E 6F 74 6F 72 69 6F 75 73 - player name (again checked this and it corresponds to "Minotorious")
      10. 00 00 00 0E - world name length
      11. 41 72 74 69 73 61 6E 73 20 52 65 61 6C 6D - world name (this corresponds correctly to "Artisan's Realm")
      12. 00 00 00 02 - block data length
      13. 00 - block position (as you said reduced to 1D)
      14. 15 - block texture (corresponds correctly to dec 21 i.e. the in game number)
      15. FF FF FF FF - object data length
      16. FF FF FF FF - construction data length
      Display All
      3) What is the format of the 8 timestamp bytes? I couldn't find a way to translate them to human date format no matter how I tried to position dd/mm/yyyy or yyyy/mm/dd. ?(
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals

      The post was edited 5 times, last by Minotorious ().

    • I answered my 2nd question by myself by trial and error, so it seems that in the .blueprint files the construction element textures have a 21 number difference to the numbers in the game. i.e. stone 21 is 0, green plaster 200 is 179 and so on. Thanks again @red51 for the information I can now enjoy my yellow beer that turned green with only a few replacements :D

      ------->
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals

      The post was edited 1 time, last by Minotorious ().

    • And what about the other noobs who want to change the colors of their blueprints? I want to change my rocking chair (blueprint in the forum) into a white modern one. If the process is so uncomplicated as it seems, this would be very helpful. I've never imagined that it works so easily as on the yellow to green bar. Is it possible without any further knowledge and not really willing to involve lots of time in it?

      Btw a tutorial or guide would be great.
    • @Deirdre I will start writing a standalone program to edit .blueprint files. I cannot promise it will be coded in java since I have no experience with it (it will either by python or c++, I haven't decided yet) but I will try to make it as simple as possible for everyone.

      For now my only advice would be to look at the file and try to understand it with red's instructions, took me a few hours with simple test case blueprints (like 1 block, or 1 plank, or a series of a few blocks) but after I understood the file structure it took me a couple of minutes to change the textures. When you do it by hand you just need to be careful not to change any of the position or rotation bytes by accident.
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals
    • Minotorious wrote:

      3) What is the format of the 8 timestamp bytes? I couldn't find a way to translate them to human date format no matter how I tried to position dd/mm/yyyy or yyyy/mm/dd.
      Sorry, I forgot to mention that this is a special type of timestamp - the amount of milliseconds passed since 1st of January 1970 (so if you divide it by 1000 you can treat it as a regular unix timestamp). The byte order is big endian, as always.

      Minotorious wrote:

      I answered my 2nd question by myself by trial and error, so it seems that in the .blueprint files the construction element textures have a 21 number difference to the numbers in the game
      That's great! :) And yeah, block- and construction textures start at 21 (to prevent any collisions between block and terrain textures)

      Minotorious wrote:

      @Deirdre I will start writing a standalone program to edit .blueprint files
      This sounds awesome :thumbup:
    • @red51 construction textures start at 21 same as making texture packs. Is it possible to get a bit more explanation in German too, so that other users could profit from it.

      @Minotorious Maybe it would takes more time to get involved in Java than I would like to spend on it. I learned more about static on roofs and buildings since I'm playing RW and was a bit trying on Lua but I'm not really interested in to learn Java , too. It would be very nice if you could create a standalone program. :D
    • Minotorious wrote:

      @Deirdre I will start writing a standalone program to edit .blueprint files. I cannot promise it will be coded in java since I have no experience with it (it will either by python or c++, I haven't decided yet) but I will try to make it as simple as possible for everyone.

      For now my only advice would be to look at the file and try to understand it with red's instructions, took me a few hours with simple test case blueprints (like 1 block, or 1 plank, or a series of a few blocks) but after I understood the file structure it took me a couple of minutes to change the textures. When you do it by hand you just need to be careful not to change any of the position or rotation bytes by accident.
      I am also a non-native Java user, so will be using Python. Once I have something to share I will put up link to GitHub page. Thank you very much @red51 this is more than enough to get started :thumbup:
    • Thank you for sharing this! :thumbsup: :thumbsup: But this part:

      red51 wrote:

      //easiest way to fill the short array is to use a ByteBuffer
      //it would be faster if you read the single bytes and convert
      //them to shorts (big-endian), but this way is by far more convenient
      ByteBuffer.wrap(blockdata).asShortBuffer().get(blocks);
      What is the alternative faster method?
      "I wish I had a dollar for every time I spent a dollar, because then, I'd have all my money back" :P
    • poptart1296 wrote:

      Thank you for sharing this! :thumbsup: :thumbsup: But this part:

      red51 wrote:

      //easiest way to fill the short array is to use a ByteBuffer
      //it would be faster if you read the single bytes and convert
      //them to shorts (big-endian), but this way is by far more convenient
      ByteBuffer.wrap(blockdata).asShortBuffer().get(blocks);
      What is the alternative faster method?
      I haven't had a chance to dive in yet, but I'd venture to guess we're talking ms at the most here. For me, and likely anyone else diving in, they will go with the easy route and find that it's more than fast enough to give any sort of optimization a second thought..

      I say this in all seriousness, and would not take the time just to "troll" or to start some argument, just speaking from personal experience (and personal opinion.. so take it for what you will)

      If it turns out I'm completely wrong, then I will promptly update this post, admit I spoke too soon, and jot down a lesson learned ^^

      -- Separate topic for the curious --
      My goal (I don't think I've stated above) is to use image processing/machine learning experience to tackle the task of reversing a "real photo" into RW primatives, which is why I needed to understand the atomic elements of a blueprint (thank you again for the detailed explanation and code, @red51!)

      The idea came when I noticed a lot of friends using internet images as their reference point for RW builds (with a lot of time involved for very detailed buildings) and thought, "wouldn't it be cool if a program could do the same... in seconds or minutes (image processing can be resource intensive both GPU and CPU) not weeks or months". Anyways, thought I'd share my initial project goal while I was posting :saint:
    • just for the record what I did in java was use a 2D byte array with two columns and rows as many as the blocks found in the blueprint. Then I parsed in the first column the position of each block and the second column the texture of each block respectively. This way helped me draw a fast and easy distinction between the position element of the blocks (which I don't care about) and the texture element which is what I want to change in my program.
      And code-wise:

      Source Code

      1. byte[][] BPblock = new byte[BPblockl/2][2];
      2. for (int i=0;i<BPblockl/2;i++){
      3. BPblock[i][0] = BPbuffer.get();
      4. BPblock[i][1] = BPbuffer.get();
      5. }
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals
    • poptart1296 wrote:

      What is the alternative faster method?
      You could read from the byte buffer directly and use bit shifting to convert the bytes to short values. This is the fastest method, however, using a ByteBuffer instead is more convenient ;)

      Java Source Code

      1. //get the block data length (4 bytes == int)
      2. int blen = buffer.getInt();
      3. //create a new short array with half of the size (1 short == 2 bytes)
      4. short[] blocks = new short[blen / 2];
      5. //now convert all bytes to short values by shifting the bits (big endian)
      6. for(int i = 0; i < blocks.length; i++){
      7. blocks[i] = (short)((buffer.get() << 8) | (buffer.get() & 0xff));
      8. }

      Steve wrote:

      I haven't had a chance to dive in yet, but I'd venture to guess we're talking ms at the most here.
      That's true. I think we're even talking about ns here (or more precisely, it isn't possible to measure the difference at all). It really doesn't matter, especially if you're not using a performance-critical application (e.g. if you have to execute this code 10000 times per second, it makes sense to use the faster method) ^^
    • red51 wrote:

      poptart1296 wrote:

      What is the alternative faster method?
      You could read from the byte buffer directly and use bit shifting to convert the bytes to short values. This is the fastest method, however, using a ByteBuffer instead is more convenient ;)

      Java Source Code

      1. //get the block data length (4 bytes == int)
      2. int blen = buffer.getInt();
      3. //create a new short array with half of the size (1 short == 2 bytes)
      4. short[] blocks = new short[blen / 2];
      5. //now convert all bytes to short values by shifting the bits (big endian)
      6. for(int i = 0; i < blocks.length; i++){
      7. blocks[i] = (short)((buffer.get() << 8) | (buffer.get() & 0xff));
      8. }

      Steve wrote:

      I haven't had a chance to dive in yet, but I'd venture to guess we're talking ms at the most here.
      That's true. I think we're even talking about ns here (or more precisely, it isn't possible to measure the difference at all). It really doesn't matter, especially if you're not using a performance-critical application (e.g. if you have to execute this code 10000 times per second, it makes sense to use the faster method) ^^
      If anyone is up for the challenge, I'm sure you could shave off a few n.s. here and there with direct x86 assembly... maybe run on bare metal? :huh:

      You made me think on the kilohertz building output... if the world is infinite you have the room to lay the material but could you? *

      * Side note -- I took the Pepsi challenge from one of your recent change logs on 400?x fly mode, using the native system JDK (Steam java is bogus on Linux, FYI.. I know the Ubuntu 2001 edition er 12.04 runtime and all...) and a few JVM tweaks for GC management to see if I could get screen tear or stutter... Arch Linux 64GB/1TB Nvme on GTX 1070 held up! No bottle necks I could see. RW kept up no problem. :thumbup:

      I take back all the bad things I *may* have said in previous years about Java (friendly Python v. Java, right?! ^^ )
    • red51 wrote:

      Java Source Code

      1. //get the block data length (4 bytes == int)
      2. int blen = buffer.getInt();
      3. //create a new short array with half of the size (1 short == 2 bytes)
      4. short[] blocks = new short[blen / 2];
      5. //now convert all bytes to short values by shifting the bits (big endian)
      6. for(int i = 0; i < blocks.length; i++){
      7. blocks[i] = (short)((buffer.get() << 8) | (buffer.get() & 0xff));
      8. }
      wait wouldn't it be wiser to use the inbuilt method buffer.getShort() (i.e. blocks = buffer.getShort() ) instead of reinventing the wheel with bit shifting? ?(

      Also a different question now:
      I created two test cases one with a single ramp texture 21 and one with a single stair1 again texture 21 to test the block data structure.The values I get from the blueprint file are:

      blocktypehexdec
      ramp26C19921
      stair10F513921


      seeing this result I understand that 21 refers to the texture, while the first two numbers refer to the position? If that is the case how does the game know if the block is a square block, a ramp or a stair1, a stair2, or a stair3 etc.?
      Admin on Artisan's Realm
      Rising World Projects:
      Blueprint Texture Editor
      MailingSystem
      ServerTools
      Portals