Hacker News new | comments | show | ask | jobs | submitlogin
JS1024 Results – 1k JavaScript Demos (js1024.fun)
195 points by KilledByAPixel 5 days ago | hide | past | web | 43 comments | favorite

Post-mortem writeups by submitters:

Frank Force: https://frankforce.com/?p=7617 (1st place)

Raimon Ràfols: http://blog.rafols.org/index.php/2020/07/21/javascript-ballo... (10th place)

Mattia Fortunati: https://www.mattiafortunati.com/detective-moji-postmortem-a-... (16th place)

> Frank Force

Hey, that's the guy who did Bounce Back[0] for JS13K! He's got some pretty cool stuff on his website

EDIT: Wait a minute, that's KilledByAPixel, who submitted this link

[0] http://frankforce.com/?p=6936

I haven’t written a post-mortem but I’ll take a quick stab here, and post a more polished post-mortem on my website later.

My demo is Star Traveler, which placed #1 in the 2D Canvas category. The GitHub repository is here: https://github.com/depp/demo-traveler

Source code: https://github.com/depp/demo-traveler/blob/trunk/src.js

What I like about 1K demos is that you can make them in a relatively short amount of time—something like a week or so, without taking time off. After a week of work I was happy with what I had written, out of space, and had diminishing returns when I attempted to reduce the size. By comparison, JS13K can be a lot more work.

The first thing I did was set up a development environment which would reload in the browser every time I saved changes. The development page showed the number of bytes left at the top of the screen and put the exact, submission-ready code in an iframe. Saving changes would trigger everything to be minified and packed again. Packing is done with Terser -> RegPack. No potentially incompatible techniques like method hashing were used, but that’s probably because I didn’t see a size improvement when I tried them. There are some custom transformations on the code during compilation, mostly so I could have ESLint watch my back.

The demo itself has three parts to it. Most of the objects are rendered by callback functions, and there’s a big array of callback functions in back-to-front order. The function closures contain any generated data necessary for drawing the data. The parts are:

1. Mountains and clouds, which are just simple midpoint displacement fractals. The mountains were flipped upside down and stretched to make clouds. Various techniques for generating a fractal were tried, a recursive functional approach ended up being the smallest.

2. Stars, which are just randomly placed in 3D space and randomly resized each frame to make them twinkle.

3. The planet, which is drawn separately. The submitted version draws it over the clouds. This was fixed in the repo, but not re-submitted.

Notes on technique:

- Path2D turns out to be a very efficient way to specify a path for a Canvas. It uses an SVG path string to specify the path, which is more compact than using .moveTo() and .lineTo(). There is room for improvement.

- The 'color' function is a beast, it lets you represent an RGB color as a 3-digit number from 111 to 999, and calculate things like gradients. There was a lot of tweaking to get colors that I liked.

- Did a lot of inlining and un-inlining of functions at the end. For example, if a function f(x) is defined like f(x) = 4 * ..., then you can move the constant out of the function, or into the function from the call sites.

- Checked the minified code to see how functions were being emitted. If they were emitted as (x) => { a; b; }, I would try to change the code so they could be emitted as (x) => (a,b).

- RegPack gives you limited space savings for repetitive code, so use it.

- If you need local variables, just add arguments to your function and use those.

> Path2D turns out to be a very efficient way to specify a path for a Canvas. It uses an SVG path string to specify the path, which is more compact than using .moveTo() and .lineTo().

Path2D w/ SVG strings is byte-efficient, but is less computationally efficient vs the same Path2D w/ lineTo(), etc.

Some context—in JS1024, the code has to fit in 1024 bytes, so you can safely assume that “efficiency” refers to size and not runtime performance.

This particular demo only creates the Path2D objects once, at startup, and then hammers the canvas with a ridiculous amount of overdraw.

There’s something ironic about a site hosting intentionally tiny snippets of code that’s crashed / sluggish under the social media hug of death...

BUT - the few that I’ve managed to see are super cool, so when it comes back to life it’s worth checking out!

Question for people that run websites that have been “hug of death”ed: would your website be able to be statically hosted on something like github pages, if no why not — if yes why do you choose not to, given it is free and would make all scaling troubles go away (or so I’ve heard).

