

Binary in JavaScript - codecurve
http://danthedev.com/2015/07/25/binary-in-javascript/

======
chrismorgan
There are several minor erroneous points in this document. Here are the two
that are probably the most egregious:

\- The whole object and string representation thing is naïve to the point of
total incorrectness. Where is the object and its length and type stored, for
example? And browsers intern strings (store them once with garbage collection
of some form to clear out the values when they are no longer needed) and don’t
use null-terminated things (otherwise you couldn’t have "\0"), so your 320
bits is actually more likely to be 192 or 96, with the full 320 bits plus
approximately three or six more words occurring only once. (I’m being a little
vague about this because I’m not familiar with what specific techniques are
actually used in browsers at present.) The end result of it all is that the
actual figure will, I think, be more like 30–50 bytes per tile, not 60. (Then
again, it may end up more, and it will definitely depend on the browser; I’m
not up to date with the performance- and memory-efficiency techniques used.)
I’m complaining here only because it’s misleading about how things are done;
the concerns it raises are absolutely genuine.

\- Bitwise operations on numbers are only 32-bit, not 64-bit. You want 64-bit
bitwise operations? There’s no native support for it, you’ll need to emulate
it. This is a part of the tangled mess that is a unified number type which can
be either a 32-bit integer or a 64-bit floating point number.

~~~
codecurve
Author here. There were a lot of ends that I tried to tie up that started to
be difficult to find hard evidence for. Some of the string/object storage
stuff is discussed casually in mailing lists, but there aren't great places I
could point to and say: _this_ is the definitive answer. If you would point me
in the right direction for some of these resources, I'd be happy to amend the
article. Thanks for reading all the same.

------
tantalor
What's more, when your data is in a TypedArray, you can upload the whole thing
to a texture with a single call to WebGLRenderingContext#texImage2D.

~~~
mxfh
Canvas supports a similiar method: _getImageData_ returns a
_Uint8ClampedArray_ , _putImageData_ stores it back into the context.

[https://developer.mozilla.org/en-
US/docs/Web/API/Canvas_API/...](https://developer.mozilla.org/en-
US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas)

------
fffrad
I've recently been getting into binary formats and being a JavaScript
developer it is very hard to think in binary.

This is the first time I see someone giving a good real world example of
bitwise operators that I can understand.

~~~
cettox
I agree, it is almost ignored in most tutorials and I only see implementation
examples in some neat projects, and always left with a wondering mind.

~~~
airza
A long time ago I gave a horrendously overkill SO answer about it.

[http://stackoverflow.com/questions/11400242/bit-vector-
imple...](http://stackoverflow.com/questions/11400242/bit-vector-
implementation-of-set-in-programming-pearls-2nd-edition/11400933#11400933)

~~~
jetskindo
Very good explanation

------
thomasfoster96
This whole problem will probably be solved with Typed Objects, which looks as
though they'll be standardised with ES7 next year. Plus, there's already a
decent typed objects polyfill available, so don't go littering your code with
bitwise operations.

~~~
codecurve
That's good to hear, I wasn't aware of Typed Objects. I guess the library
linked at the end of the post is basically a very non-specific polyfill
already? Well, using it like that is one way to get around bitwise littering.

~~~
thomasfoster96
The library at the bottom isn't anywhere near a typed objects polyfill - it
just packs data into small spaces. Typed Objevts would let you have objects
where properties are of a static type (int8, Boolean, string) and they are
stored using Array Buffers.

~~~
codecurve
Sure, the underlying storage mechanisms are different and it doesn't support
as many types, but I didn't say it was a good polyfill.

------
fishtastic
If the design of your roguelike limits player vision so they only see their
surroundings, then instead of generating the 512 x 512 map in one go, you can
improve the performance/memory usage by generating only the blocks around the
player.

This would save a lot of initial loading time and could support maps much
larger than 512 x 512.

~~~
seivan
Does this matter if your engine doesn't render stuff outside the viewport?

~~~
fishtastic
If your engine doesn't need to render objects outside the viewport, then you
don't need to generate those objects until you actually need to render it.

~~~
seivan
Yeah I got that, but I was just wondering if thats where the performance hit
is. Generating the map vs rendering outside visible area.

------
fenomas
If there's one thing I've learned in a half year of JS game development, it's
that there are usually good libraries to solve most low-level problems.
Compactly storing a 512x512 array of binary values can be as simple as:

    
    
        var vegetation = require('ndarray-bit')([512, 512])
        vegetation.set(23, 42, true)
        vegetation.get(23, 42) // true

~~~
yoklov
If there's one thing i've learned in ~5 years of game development (and ~1 of
JS game development), it's that generic libraries are almost always inferior
to a custom solution when you're performance tuning.

------
the_rosentotter
Awesome technique, thanks for posting. I have a very large grid of nodes for
my game map (used for path finding) and this looks like it could save a lot of
memory.

------
anotherangrydev
>Unbeknownst to some, Javascript comes equipped with a relatively good set of
bitwise operators.

Never thought that there were people doing Javascript who didn't know about
bitwise operators. I guess I know where 99% of the "Javascript sucks" posts
come from.

~~~
Kequc
It is a low level language, it is blazingly fast and powerful if you use it
correctly.

It is also badly designed and disliked as far as I can tell just about
universally in every aspect as a language. Objective C is also blazingly fast
and powerful if you use it correctly but not everyone wants to. It isn't about
not knowing it has access to bitwise operators.

~~~
yoklov
JS is not really a low level language in any sense.

------
whalesalad
In a similar fashion, storing user properties like whether or not they want
email subscriptions, their notification settings, etc... Is something that I
often use a bitmask field in my model to save space in the db.

These can be queried using bitwise operations and you can abstract all of it
with synthetic instance properties.

User.email_enabled = true would translate to 0010 or something in, for
example, a properties column.

Really handy stuff!!!

~~~
cdmckay
Are you running out of space in your database? It just seemed like a way to
needlessly complicate your database, make it difficult to query (what was
email_enabled again? the third bit?), difficult for other developers to use
(now it needs a comment to understand) and difficult to constrain for data
integrity.

I think that unless you're having space issues, you're better off using
boolean columns.

~~~
whalesalad
This was somewhat of a contrived example.

