Video about Edge Not Found for FreeCodeCamp! + Transcript

March 20, 2021

Full dis­clo­sure: I won a year of Code­Pen Pro as part of the prizes from js13k.

Level 301 of Edge Not Found.

A cou­ple of months back I was approached by Ania Kubów, who has a YouTube chan­nel ded­i­cat­ed to JavaScript tuto­ri­als. She want­ed me to con­tribute to a video for FreeCode­Camp show­ing of the top 20 entries of this years JS13K, by hav­ing their devs show and explain some cool bits of code. As Edge Not Found man­aged to get 2nd place, I fig­ured I should actu­al­ly record and voice this video myself (some­thing I don’t often do online). My code exam­ple is about how I ren­der the same lev­el seem­ing­ly infi­nite­ly across the screen, which you can find on Code­Pen here.

My part start at 9:12 in the video, but I’ve also pro­vid­ed a tran­script with images of my part in the video below. I hope it is use­ful to someone!


Hel­lo! I’m Tom Her­mans, I’m a Dutch devel­op­er who also makes video games some­times, and for this year’s 13K jam I made “Edge Not Found”. It’s a puz­zle game in an infi­nite­ly repeat­ing world. I real­ly like tile-based box push­ing games like Sokoban, and I’ve already made sev­er­al of them, but this one is prob­a­bly my most com­plex one yet. I’ve been sit­ting on the idea for this game for a while, and the jam was a good oppor­tu­ni­ty to devel­op it and design some cool puz­zles for it.

So let’s talk about the ren­der­ing for a bit. Each frame in the game is drawn using three steps. In the first step I cre­ate mul­ti­ple can­vass­es that serve as sprites for the var­i­ous puz­zle ele­ments, like walls and box­es. These are drawn using the rough library, which gen­er­ates nice, hand-drawn look­ing shapes. 
The sec­ond step ren­ders the cur­rent puz­zle state using these sprites, like this, then final­ly, it’ll draw this lev­el repeat­ed­ly to fill up the entire game can­vas. I real­ly like the bit of code that han­dles this, so today, I’ll explain how this infi­nite­ly wrap­ping world works.

For demon­stra­tion pur­pos­es, I’ve pre-gen­er­at­ed a lev­el image from the game instead of gen­er­at­ing one from scratch, to keep it sim­ple. Now then, I have iso­lat­ed the code in this sam­ple. I’ll go over the most impor­tant bits, but if you want to toy around with the full thing, you can access this exam­ple with this link. So let’s go through it!

Rendering magic

The core of the tiling mag­ic hap­pens here, with the x and y offsets:

These essen­tial­ly affect how the lev­els are tiled. For exam­ple, if you’ve played the game you know this lev­el can’t be solved, since the crate can’t get to the goal:

But if we change the y off­set to 2, the lev­el becomes a straight line, and the puz­zle becomes solv­able. It’s kin­da com­pli­cat­ed, but it is used in lots of tricky puzzles!

Next, we cal­cu­late how much lev­els we can fit onto the screen. The clipoff­set here adds a small mar­gin to the lev­el bor­der. But it also shows that the code works by putting it to a neg­a­tive val­ue*, then if I resize the screen you can see that lev­els are no longer drawn near the bor­der of the screen. This makes sure that noth­ing will be drawn if it near­ly or com­plete­ly invisible:

Final­ly, a nest­ed FOR loop actu­al­ly draws the lev­els. Note that lev­els fur­ther away from the cen­ter will get more trans­par­ent. So if I zoom out all the way, you can see it will go on for a while, but even­tu­al­ly the wrap­ping will no longer be visible!

When draw­ing the image with an off­set defined, we shift the image on the grid. So, if I enable the coor­di­nates dis­play, you can see that the image also shifts two tiles down for each step on the x axis, and that’s due to the lev­el­Off­se­tY I set earlier:


And that is it! Once again, you can view this code snip­pet here. Do con­sid­er play­ing Edge Not Found first if you haven’t, so you can learn how this lev­el wrap­ping is used for tricky puzzles.
So, I hope this inspired you to make your own infi­nite worlds! If you liked this, then you can find me as Auro­r­i­ax on Twit­ter for more of my things, and if you look that name up on GitHub you should also be able to find the full source code of the game. Bye, and thanks for watching!

  or subscribe here!