Why do we still use 3 bytes per block?

    Joined
    Mar 10, 2015
    Messages
    122
    Reaction score
    50
    • Community Content - Bronze 1
    • Purchased!
    • Legacy Citizen 5
    Just a quick note: I have no idea if this properly belongs in general discussion (for answers to the title question), or suggestions (since I make a case for using 4 bytes instead). Please move if necessary.

    I keep hearing people talk about how we're running out of block IDs, that we need to conserve them for later features, so on and so forth. Everyone talks about this:


    Blue is block ID bits: 11 bits, 2048 possible values.
    Red is HP bits: 8 bits, 256 possible values.
    Green is Activation bits: 1 bit, 2 possible values.
    Yellow is orientation bits: 4 bits, 16 possible values.
    I haven't been here very long, and I've heard a lot about this system, so I'm going to assume everyone else has too. I decided to write this when I saw this suggestion thread (abridged):

    Ok so my suggestion is this... (not sure if I can explain it well)
    Being able to change the color of a single face of a hull block.

    The reason I would like this feature is more or less because with smaller ships you have to choose between having the same interior/exterior color -or- making your walls/hull 2-3 blocks thick, which at the small scale can be... odd? Basically, I think this is a way to get more variation with fewer blocks, as walls/hull etc. would only need to be 1 block thick, while still having 2 different colored rooms/etc. This would also allow more room in general for systems, etc. etc.
    And, more specifically, this reply to that suggestion:

    Idea: good
    Would it work well with how the game currently works internally? no
    As hull is frequently used, storing which face has which color in the same way as display blocks store their text is not an option, making a block for each combination of hull-colors per face would also take up WAY too many IDs.
    Without extending the 3 byte per block limit, I see no efficient way of implementing this, sadly.
    This is true. There's no way to fit this into the current system. Actually, realistically, this won't fit into any compact system - we have 10 colors, which is 5 bits minimum x 6 faces on a cube = 30 bits, which is almost an entire extra 4 byte int. If we can part with two of our colors (good luck with that!) we could drop down to 24 bits; then we'd only be doubling the file size of every ship ever. So, bummer.

    But this is only one recent example of IDs getting in the way - here's two pages of a google search:

    http://starmadedock.net/threads/longer-building-blocks.5422/
    http://starmadedock.net/threads/furnature-blocks.5551/
    http://starmadedock.net/threads/new-block-decor-concepts.6254/
    http://starmadedock.net/threads/alpha-numeric-blocks.6267/
    http://starmadedock.net/threads/multislots-extrapolated-simpler-crafting-and-fewer-ids.6481/
    http://starmadedock.net/threads/new-decoration-block-idea-colored-linear-particle-emitters.5794/
    http://starmadedock.net/threads/why-are-people-complaining-about-block-ids-running-out.3504/
    http://starmadedock.net/threads/wedges-that-fuse-collide-fit-together.5654/
    http://starmadedock.net/threads/half-block.5326/

    Which kind of begs the title question:

    Why do we still use 3 bytes per block?

    The first time I heard about this system, my first thought was - why 3 bytes? From a computer science standpoint, 3 bytes is kind of a random number. Pretty much everyone uses powers of two. Back in the 70s, when 256k RAM / 70MB disk was high tech, weird sizes were a lot more common just because no one could afford to waste space. Since then, we've more or less settled on powers of two for everything - modern C compilers will intentionally make your data take up more space if it'll be faster to access - because we now live in an age where space is cheap and processing power is starting to plateau.

    In the interest of computer science, I am now going to turn this question around to "Why don't we use 4 bytes?", and bring up all the arguments I can think of.

    1. Memory
    If I build a 1 million block ship, at 3 bytes/block, that's 3 million bytes (~2.86MB). At 4 bytes/block, that's 4 million bytes (~3.81MB) - a 33% increase. Obviously, taking up less RAM is superior to taking up more RAM.

    My best counter to this is, admittedly, that a 33% increase in memory is not actually that much. If you allocate 2GB of memory to starmade, it can handle 357,913,941 3 byte blocks, or 268,435,456 4 byte blocks. 2GB is on the low end of what most people are bringing to the table; my non-gaming laptop is two years old and it has 6GB RAM. My old non-gaming laptop, now 6+ years old, had 4GB.

    2. Disk space
    Intuitively, you might think that a 33% increase in RAM usage would translate into a 33% increase in disk space usage, but you'd be wrong. Because of how file compression works, a 3 byte block .sment and a 4 byte block .sment should end up around the same size (if you've got a good compressor), due to the fact that in practice, they contain the same information. As time goes on, however, it's unlikely to stay that way - although 4 byte blocks would probably never actually hit the 33% extra space mark. I'd peg it at 20% tops by the time we hit 1.0.

    3. Bandwidth
    This is the real kicker.

    A 33% RAM increase doesn't translate to a 33% disk space increase, but it does translate to a 33% bandwidth increase. Bandwidth isn't free, and high pings are bad for everyone.

    Fortunately, file compression works here too. Webservers and even web browsers have been compressing data before sending it for a while, and it works pretty well. File compression is expensive, but i/o is generally more expensive - webservers compress stuff because there's usually a good chance it'll actually speed the server up, even though it's doing more work.

    Why we should use 4 bytes
    Now let's look at direct benefits.

    1. Data alignment
    As I said above, modern C compilers will intentionally make your data take up more space if it'll be faster to access. They do this to avoid field or data misalignment, which is what happens when the CPU tries to access memory at an address that isn't a multiple of 4 (usually, nowadays). Generally, when this happens, the CPU has to do all the work of a properly aligned access twice.

    You can't have an array of 3 byte values without having field misalignment problems:



    Half of all blocks overlap a word boundary. Additionally, of the two that do not overlap a word boundary, only one is easily addressable - the other one (in our case, the green one on the far right) is likely addressed by its base, rather than by the base of the word that contains it. This comes out to a best-case 50% increase in lag time, worst-case 75%. Four byte blocks would all be aligned (the JVM is even nice enough to do it for you), and this wouldn't be a problem.

    This might sound like a stupid or nitpicky problem, but memory access time is huge in computer science - so huge that we've invented like 12 different kinds of it in an effort to milk every nanosecond. Numbers vary from system to system, and cache mechanics are involved, but data alignment is pretty much the only area in programming where moving around bigger chunks of memory is actually pretty likely to be easier.

    2. All of the block IDs
    And of course, who doesn't want to be swimming in blocks?

    Schema can pick whatever bit distribution he wants, but here's an example of what 4 bytes has to offer:



    16 byte block ID: 2^16 = 65,536 IDs
    8 byte HP: 2^8 = 256 max HP
    8 byte orientation: 2^7 = 128 possible orientations + sign bit for activation

    Conclusion
    Imagine a universe filled with wedges. Wedges as far as the eye can see. A wedge for every block, and a block for every wedge. Corners, heptas, tetras. Hell, we could have inverse corners - for everything - and still have tens of thousands of ids to spare. If you added 600 unique furniture blocks, you would be using a paltry 1% of the available ID space. How about 600 unique furniture blocks - in 10 colors each? What if I told you this universe had lower pings, faster load times, and higher FPS?

    Are you sold yet?
     
    Joined
    Nov 20, 2014
    Messages
    24
    Reaction score
    18
    simply put.... yes, so much yes.

    I have wondered this a lot since I played a ton of another voxel based building game where the number of blocks can balloon when you start adding mods. There are quite a few servers running 100+ mods adding 100s of blocks with very little lag. I don't see why this has to be a problem for starmade.

    But after this post I at least understand why I keep hearing "running out of IDs".

    Great post.
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    1. Memory
    If I build a 1 million block ship, at 3 bytes/block, that's 3 million bytes (~2.86MB). At 4 bytes/block, that's 4 million bytes (~3.81MB) - a 33% increase. Obviously, taking up less RAM is superior to taking up more RAM.

    My best counter to this is, admittedly, that a 33% increase in memory is not actually that much. If you allocate 2GB of memory to starmade, it can handle 357,913,941 3 byte blocks, or 268,435,456 4 byte blocks. 2GB is on the low end of what most people are bringing to the table; my non-gaming laptop is two years old and it has 6GB RAM. My old non-gaming laptop, now 6+ years old, had 4GB.

    2. Disk space
    Intuitively, you might think that a 33% increase in RAM usage would translate into a 33% increase in disk space usage, but you'd be wrong. Because of how file compression works, a 3 byte block .sment and a 4 byte block .sment should end up around the same size (if you've got a good compressor), due to the fact that in practice, they contain the same information. As time goes on, however, it's unlikely to stay that way - although 4 byte blocks would probably never actually hit the 33% extra space mark. I'd peg it at 20% tops by the time we hit 1.0.

    3. Bandwidth
    This is the real kicker.

    A 33% RAM increase doesn't translate to a 33% disk space increase, but it does translate to a 33% bandwidth increase. Bandwidth isn't free, and high pings are bad for everyone.

    Fortunately, file compression works here too. Webservers and even web browsers have been compressing data before sending it for a while, and it works pretty well. File compression is expensive, but i/o is generally more expensive - webservers compress stuff because there's usually a good chance it'll actually speed the server up, even though it's doing more work.
    Just stating a neutral fact: empty blocks within a partially filled chunk will eat 3 bytes too. Emptying a chunk does not undo that effect.
    So, block count doesn't matter, number of chunks does.
     
    • Like
    Reactions: Mariux
    Joined
    Jul 20, 2013
    Messages
    603
    Reaction score
    203
    • Legacy Citizen 2
    • Community Content - Bronze 2
    • Purchased!
    Really interesting thread OP. I have only a cursory knowledge of CompSci, but I always find the technical aspects really interesting. If 4 bytes will actually be faster for the game and get rid of one of the worst problems starmade has, I'm all for it.
     
    Joined
    Jul 1, 2013
    Messages
    530
    Reaction score
    348
    • Legacy Citizen 8
    • Community Content - Bronze 1
    I have about as much computer knowledge as a squirrel has understanding of algebra (none) but if there's a limiting factor on game content like number of unique blocks we can use, I wouldn't mind if it vanished.

    However, you mention only RAM memory in your post, not GPU memory. My laptop's video card only has 1gb or something of available memory, and if this change will increase graphics memory usage as well as RAM usage, it could really be a killing blow for me.
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    However, you mention only RAM memory in your post, not GPU memory.
    The ships aren't stored in the VRAM, as such, changing the amount of bytes per block has no effect on the VRAM usage (VRAM is the memory dedicated to the GPU)
     
    Joined
    Feb 15, 2015
    Messages
    158
    Reaction score
    37
    The big question [from a non-computer-logic-type-of-guy (I'm all over verbal logic, however...)] is:
    Can the game, in it's entirety, be "converted" into the 4-byte paradigm easily, or with minimal difficulty? If Schema has to start over from scratch I just don't see it happening. (Shoulda been the literal "starting block" though, if what you say is true -- and I cannot argue.)

    ~
     
    Joined
    Aug 5, 2013
    Messages
    405
    Reaction score
    140
    • Community Content - Bronze 1
    interesting, worth reading, but i am not sure this can be done or not
    I remember someone posted something similar in the suggestion forum before
     

    takethispie

    Titan-class builder
    Joined
    Oct 3, 2012
    Messages
    239
    Reaction score
    103
    • Purchased!
    • Wired for Logic
    • Legacy Citizen 9
    I told you this universe had lower pings, faster load times, and higher FPS?
    you forgot something: ram and memory disk isn't the most important , the thing is:
    if you use 4bytes instead of 3bytes, the calculation on each block will be longer ! bigger data structure mean slower not faster !
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    you forgot something: ram and memory disk isn't the most important , the thing is:
    if you use 4bytes instead of 3bytes, the calculation on each block will be longer ! bigger data structure mean slower not faster !
    Depends, assigning 2 full bytes for blockIDs allows the ID to be stored in a short, which will be faster, as it is a primitive type for the JVM, unlike the 11 bit number we have now.
    As this causes HP and orientation/activation to also be aligned with byte boundaries, handling them will be easier for the JVM too, as they can then be completely stored in byte variables, which, again, are primitive types and should thus be easier to handle for the JVM.
     

    Valiant70

    That crazy cyborg
    Joined
    Oct 27, 2013
    Messages
    2,189
    Reaction score
    1,168
    • Thinking Positive
    • Purchased!
    • Legacy Citizen 4
    Just stating a neutral fact: empty blocks within a partially filled chunk will eat 3 bytes too. Emptying a chunk does not undo that effect.
    So, block count doesn't matter, number of chunks does.
    //Begin Geek-Greek
    If this is correct, it sounds like chunks may not be using a very efficient data structure (probably a straight-up 3D array). This is probably because it's fast to access this way. Unfortunately that leaves a lot of wasted space.

    I wonder if using a HashMap (one of Java's collection structures) to store blocks in a chunk would help. Its size is dynamic so it won't waste nearly as much space. There shouldn't be any particular need to store the blocks in a particular order on the disk. If they're out of order, you'd just see the chunk get populated in more of a "fade-in" manner than like a 3D printer.

    schema I'm still kind of a noob with this stuff, but what do you think? Does this idea have any substance?
    //End of Geek-Greek

    Translation: Schema can probably make this less wasteful.
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    I wonder if using a HashMap (one of Java's collection structures) to store blocks in a chunk would help. Its size is dynamic so it won't waste nearly as much space. There shouldn't be any particular need to store the blocks in a particular order on the disk.
    The structure of smd2 files allows easy random access. Why, I don't know, but probably for a reason, same for the array(which I doubt is 3D, but just a 1D array)
     
    Joined
    Mar 10, 2015
    Messages
    122
    Reaction score
    50
    • Community Content - Bronze 1
    • Purchased!
    • Legacy Citizen 5
    So this blew up, which is cool.

    The big question [from a non-computer-logic-type-of-guy (I'm all over verbal logic, however...)] is:
    Can the game, in it's entirety, be "converted" into the 4-byte paradigm easily, or with minimal difficulty? If Schema has to start over from scratch I just don't see it happening. (Shoulda been the literal "starting block" though, if what you say is true -- and I cannot argue.)
    Converting wouldn't be as hard as you think. You'd have to convert everything, which would be annoying - and probably take a few minutes - but after you did, everything would work pretty much the same.

    Schema would write a "conversion script", which, from what I know of the file format, would just be a short little thing that reads in every 3 byte block and writes it back out as a 4 byte block (and then changes .smd2 to .smd3). The script itself (schema's job) isn't that hard, and then it would be like converting a minecraft world to anvil (if you remember what that was like).

    Just stating a neutral fact: empty blocks within a partially filled chunk will eat 3 bytes too. Emptying a chunk does not undo that effect.
    So, block count doesn't matter, number of chunks does.
    //Begin Geek-Greek
    If this is correct, it sounds like chunks may not be using a very efficient data structure (probably a straight-up 3D array). This is probably because it's fast to access this way. Unfortunately that leaves a lot of wasted space.

    I wonder if using a HashMap (one of Java's collection structures) to store blocks in a chunk would help. Its size is dynamic so it won't waste nearly as much space. There shouldn't be any particular need to store the blocks in a particular order on the disk. If they're out of order, you'd just see the chunk get populated in more of a "fade-in" manner than like a 3D printer.

    schema I'm still kind of a noob with this stuff, but what do you think? Does this idea have any substance?
    //End of Geek-Greek

    Translation: Schema can probably make this less wasteful.
    The short answer is hashtables won't save you. The long answer is it's a trade off between space usage and access time that we'd probably end up on the wrong side of.

    Empty space is a thing, but file compression would deal with this. What file compressors actually do is get rid of redundant information, and empty space is (hopefully) just a big chunk of all 0s. File compressors can get rid of that with really good compression rates. Under the same principle, file compressors are really good at compressing large chunks full of the same system block.
     
    Last edited:
    Joined
    Aug 28, 2013
    Messages
    1,831
    Reaction score
    374
    • Legacy Citizen 2
    • Top Forum Contributor
    • Legacy Citizen
    Hmmm.... how to use 128 orientations.
    6 for a cube
    12 for wedges = 18
    8 for heptas = 26
    8 for tetras = 34
    24 for corners = 58

    6 for half-slabs on a face = 64
    12 for halfs of half-slabs = 76
    8 for half-sized cubes = 84
    6 for wedge panels = 90 //basically take the only sloped face on a wedge and make it double sided.
    3 for rods = 93
    3 for center panels = 96
    24 for reverse corners = 120
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    Hmmm.... how to use 128 orientations.
    6 for a cube
    12 for wedges = 18
    8 for heptas = 26
    8 for tetras = 34
    24 for corners = 58

    6 for half-slabs on a face = 64
    12 for halfs of half-slabs = 76
    8 for half-sized cubes = 84
    6 for wedge panels = 90 //basically take the only sloped face on a wedge and make it double sided.
    3 for rods = 93
    3 for center panels = 96
    24 for reverse corners = 120
    You forgot half-corners, hepta-panels, anti-hepta-panels, hepta-wedges, 2-tetra, anti-2-tetra. :P
     
    Joined
    Aug 28, 2013
    Messages
    1,831
    Reaction score
    374
    • Legacy Citizen 2
    • Top Forum Contributor
    • Legacy Citizen
    You forgot half-corners, hepta-panels, anti-hepta-panels, hepta-wedges, 2-tetra, anti-2-tetra. :p
    I was being serious. Though hepta-panels would bring the total up to 128.(and note that you would only need hepta-panels or tetra-panels as they are the same thing.
    And 2-tetra and reverse-2-tetra would also only take up 8 orientations.
    I'm not even sure what you mean by hepta-wedge and half-corners/wedges ugh.
     
    Joined
    Mar 10, 2015
    Messages
    122
    Reaction score
    50
    • Community Content - Bronze 1
    • Purchased!
    • Legacy Citizen 5
    You can't activate hull, so if you want you can cannibalize the activation bit and double the fun.
     
    • Like
    Reactions: Mariux
    Joined
    Aug 28, 2013
    Messages
    1,831
    Reaction score
    374
    • Legacy Citizen 2
    • Top Forum Contributor
    • Legacy Citizen
    Though I do want full shapes for the doors though. Though some shapes might not work for the doors.
     
    Joined
    Jul 21, 2013
    Messages
    2,932
    Reaction score
    460
    • Hardware Store
    I'm not even sure what you mean by hepta-wedge and half-corners/wedges ugh.
    A hepta-wedge is a hepta, with a wedge removed from it.
    A half-corner is a corner diagonally sliced through(the full square is diagonally sliced through)
    A 2 tetra is NOT an anti-hepta-panel, as unlike in the case of the anti-hepta-panel, the tetras are not in opposing sides of the cube.