There are two reasons why sites fall over in cases like this: CPU saturation, where the solution is better caching (which includes going fully static), and network saturation, where the solution is either to get fatter pipes or to reduce the data transferred. Hugs of death are normally due to CPU saturation.

But in this case, I suspect that the server is just saturating its network connection because of poor treatment of images.

I have JavaScript disabled so maybe it’s loading more if you have JavaScript enabled, but when you exclude images, it’s only transferring about 152KB. Images are where it goes wrong: it’s serving up a large number of images, and some of them are unreasonably large and high quality (like 34ᵗʰ place, a 1000×1000 PNG of a fractal being shown at 400×400), and most significantly it’s using quite a few multi-megabyte GIFs, which is flatly stupid and wrong and they deserve to have their site fall over for pulling that.

So the end result is at least 20MB. 20MB = 160Mb, and if your server has only a one gigabit link (very common), you can suddenly only cope with about six visitors per second (though in practice things will start falling over before that, maybe round down to five), which is not quite enough for the peaks you’ll get when high on HN, and it becomes a bit of a cascading problem, kinda like a capacitor but bad.

The solution is to treat the images properly: actually compress them, use videos instead of GIFs, that sort of thing. I reckon 3MB total is readily attainable here, which would allow you to serve 40 visitors per second, which is probably enough.

So yeah, putting your pages on a platform with really fat pipes will solve problems like this after a fashion, but I’d argue that it’s not really solving them, it’s just letting you get away with doing a bad job and shifting the burden onto users.

There was 5MB preview image limit for each submission. I was a bit surprised when my preview image went straight into the listing after review. The organizer was a bit struggling with the website (for example, there was no HTTPS for the first days of the contest and multiple people helped to get it working), hopefully next time it will improve.

Hi! I'm the host of js1024. Thank you for your advice, I'll try to fix these errors

> if yes why do you choose not to

Because there's more work in caching your dynamic server/CMS to static files and often isn't trivial. And the dynamic-rendered CMS is enough 99% of the time. You act like it's just a button you press, and you're wondering why people don't just press it.

It's also not a money-making venture. So you have very poor ROI on making your charity site endure the rare hug of death. It goes down? Oh well. It'll come back up. It's also the reason you're using some cheap CPanel setup, not deploying to a $5 VPS.

Sure I can understand not migrating existing dynamic websites to a static deployment model - don’t fix what isn’t broke. I suppose the question is more about greenfield projects, where in my experience writing a couple markdown files and pushing them to github and checking the “serve this” box is easier than managing a server.

> It's also not a money-making venture. So you have very poor ROI on making your charity site endure the rare hug of death. It goes down? Oh well. It'll come back up.

This is a very strange statement to me. My impression would be that if you’re running a charity site (or any site that makes money from being visited), you would want it to absolutely not go down during a hug of death, as that’s money out of your pocket at a time when it’s getting a ton of free publicity. Why make the site in the first place if you aren’t expecting it to provide value to either you or the viewer?

>where in my experience writing a couple markdown files and pushing them to github and checking the “serve this” box is easier than managing a server.

