5 ms·
Binary in JavaScript
- tantalor 11y agoWhat'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 11y agoCanvas 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/Tutorial/Pixel_manipulation_with_canvas https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/...
- fishtastic 11y agoIf 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 11y agoDoes this matter if your engine doesn't render stuff outside the viewport?
- fishtastic 11y agoIf 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 11y agoYeah I got that, but I was just wondering if thats where the performance hit is. Generating the map vs rendering outside visible area.
- fffrad 11y agoI'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 11y agoI 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 11y agoA long time ago I gave a horrendously overkill SO answer about it. http://stackoverflow.com/questions/11400242/bit-vector-implementation-of-set-in-programming-pearls-2nd-edition/11400933#11400933 http://stackoverflow.com/questions/11400242/bit-vector-imple...
- jetskindo 11y agoVery good explanation
- whalesalad 11y agoIn 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!!!
- fowl2 11y agoClever databases can do this themselves.
- cdmckay 11y agoAre 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 11y agoThis was somewhat of a contrived example.
- BinaryIdiot 11y agoGah, booleans use so little space do you really need that added complexity?
- onion2k 11y agoA solution that seems good right up until a bug starts flipping the wrong bit or someone decides that a flag needs 3 states instead of two. Bitmasking is a useful technique in some places, but storing user preferences isn't one of them. It's 'cleverness' for the sake of being clever - the code is harder to read, new developers can't immediately understand it, experienced developers have to look up what flags mean, you can't just dump the database row to see what a user's preference are, and if your documentation ever gets out of sync you're screwed. For the sake of saving DB space it's a really bad idea.
- chrismorgan 11y agoThere 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 11y agoAuthor 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.
- thomasfoster96 11y agoThis 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 11y agoThat'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 11y agoThe 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 11y agoSure, the underlying storage mechanisms are different and it doesn't support as many types, but I didn't say it was a good polyfill.
- fenomas 11y agoIf 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 11y agoIf 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.
- jchomali 11y agoNice article! Thanks for sharing this with us!
- the_rosentotter 11y agoAwesome 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 11y ago>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 11y agoIt 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 11y agoJS is not really a low level language in any sense.
- _greim_ 11y agoMy assumption was that JS bitwise misses the advantages of speed and space-compactness of bitwise in other langs, since you only have 64 bit floats to work with, thus forcing conversion to int and back for any bitwise stuff. I haven't read any good in-depth articles on the subject though.