Binary

From VbGORE Visual Basic Online RPG Engine

This page is unorganized / messy or does not contain substantial information!
You can clean up this page by editing it. Relevant information may be found at the talk page.

The typically used method of storing and sending data is to do something like this:

Dim BlockedTile As Byte 
Dim MailBox As Byte 
Dim Bank As Byte 
If <TheTileIsBlocked> Then BlockedTile = 1 Else BlockedTile = 0 
If <TheTileIsMailbox> Then MailBox = 1 Else MailBox = 0 
If <TheTileIsABank> Then Bank = 1 Else Bank = 0 
ConBuf.Put_Byte BlockedTile 
ConBuf.Put_Byte MailBox 
ConBuf.Put_Byte Bank

The problem with this is there are 254 numbers that go to waste for every byte you send! Here is where boolean operators come in handy. For this guide, we will use only OR and AND.

A OR B - The result is any 1's in A or B 
A AND B - The result is the 1's in both A and B

In binary, this looks like this:

A = 0010 
B = 0110 
A OR B = 0110 
A AND B = 0010 

A = 1010 
B = 1110 
A OR B = 1110 
A AND B = 1010

Now what do these numbers mean? Well everything in computers is handled by binary. Binary works from reading right-to-left, each number representing a power of 2. Ex:

0000 = 0 
0001 = 2 ^ 0 = 1 
0010 = 2 ^ 1 = 2 
0100 = 2 ^ 2 = 4 
1000 = 2 ^ 3 = 8

That isn't too bad, right? Just combine the numbers to get the resulting number you want. Simple, huh? If you dont understand, though, it's not too important - all we have to know is that those values above are right, not why they are right. As long as you understand that they ARE right, you are good to go!

Now is where the compression comes into play. Lets refer back to our old code up top:

If <TheTileIsBlocked> Then BlockedTile = 1 Else BlockedTile = 0 
If <TheTileIsMailbox> Then MailBox = 1 Else MailBox = 0 
If <TheTileIsABank> Then Bank = 1 Else Bank = 0

Like I said before, we are wasting 254 numbers for each byte since we only use 2 numbers (0 and 1) and a byte is a 8-bit number (2^8 = 256, but 0 is in there too, so it is 0-255 not 1-256). Well using the boolean operator OR above, we can combine these bytes all into one!

Dim ByFlags As Byte 
ByFlags = 0 
If <TheTileIsBlocked> Then ByFlags = ByFlags OR 1 
If <TheTileIsMailbox> Then ByFlags = ByFlags OR 2 
If <TheTileIsABank> Then ByFlags = ByFlags OR 4

Now lets look at what is happening in binary:

ByFlags = 0: Clears all 1's: 0000 0000

...Then ByFlags = ByFlags OR 1: 
Sets the first bit: 0000 0001 

...Then ByFlags = ByFlags OR 2: 
Sets the first bit: 0000 0010 

...Then ByFlags = ByFlags OR 4: 
Sets the first bit: 0000 0100 

...Then ByFlags = ByFlags OR 8: 
Sets the first bit: 0000 1000

As you can see, none of the 1's get in eachother's way - this is because we are using perfect powers of 2 (2^X). Each different combination will result in a different number!

Also you may notice that we can only store 8 flags with the byte. Well if you ever need to store more, then just use a different variable! Byte = 8 bits, Integer = 16 bits, Long = 32 bits.

Now that you know all of that, lets take a look at the once possibly confusing tile-creation packet the server sends to the client when changing a tile, which shows examples of not just storing values that will only be yes or no, but telling ahead of time if there is a value for you to get so you dont have to get a common (like -1 for the light) or unused (like 0 for a graphic layer) value:

Dim ChunkData As Long 
ChunkData = 0 
If .Blocked Or BlockedNorth Then ChunkData = ChunkData Or 1 
If .Blocked Or BlockedEast Then ChunkData = ChunkData Or 2 
If .Blocked Or BlockedSouth Then ChunkData = ChunkData Or 4 
If .Blocked Or BlockedWest Then ChunkData = ChunkData Or 8 
If .Mailbox Then ChunkData = ChunkData Or 16 
If .Graphic(1) > 0 Then ChunkData = ChunkData Or 32 
If .Graphic(2) > 0 Then ChunkData = ChunkData Or 64 
If .Graphic(3) > 0 Then ChunkData = ChunkData Or 128 
If .Graphic(4) > 0 Then ChunkData = ChunkData Or 256 
If .Graphic(5) > 0 Then ChunkData = ChunkData Or 512 
If .Graphic(6) > 0 Then ChunkData = ChunkData Or 1024 
If .Light(1) <> -1 Then ChunkData = ChunkData Or 2048 
If .Light(2) <> -1 Then ChunkData = ChunkData Or 2048 
If .Light(3) <> -1 Then ChunkData = ChunkData Or 2048 
If .Light(4) <> -1 Then ChunkData = ChunkData Or 2048 
If .Light(5) <> -1 Then ChunkData = ChunkData Or 4096 
If .Light(6) <> -1 Then ChunkData = ChunkData Or 4096 
If .Light(7) <> -1 Then ChunkData = ChunkData Or 4096 
If .Light(8) <> -1 Then ChunkData = ChunkData Or 4096 
If .Light(9) <> -1 Then ChunkData = ChunkData Or 8192 
If .Light(10) <> -1 Then ChunkData = ChunkData Or 8192 
If .Light(11) <> -1 Then ChunkData = ChunkData Or 8192 
If .Light(12) <> -1 Then ChunkData = ChunkData Or 8192 
If .Light(13) <> -1 Then ChunkData = ChunkData Or 16384 
If .Light(14) <> -1 Then ChunkData = ChunkData Or 16384 
If .Light(15) <> -1 Then ChunkData = ChunkData Or 16384 
If .Light(16) <> -1 Then ChunkData = ChunkData Or 16384 
If .Light(17) <> -1 Then ChunkData = ChunkData Or 32768 
If .Light(18) <> -1 Then ChunkData = ChunkData Or 32768 
If .Light(19) <> -1 Then ChunkData = ChunkData Or 32768 
If .Light(20) <> -1 Then ChunkData = ChunkData Or 32768 
If .Light(21) <> -1 Then ChunkData = ChunkData Or 65536 
If .Light(22) <> -1 Then ChunkData = ChunkData Or 65536 
If .Light(23) <> -1 Then ChunkData = ChunkData Or 65536 
If .Light(24) <> -1 Then ChunkData = ChunkData Or 65536 
If .TileExit.Map > 0 Then ChunkData = ChunkData Or 131072

Not too confusing now anymore, is it? Each set of 4 lights are combined together (or else we'd run out of bits!), so if 1 light of a tile is not -1, then all lights will be sent. This may seem sucky, but think of how often you have lights that arn't -1 on just one verticy... not too often, huh?

This also works like how the maps are saved/loaded. Certain flags are stored if a value is there or not, then it is grabbed. This is in replacement of grabbing the value no matter what just to find out if it has a value.

Now go put that binary knowledge to use!

Personal tools