12 ms·
Monospace: A JavaScript demo in 1021 bytes, winner of the demo competition
- kebman 6y agoThis made me think of THX 1138, the 1971 science fiction movie by George Lucas. Very nice work!
- rado 6y agoIt was hard to get to a working demo and here it is: http://www.p01.org/MONOSPACE/monospace-compatible.htm http://www.p01.org/MONOSPACE/monospace-compatible.htm
- josteink 6y agoEven as a Firefox-user, I would recommend running this in Chrome. It's clearly optimized for that target, and it's getting a much higher FPS in Chrome than Firefox.
- deleted 6y ago[deleted]
- mythz 6y agoNot optimized, Blink/WebKit doesn't have the Firefox performance issue emphasized in the article: > Unfortunately, Mozilla still hasn't fixed the performance bug 1190398 around ShadowBlur, filled for BLCK4777 5 years ago
- mcjiggerlog 6y agoJesus I should have read this comment first. It completely locked up Firefox on Ubuntu 20.04, rendering a frame and making a single beep sound about once per second. Had to close the browser and force kill some processes to get the TTS to stop.
- draw_down 6y agoGood old desktop Linux
- 1MachineElf 6y agoI had a beeping issue on Firefox 81 running on Windows 10. The weird thing was, the beeping noise continued even after I closed Firefox. There were some OS updates pending installation, so I just chose to reboot/install instead of troubleshoot further.
- bni 6y agoWorks fine in Safari also
- 0xcoffee 6y agoPretty interesting that even though I mute the tab it still speaks. The music does get muted, but not the TTS
- Namari 6y agoEven when the tab is removed the music continues :/
- 3np 6y agoThat is so weird - same here, sound keeps playing ~1-2 min after tab is closed. Must be bug in Firefox? How does that happen?
- username90 6y agoPretty easy to not properly clean up resources when you share processes between tabs. Firefox does that, chrome doesn't, so it properly cleans up in chrome since it quits the process. If you wonder why it plays for 1-2 minutes after the code stopped sending to the sound card, you always write sound in batches to the sound card so he likely wrote the whole 1-2 minutes in one big batch.
- 3np 6y agoMakes sense!
- paraboul 6y agoIt's using https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynth... which probably isn't affected by the "mute toggle" for accessibility reason.
- skykooler 6y agoHuh, I was wondering how they fit a speech synthesizer into less than 1kb. It being a builtin makes much more sense.
- mmanfrin 6y agoTanked my firefox instance, which I closed, and the noise from the page continued. Do no open this in firefox.
- deleted 6y ago[deleted]
- lifthrasiir 6y agoAnd when I tried to run it in Chrome, my laptop (MacBook Air 2015 early) completely froze up after a few seconds. Probably you should not open this in older devices at all.
- read_if_gay_ 6y ago> Unfortunately, Mozilla still hasn't fixed the performance bug 1190398 around ShadowBlur, filled for BLCK4777 5 years ago. > Therefore you need to use a Chromium or Webkit browser to enjoy MONOSPACE live.
- FraKtus 6y agoIt did stutter a little bit but I could enjoy it with Chrome on my MacBook Pro 2012.
- SandmanDP 6y agoBecause the rest of the commentors in this thread seem to not be reading the article, there's a performance issue in Firefox due to the following unresolved bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1190398 https://bugzilla.mozilla.org/show_bug.cgi?id=1190398
- mmanfrin 6y agoThe link to the demo comes before the warning to firefox, don't shame commenters who chose to see the content at discussion first before reading below the fold.
- lbj 6y agoWho's shaming anyone?
- m4r35n357 6y agoGuess . . . . "Because the rest of the commentors in this thread seem to not be reading the article"
- naikrovek 6y agoWe'll, they're not reading the article, yet they're expecting people to read their comment. And if not, why comment at all? I think some selective derision is warranted.
- _Microft 6y agoWhile it says that "[...] you need to use a Chromium or Webkit browser to enjoy MONOSPACE live." (emphasis mine), it does not say "DO NOT USE FIREFOX UNDER ANY CIRCUMSTANCES, it will mess up your device for minutes" anywhere. We saw so many (warranted or unwarranted) "Best viewed with Chrome"-statements on the web already that we became desensitized to it years ago.
- dang 6y ago
- vardump 6y agoI was so happy not to see another cheap dismissal here. Too often you have to read how a sizecoded demo uses a ton of system libraries or whatever, completely dismissing the technical achievement.
- posterboy 6y agoThat's a nonsense statement. There is no technical achievement, it's no breakthrough in any relevant technical sense. Sorry to get technical, but you called it. I'm not dismissing the demo, mind. It's a great feat of engineering and its main achievement, that is creative, surely thrives from a technical esthetic. Using system libraries has to be put into perspective, for sure. The common wisdom (in sizecoding at least) is that creativity thrives from constraints. Necessarily then, one has to be aware of the constraints. One might say having to write in .js is extreme masochism, so the criticizm about .dlls is just one side of the equation. Browser bugs and all that. no, thanks.
- algieg 6y agoTo everyone running it in Firefox: "Unfortunately, Mozilla still hasn't fixed the performance bug 1190398 around ShadowBlur, filled for BLCK4777 5 years ago. Therefore you need to use a Chromium or Webkit browser to enjoy MONOSPACE live."
- m4r35n357 6y agoThere is no opportunity to read this information before . . .
- mythz 6y agoDon't try this [1] in Firefox, from the article: > Unfortunately, Mozilla still hasn't fixed the performance bug 1190398 around ShadowBlur, filled for BLCK4777 5 years ago > Therefore you need to use a Chromium or Webkit browser to enjoy MONOSPACE live [1] http://www.p01.org/MONOSPACE/monospace-compatible.htm http://www.p01.org/MONOSPACE/monospace-compatible.htm
- A_Venom_Roll 6y agoFor people not able (or willing) to run the demo themselves, it can also be seen on YouTube in a 3 minute clip [0]. It keeps amazing me how much people can accomplish with less than a KB of code. [0] https://www.youtube.com/watch?v=2HN139WkcCY https://www.youtube.com/watch?v=2HN139WkcCY
- j4nt4b 6y agoNot being willfully obtuse, but there's a lot more than a KB of code on that YouTube page. To me it feels like the difference between watching a movie on 35mm vs DVD.
- posterboy 6y agoI expected the comment to go on about how much code in the support libraries is needed to support this. It's not a 512 byte boot sector intro, far from it.
- Theodores 6y agoThe video was lost on me whereas the demo made me think how cool it was. I expected the video to explain what it was but alas no. The video is just the demo running. The demo was brilliant, but, the video of the demo, although practically the same had me wondering quite negative thoughts. I wasn't thinking 'how do they do that', I was thinking 'this is a bit pretentious'. It is amazing the difference context makes.
- j4nt4b 6y agoTotally agree. I can't watch the demo run because I'm on Firefox, and I have no desire to watch a video for the reasons you described. And the world keeps spinning, I guess.
- robertlagrant 6y ago> I wasn't thinking 'how do they do that', I was thinking 'this is a bit pretentious'. Everyone experiences things differently. Some people see a sports car and think, "Wow, I wonder how it works?" Others, "Wow, I hate that colour." Doesn't really matter.
- deleted 6y ago[deleted]
- Rheajain 6y agoPackers and Movers Delhi for 100% Affordable and Professional Packers and Movers in Delhi Compare Charges of Movers and Packers, Household Shifting Services at. @ https://packers-and-movers-delhi.in/ https://packers-and-movers-delhi.in/
- m4r35n357 6y agoDon't use this piece of JS shit in Firefox!
- j4nt4b 6y agoI'm getting the same issues as all of the other Firefox users. Guess I'll never watch it, because I have a hard policy of never, ever installing Chrome malware on my personal computer. Maybe the title should be changed to "Chrome demo"?
- jansan 6y agoYou could ask one of your friends to watch the demo on their computer.
- fireattack 6y agoJesus, no one cares what your "policy" is. Not to mention, it's a Firefox bug, so probably should be changed to "Firefox bug demo". I fucking hate how snarky sometimes HN can be.
- account42 6y ago> Jesus, no one cares what your "policy" is. I care.
- olig15 6y agoJust watch the attached video?...
- onion2k 6y agoMaybe the title should be changed to "Chrome demo"? It works in Chromium browsers (Chrome, Edge) and Webkit browsers (Safari). Saying it's a Chrome demo would not be accurate.
- bulka 6y agoI, for one, liked the "firefox version" of the demo. No way to close, mute or go back. And after a minute someone starts talking to you. Pretty cool.
- 3np 6y agoThis is amazingly impressive. It boggles my mind how much can be done with so little.
- ricksharp 6y agoAmazing! Very impressive how you got all the details in. I'd be interested in hearing what the development process is like. Do you work directly in the minified code, or do you create the demo in normal code first then look for ways to minimize it?
- lifthrasiir 6y agoI'm not the author but I've done this before [1], so here's what I can quickly make up (EDIT: updated using informations gathered from p01's comment below): // c is a canvas created outside d = [ // 2 times audio frequencies used, I think 2280, 1280, 1520, c.width = 1920, // d[4] is not used, not sure why this stmt was stuffed into d // required to hide the PNG bootstrap; the bare minimum would be `0'`, probably this compresses better though? document.body.style.font = "0px MONOSPACE" ], g = new AudioContext, o = g.createScriptProcessor(4096, // clears the margin and initializes vars // (t: time in seconds, n: last t when speak occurred) document.body.style.margin = t = n = 0, 1), o.connect(g.destination), o.onaudioprocess = o => { // periodically called to fill the audio buffer, used in place of setInterval o = o.outputBuffer.getChannelData( e = Math.sin( t / 16 % 1, // this is the only arg to sin, others are for shoving exprs into a single stmt m = Math.sin(Math.min(1, y = t / 128) * Math.PI) ** .5 + .1, c.height = 1080, // setting canvas.width/height clears the canvas b.shadowOffsetY = 32420, // results in `radial-gradient(#222,black` or so, reinterpreting decimal number as hex, the last `)` is not required c.style.background = "radial-gradient(#" + [222, 222, 222, 222, 155, 155, 102, 102][t / 16 & 7] + ",black", b.font = "920 32px MONOSPACE", // each function determines the dot size for 16 seconds, also sometimes used as a display text f = [ (x, y, t) => x / y * 2 - t, (x, y, t) => (x ** 2 + y ** 2) ** .5 - t, (x, y, t) => x / 4 ^ y / 4 - t, (x, y, t) => y % x - t ][t / 16 & 3], // determines a string to print and speaks it every 16 second // the inner [...][t/16|0] can return undefined, which gets coerced to an empty string by `""+[...]` u = "" + [[, f, f, " CAN YOU HEAR ME", f, f, , "MONOSPACE", "THE END"][t / 16 | 0]], t > n && speechSynthesis.speak(new SpeechSynthesisUtterance(u, n += 16))) ); for (i = 0; 4096 > 4 * i; i++) // for each dot; `4096>4*i` probably compresses better than `1024>i` // calculate the dot size and mix with the radius in the previous frame for easing // f and g are objects (function and AudioContext), so can be abused as a generic store g[i] = r = (f(x = 16 - i % 32, a = 16 - (i / 32 | 0), t) / 2 & 1) + (g[i] || 0) / 2, x += o[0] / 4 + 4 * (1 - m ** .3) * Math.sin(i + t + 8), a += o[64] / 4 + 4 * (1 - m ** .3) * Math.sin(i + t), h = x * Math.sin(y * 2 + 8) + a * Math.sin(y * 2), p = 4096 / (m * 32 + 4 * h * Math.sin(e) + t % 16), b.beginPath(f[i] = r / p), b.arc(h * Math.sin(e + 8) * p + 1280, x * Math.sin(y * 2) * p - a * Math.sin(y * 2 + 8) * p - 31920, p > 0 && p / (2 + 32 - r * 16), 0, 8), // anything larger than `2*Math.PI` will draw a full circle b.shadowBlur = o[0] ** 2 * 32 + 32 - m * 32 + 4 + h * h / 2, // `[a,b,c]` coerces into a string `a,b,c` b.shadowColor = "hsl(" + [f(x, y, t) & 2 ? t - a * 8 : 180, (t & 64) * m + "%", (t & 64) * m + "%"], b.fill(); b.shadowBlur = o[0] ** 2 * 32, b.shadowColor = "#fee"; for (i = 0; 4096 > i; i++) // generate each sample, also prints the glitched text o[i] = o[i] / 2 + ( ( Math.sin(t * d[t / [4, 4, 4, 4, 1/4, 1/4, 16, 4][t / 16 & 7] & 3] * Math.PI) * 8 + (t * d[t / 8 & 3] / 2 & 6) + t * d[t / 16 & 3] / 4 % 6 ) / 64 + f[i / 4 | 0] // f[0..1023] is the visual data, reused as a noise ) * m, // prints at most 64 characters of u; // 0th and 64th samples (o[0] & o[64]) of the prev/current buffer act as x/y jitter, // first 64 samples also displaces the char offset for the glitched text effect 64 > i & t % 16 * 6 > i && b.fillText([u[i + (o[i] * 2 & 1)]], // again, [undefined] coerces into an empty string i % 9 * 32 + o[0] * 16 + 180, (i / 9 | 0) * 64 + o[64] * 16 - t - 31920), t += 1 / g.sampleRate // so t increments by 1 per second } While the obfuscation itself is fairly standard, I think the real magic here is the carefully selected motion and jitters---which I can't easily figure out from a glance. > Do you work directly in the minified code, or do you create the demo in normal code first then look for ways to minimize it? Also, in my experience you end up structuring everything so that it can be easily minifiable (by hand or using something like terser-online [2]). This doesn't necessarily mean that the code is unreadable (variables can be renamed, statements can be converted to comma expressions and so on), but the resulting code would be very unorthodox. See the source code of my JS1024 entry for example. [1] https://www.js1024.fun/demos/2020#46 https://www.js1024.fun/demos/2020#46 [2] https://xem.github.io/terser-online/ https://xem.github.io/terser-online/
- Kiro 6y agoPeople love to bash developers who put up "Chrome recommended" banners, dismissing them as lazy, but when making games and such there are real issues that are impossible to circumvent. This bug is a prime example of that.
- lifthrasiir 6y agoI sympathize with developers dealing with browser bugs, but a majority of "Chrome recommended" banners are not. For many cases they are used as a cheap excuse not to care about or even deter non-Chrome browsers at all, even when they do work mostly or completely fine. Demos, in comparison, tend to have much narrower requirements due to various constraints (many D3D demos only worked with specific graphic cards at least in the initial release, for example).
- robertlagrant 6y agoNow CypressJS has a Firefox backend it's less forgiveable.
- Kiro 6y agoI agree but the last time the pitchforks went out on HN regarding this was for a game, so not very different from demos. The issue I'm personally dealing with is for a game revolving around a feature that's only working properly in Chrome (see sibling comment for link to bugzilla). I've tried solutions for mitigating it but since I'm just one guy I've basically given up for now and have resorted to a warning for Firefox users. In all honesty I don't see how it's different from only releasing a game on Xbox and not PlayStation.
- lifthrasiir 6y agoI guess that was shapez.io [1]? The situation around WebRender is pretty unfortunate, as AFAIK it is blocked by the compatibility issue in macOS. I have played it in Windows Firefox just fine though. Anyway, I think it's more about the wording: it's very fine that the developer hasn't tested much in other browsers (not every developer has resources to do so, sure), but saying a certain browser is required or recommended implies that the issue is something to do with that browser (which might or might not be the case). Shapez.io also doesn't support macOS in its standalone build, but the statement on that was more amicable and honest; I wish the developer did the same for non-Chrome browsers as well. > In all honesty I don't see how it's different from only releasing a game on Xbox and not PlayStation. Consoles generally have much different requirements (hardware, vendor integration etc.) than PC games. For me it's more like Steam vs. Epic Store which I found pretty frustrating as a gamer. [1] https://news.ycombinator.com/item?id=24678720 https://news.ycombinator.com/item?id=24678720
- rsiqueira 6y agoHere are other visual JS Demos created by p01 and others using just 140 characters of code (or less!): https://www.dwitter.net/top/year https://www.dwitter.net/top/year Dwitter is a collection of amazing short JavaScript codes that can be explored, remixed and voted "awesome". It works like a living portfolio of short code/graphic creations where one can learn by exploring other people's code.
- janOsch 6y agoIt is amazing how much one can achieve with so little code. I would dare to say that such demos are a kind of...indie art? Can you give us some pointers, which APIs and algorithms did you use to generate the demo? I bet it will be an interesting lesson on math and web
- Hnrobert42 6y agoI was put off by the first paragraph. The author could have found a more modest way to introduce the subject.
- nneonneo 6y agoThe real version of this, which is actually 1021 bytes, is here: http://www.p01.org/MONOSPACE/monospace.htm http://www.p01.org/MONOSPACE/monospace.htm. It uses the very clever trick of compressing the JavaScript code as the pixels of a PNG image (which uses Deflate internally), then including the page itself in an <img> tag and decompressing the JS code from the resulting pixels. Unfortunately, the developer made a bit of a mistake when uploading this file: it appears to have been uploaded in ASCII mode rather than binary mode, meaning that all the 0x0d (CR) bytes in the file have gone missing (an artifact of the standard "CRLF -> LF" translation performed in text mode uploads). Therefore, it doesn't work: all you get to see is a screenful of binary junk. (Author, if you're seeing this - it's hopefully an easy fix!) I've uploaded the correct version (obtained from http://www.p01.org/MONOSPACE/monospace.zip http://www.p01.org/MONOSPACE/monospace.zip) here: https://robertxiao.ca/misc/monospace.htm https://robertxiao.ca/misc/monospace.htm. This works out-of-the-box on Firefox (modulo being really slow, thanks to https://bugzilla.mozilla.org/show_bug.cgi?id=1190398 https://bugzilla.mozilla.org/show_bug.cgi?id=1190398), but fails on newer Chrome because of click-to-play audio. You'll have to "allow" my site under chrome://settings/content/sound, then refresh. But! Once you've jumped through those hoops, you can appreciate the real ingenuity that manages to pack this demo into a cool 1021 bytes (the compatible version that most of you would have seen is much larger, at 2338 bytes).
- RobertKerans 6y agoAh, I wondered why I was getting junk when I clicked that link, thank you for uploading (still falls over for me when I accidentally opened it using FF, but no harm done)
- p01 6y agoHi, my bad. I forgot to set the Transfert Type to binary on my new laptop :p Hope you enjoy MONOSPACE anyhow. I am pretty happy with how it turned out. I believe I managed to nudge a little the state of art of what type of camera work is possible in 1kb demos.
- RobertKerans 6y ago
- auggierose 6y agoThe sounds reminds me a bit of Laurie Anderson's "O Superman".
- rpastuszak 6y agoOK, this is really weird, but I closed the browser tab with the demo ca. 1 minute ago and can still hear the music. I'm on FF/Big Sur.
- faitswulff 6y agoSame. Had to force quit.
- suprfsat 6y agoHad to recycle my macbook
- import 6y agoSame, there is a weird sine wave with high pitch and frequency.
- jackewiehose 6y agoWith FF mobile on Android I still had ongoing sound after closing FF completely (at least as far as I know) and I had to reboot my phone. It's quite concerning that websites are able to do this. While it is the browsers fault to support all that javascript crap I think this is also a bug in Android.
- rpastuszak 6y ago> It's quite concerning that websites are able to do this. They've been able to do this for a long time and for valid reasons (think of a PWA audio player, like a podcast app). Unfortunately this used to get abused very often. I remember seeing bugs in ads that would: stop your Spotify playback (due to how audio apis work on phones), and continue playing in background (again, this is a feature, but often abused). iOS is much better in that regard, with stricter autoplay policies, etc... What's super concerning is that audio worked even when the page was closed. Once I kill the tab, the entire process should be killed too. So yeah, it's possible that it's just an FF bug purely because being able to play audio in BG is a valid feature BUT there should be no audio when the tab has been killed. My guess is that from the OS perspective, the tab is still running. My another guess is that it has something to do with some clever techniques regarding reducing the app size.
- sergeykish 6y agoFunction call without parentheses c.getContext`2d` invoked as tagged template
- detritus 6y agoIt's amusing to me that I saw this about 5 minutes after I received a pop up notice from Adobe advising me to uninstall Flash as it'll be EoL'd in a few months. I appreciate they're entirely different beasts, but the Monospace demo here definitely IS creative.
- mrspeaker 6y agoThis is similar (but much much better) to a demo I was making for JS1K a bunch of years back: http://mrspeaker.github.io/js1k16/ http://mrspeaker.github.io/js1k16/ My "big idea" was to use the speech synthesis API (I still liked how I used it)... but I thought it was funny, because it felt like cheating to say "1K" when it relied on so many megabytes of APIs!
- p01 6y agoDoes it count as megabytes when it's bog standard API ?
- mrspeaker 6y agoNah, of course not! It's fair game (otherwise you'd first have to invent the universe). It was just the speech synth API was pretty new when I did that, so it felt sneaky ;) Also - p01, you are a hero to us all. MONOSPACE is beautiful, congrats on the Assembly win!
- nacs 6y agoThe speech synthesis sounds like it is panicking. Quite funny.
- crehn 6y agoThis is some next-level rap music, nice.
- andrethegiant 6y agoTIL of the speech synthesis API. It's been around since 2013/2014 https://caniuse.com/mdn-api_speechsynthesis https://caniuse.com/mdn-api_speechsynthesis
- _the_inflator 6y agoI value p01's contribution to the world of optimized code using JavaScript. He is doing this for many years now, and he still keeps pushing the boundaries with creative optimization techniques. This is so cool!
- p01 6y agoGlad you like it :) -- p01, author of MONOSPACE
- raydev 6y agoWhat is the source for the music?
- p01 6y agoDo you mean the source code or the inspiration ? The main part of the source code is the last `for(...)` loop that updates the sound buffer, and draws the text. There was not much inspiration :p I needed something simple enough to be fairly compact and sound melodic. So I used a chord of 4 notes, played them at different speed and octaves. The lead using a sinus oscillator to get nice pure tones, a deeper sound 4x slower with a pulse oscillator to get more edgy sound, the deepest sound 16x slower with a sawtooth to get a gritty bass. Layered with the perspective scaling of the dots to get something bleeps in synch with the visuals. Hope that answers your question
- khazhoux 6y agoWas blown away by the technical and artistic merit. Well done!!
- bane 6y agoThis won the Assembly 2020 1kb demo competition. There are some truly mind-blowing entries, including the 2nd place entry which features multiple types of spaceships and a stargate, with audio. https://www.pouet.net/party.php?which=7&when=2020 https://www.pouet.net/party.php?which=7&when=2020
- btbuildem 6y agoIt's fantastic that the demoscene just keeps on going. It's been decades!
- warent 6y agooh wow, I thought the video was an artistic edit of the program. it was frustrating me because just wanted to see the program, not a filtered, edited trailer. then I realized that's the program. this is really mindblowing, the creator is definitely some kind of genius
- woohoojoo 6y agoWho decided to use extremely annoying sounds as the audio track for the first video on the page [1]? I turned it off immediately after hearing its audio. If you want folks to watch a video, allow me to suggest making it as pleasant an experience as possible, at least in terms of the audio. Terrible marketing = marketing that makes your customers/prospects/audience suffer [1] https://www.youtube.com/watch?v=2HN139WkcCY&feature=emb_logo https://www.youtube.com/watch?v=2HN139WkcCY&feature=emb_logo
- dpc_pw 6y ago1021 bytes of JS, and 6 million lines of browser code. FTFY These modern demos, using OpenGL and now the whole web browser that are mimicking the rules and sentiment of old 8-bit machines demos, or even later DOS demos, are not the same thing. Oh, this demo has text being spoken ... how was it done ... checks source code ... SpeechSynthesisUtterance . Yeah right, 1021 bytes. :)
- debt 6y ago"Finally, yes MONOSPACE is named after the font family used to write the text, to gain a few bytes." Ha, that's amazing.
- ExcavateGrandMa 6y agoIt's so useful... were I can find the util code demo scene? :Ð
- deleted 6y ago[deleted]
- sabujp 6y agohere's the rest of them : https://archive.assembly.org/2020/online-1k-intro https://archive.assembly.org/2020/online-1k-intro
- rendall 6y agoVery impressive. Under 1kb. Astonishing. I love that people keep pushing against the boundaries of what is possible to do. It's important work, and so fun!
- thelazydogsback 6y agoGreat art piece regardless of size -- I could totally see this playing from a 8mm projector at the Whitney museum in 1968...