Making a site is more than "just some markdown files". Can you show me what you're talking about? Maybe I'm missing it. If you mean static-site generators (they aren't just a couple markdown files), they are very nerdy and have pretty bad UX for most people. I don't even use them. They are effectively developer-only, for one.

> This is a very strange statement to me.

Well, this is how things work. This goes back to the parable of the lumberjack who didn't have time to sharpen his axe, or the guy who didn't have time to write a shorter letter.

You just want to get something online that others can modify. Any additional second your pour into it is probably a waste of time. A niche website like JS1024 is down? Maybe nobody really cares. Maybe the only person willing to host this just does things this way. Oh well.

Edit: Your confusion here reminds me when I got my first dev job and was confused why the other developers never wanted to improve these obvious problems in the code. Or use new patterns. Or learn new things (16+yo VBScript app, the website was one 500k line switch statement running on IIS). "Doesn't anyone care?!" But as I got older, "I can't be fucked" or "cbf" made a lot more sense to me. Don't underestimate how often "cbf" answers your questions. ;)

Cloudfront & friends are pretty easy and cheap to do.

I was expecting an expensive hassle, but was happy to be wrong on that.

Sure most websites could easily served as static files on a server, but advocating for everything to be hosted on a single proprietary service is not a good idea.

But hosting an Apache or nginx to serve static files is easy enough and a single $5 or $10 instance on any hosting service out there could easily survive a HN frontpage.

Not advocating for any service in particular (though disclaimer I do work at msft), I’m honestly wondering why someone would choose to ship a website as a server running on a hardware time slot rental with all the setup, cost, inscalability, and management that requires, as opposed to a free cdn that gives you a website with only some markdown.

Mainly because it was not a mere markdown. You can't see right now, but it had submission forms with previews and rating forms. Yes, you can route dynamic parts to elsewhere, but it was not really static for a while.

You're assuming everyone expects to get Hug'o'Deathed. I suppose a site like the one here should expect a higher bandwidth around competition and announcement time, but for independent people who happen to get picked up on HN/Reddit/etc?

Cloudflare is free, and will take most of the hit if you can serve a reasonable amount of it yourself.

Just gotta make sure its setup to cache your html

The website is loading megabytes of images from its own domain without a CDN. R.I.P. web server.

I only get a secure connection error with Firefox 79 (on ArchLinux) when trying to connect to that domain. The certificate configuration seems to be missing some intermediate certs:



Alway there is that one arch guy in the comments

Having the same error on Firefox Preview

Same thing with Firefox for Android ..

If you enjoy this kind of thing, check out the wizardry/madness over at https://www.dwitter.net/ - javascript animations in 140 bytes (the size of a tweet, hence the name, "dwitter").

Thanks. In 10 minutes I have seen more art than one can see in the average museum of modern art.

yeah already bookmarked that website, pretty cool!

I really appreciate how well documented a lot of the source files are. There are a lot of cool golf hacks/tricks in these!

i.e.: https://js1024.fun/demos/2020/16/source

Besides from being one of the winners (AquaPop1K), I also had a pleasure to read every single source code to rate submissions (as every submitter could rate other entries). I recommend to do the same if you have time.

“Shedding snake” reminds me of a game I made on my Casio CFX-9850GB+ Color in high school. It started out as snake, but keeping track of the positions of the snake’s pixels in an array or matrix, even if treating it as a ring buffer so you weren’t constantly shuffling all the values in it, was really slow, so that by the time the snake was even six pixels long there was not the slightest bit of challenge to it because it was moving less than two pixels per second (and by ten, below one). So I turned it into what I called Snail Trail, with it just laying down pixels behind it and never keeping track of them, because you could query “is this pixel filled?” much more rapidly (and it was O(1) rather than O(n²) or worse). That was much faster, and I rapidly worked out the optimal strategy. A year or two later I transferred it to someone’s newer model of calculator which was generally about six times as fast, and… yeah, I had to insert busy loops to make it playable!

I had good times with that calculator. 32KB taught me frugality not unlike that needed for competitions like JS1024, and how to find that there was a character/instruction akin to a semicolon in Python that took one byte, where the new line character/instruction took two bytes. (I only obtained a manual for the calculator after having it for two years. Figured out one or two new tricks after that, but I’d worked almost everything possible out by trial and error.) So power efficient, too: I changed the four AAA batteries only twice in more than three years of very heavy usage (looking back on it, I probably got more than 200h of life from each set), while all the rest of the class that had the newer, faster version (except one other who had the same model as me) would need to change them around once a term, and they didn’t use their calculators even a quarter as much as me. I’m going to guess figures of a CPU 6× as fast and power consumption 30× as high. And those newer ones were even only monochrome rather than three-colour LCD.

Then after I left they shifted to CAS calculators and battery life was a zillion times worse again. And laptops, phones and such will be even worse still. Ah well.

My lockdown project has been hacking up my CFX-9850G calculator. So far I have physically removed the ROM of the calculator and replaced it with a new ROM (I was able to get old-stock chips from aliexpress) flashed with a patched version of the original OS that includes a new BASIC command to jump to a fixed location in RAM and start executing whatever is there. This means I can write and run arbitrary machine code in the calculator’s RAM by abusing the built in backup feature. The Hitachi CPU in the calculator is quite strange but by working with the little information I can find online [1] I have written an assembler and linker for creating compatible machine code from a custom assembly language. The resulting code runs much faster than in BASIC because it doesn’t have to be interpreted. Here [2] is a video of the calculator jumping into RAM and running a Game of Life program that I wrote when Conway died. I’m currently writing code to run the 3-colour display for a replacement Forth-like shell/OS with the aim to eventually get to the point where I can replace the calculator ROM completely with my own. Writing my own mathematical functions for a calculator is fun when (AFAIK) the CPU itself lacks even multiplication opcodes.

[1] http://martin.poupe.org/casio/ [2] https://youtu.be/cTB5YM898g4

Same for me, except with the FX-9860GII and for the 'trails' feature originally being a bug in my ring buffer that triggered when it grew.

It definitely was fun to experiment within such constraints. I can't remember being very concerned with program size, although after a certain size there was a boundary the jump statements weren't able to cross any more. Only having global one-letter variables and no function calls (and a 21*7 character screen) also made the code hard to read/write, but it was a fun puzzle and I ended up writing a ray caster (god it was slow), something akin to the game Concrete Jungle and a complete 2-player implementation of Settlers of Catan, amongst other things. Not sure if my math teacher was a fan of me not paying attention in class though.

I say 32KB, but the actual usable space was more like 20KB, due to things like 4KB for a screen buffer if you went graphics mode rather than text mode, which I did for some things and needed to do if ever actually graphing, however much if you used lists or matrices, &c. Anyway, I kept writing programs (sometimes games, sometimes useful things like automating the techniques we learned, such as a surd simplifier or a quadratic solver or a prime checker), so every so often I’d run out of space and rename a multi-letter program down to one letter to save a few bytes, or comb through a program to find ways of saving a few more bytes. I certainly spent many hours coming up with clever ways of saving single bytes. It was good fun. Even sold a few programs to other students for a few dollars if they had the necessary transfer cable. Occasionally I’d regretfully delete a program if it was no longer pulling its weight.

I definitely never tried a ray caster or anything that complex. I can imagine that taking literally hours to render a single frame, if I even coded it right.

I kept my calculator in my pencil case, so I always had it with me in classes. I think all the teachers (definitely not just maths) were pretty much resigned to me using it when I finished my work in their classes (or if I didn’t want to do it and reckoned I could get away with it). Having three elder siblings that would read books or used calculators under the desk certainly helped. One teacher complained volubly about the first couple of us for this very reason (and I was very probably worse than them), but by halfway through my schooling he said to my mother once that he always loved having Morgans in his class. This amused mum greatly. Stockholm syndrome, we decided.

I'm not into graphics/games development so that might be why, but I had never heard of Shaders (the third category), which doesn't look at all like JavaScript.

Demo: https://js1024.fun/demos/2020/12

Source code: https://js1024.fun/demos/2020/12/source

Shaders: https://developer.mozilla.org/en-US/docs/Games/Techniques/3D...

It’s WebGL.

Check out https://www.shadertoy.com/ for lots more of these demos. You can do some really amazing stuff.

It's slow AF because the smallish images are in fact much larger but shrunk and many animated on top of that. So far that page has pulled 15MB down and is still going.

Edit: up to 24.5MB now.

Edit: 34.5MB now and still going

Edit: 44.4MB and still going. It's clearly slowing down badly. I'm killing it.

The site is unusable in portrait orientation on a phone. You can't see the [X] to dismiss the pop up divs unless you rotate the phone to horizontal.

I though this is same as https://js1k.com/ it's not

Js1k closed 1 year ago.

Bad time to have your cert go bad on you.

That 'Wetlands' demo (winner in shader class) is completely borked in my browser (FF 79, Linux).

Same here, Firefox 80.0b2, MacOS 10.15.

But it's not Firefox: I see exactly the same artifacts with Safari 13.1.2. (Safari is also much slower with this demo than Firefox.)

Surprisingly, it depends which GPU it starts with, not the one it's running on. Some Macbooks have two GPUs, only one active at a time.

If Wetlands is started with the Intel GPU active, it looks fine, and continues to look fine if the GPU is switched to nVidia. But if started with the nVidia GPU active, it looks a mess, lots of colour noise, and continues to look that way if the GPU is switched to Intel.

I've checked all combinations and found the same on both Firefox and Safari. So I guess it's probably the underlying OpenGL driver. I'm relieved, this means it's not a faulty GPU :-)

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact