I recently fell into a bit of a rabbit hole with equirectangular projections. They’re a way of mapping the surface of a sphere onto a single image. That can mean unwrapping a ball-like object like the Earth to make a map, but can also be a way to map 360 degrees of an environment to a single image that’s much more readable than say six separate images (as in cube maps).
A side effect of the equirectangular projection being easy to understand is that you can use it to hand-draw virtual spaces. It’s a little tricky to get the hang of though, so having a nice guide definitely helps. To that end, I’ve made a tool using JS that generates an equirectangular grid in a light blue, suitable for printing out and drawing on top of.
See it for yourself here. Right-click on the image to save it, or download one of the PDF versions.
This was a project to generate a 3d printable dungeon using OpenSCAD. To play the game, the player uses a screwdriver or similar to break away parts of the printed model, revealing additional information.
The result has multiple layers stacked on top of each other, with the bottom layer (red) consisting of the maze pattern, the middle layer (green) supporting iconography for things like monsters, and the top layer (blue) being the door. Both the blue and green layers break away.
To see a playthrough of an example level, check out this video:
This was a project to create procedural flowers using pure WebGL. All of the geometry and textures are generated via code, and the only external library used is glMatrix. The flowers are also generated using a seed derived from lat-long coordinates, so specific flowers can be generated for specific locations. To see it in action, head here.
Development Process
Step 1: Flat leaves The project happened over the course of about a week and a half. I started by generating flat, 2d versions of leaves:
I started by implementing Bezier curves, then using two cubic curves to set the shape of the leaf edge and generating faces to fill in the contents. I also set up a simple shader to have the center of the leaf be a bit red, fading to green at the edges. See this version head here: http://www.adrianherbez.net/glflower/01/.
Step 2: 3d Leaves Once I had the basic 2d leaf working, it was time to add additional cubic curves to make it bend backwards along its length as well as to curve gently away from the spine of the leaf.
Step 4: Expanding leaves to petals, normals At this point, it was time to move onto the flower itself. I refactored the code for the leaf to be more general, making it a general class for creating geometry from sets of curves (XY, XZ, and YZ). By changing the curves, it was easy to go from pointy leaves to more bell-like petals.
I also added in proper normal calculations for the faces, which also meant writing a normal shader for easy debugging. All of the geometry is rendered double-sided, with one side rendering with the normal color and the other either red (for petals) or green (for leaves). See this version here: http://www.adrianherbez.net/glflower/04/
Step 5: Lathed Geometry In order to create the central part of the flower, I created a LathedGeometry class that could take a curve and spin it around the Y axis to generate a sealed piece of geometry.
Step 6: Putting it all together Now that I had all of the parts I needed, I put it all together into a full flower, with a stem, leaves, a central element, and petals.
The colors look a bit crazy, but that’s because I was still using the normal shader as a diagnostic. It makes a lot more sense if you see it moving- to do that, head here: http://www.adrianherbez.net/glflower/06/. Moving the mouse in the canvas will change the angle of the flower (added that in to make it easier to see what was going on).
Step 7: Colors! With all of the geometry in, I started working on better colors for the shaders.
Step 8: Lat-long based seed values Now that the flower was close to done, I turned my attention to adding support for a lat/long-derived seed value.
Once set, the same seed is used for all the randomized generation, allowing any place in the world to have its own unique flower. At this point, the colors were still always the same though. See it here: http://www.adrianherbez.net/glflower/08/
Step 9: Finishing Touches I was pretty happy with things at this point, but added a few things here and there to provide some polish, namely: – randomized colors for the petals – modification of the leaf shader to have stripes on the underside – changed the background color to a nice medium gray
I’ve been a huge fan of logic puzzles since I was a kid, and for a long time I’ve wanted to try my hand at building a system to generate them.
This represents the first pass of such a system- a puzzle is generated, along with 16 clues, pulled from four different types:
Assertion Clues that state that two things are linked (“Alice ordered a burger”)
Negation Clues that state that two things are notlinked (“Alice did not order a burger”)
List All Clues that give one fact for each component of a solution (“The four people were: Alice, the person that ordered the steak, the person that ordered a beer, and the person from New Orleans”)
Either / Or Clues that generate two facts, one true and one false (“Either Alice ordered a burger OR the person from New Orleans ordered a steak”)
I’m pretty happy with what I have so far, though the big missing feature is that there’s no guarantee that a given puzzle is solvable with the clues given. For that, I plan on approaching things by starting with all the possible values, and trimming things away as clues are applied. Once there’s only a single option for each value, then the clues are sufficient.
There’s also a huge amount of room for improvement with respect to the way clue text is generated, so that’s something I want to improve as well. The ultimate goal with this is less about just generating puzzles and more about building logic puzzles into other kinds of games.
To play with it yourself, head here. Note that at present, the generated image is meant to be printed, rather than solved online. That’s mainly because this incarnation is more about puzzle generation (for later inclusion in other projects). Also note that the solution is printed upside-down at the bottom of the page.
I spent some time recently diving into noise generation, which is something I’ve previously taken for granted. As part of that, I ended up putting together a simple 2d noise generator. The code isn’t particularly optimized or well-structured, as this is just a stepping stone on the way to bigger things. I was pretty happy with the results anyways though, so I’ve put the current state up. See if for yourself here.
I picked up a few of the books, and absolutely love them. When I gave my girlfriend’s niece her copy, we couldn’t find the required three dice to play. So I whipped up a quick little JS canvas project to roll three D6s. Once I had that working, I went ahead and added some logic to draw the various options available to the player according to the Honeycomb tavern rules.
To use it for yourself, head here. Reload the page to get a new result.
This is a small game prototype I created over a few evenings, based on classic “knights and knaves” type puzzles. The player is presented with three characters, one of which is guilty. Each of the bots either always tells the truth (a “knight”) or always lies (a “knave”).
The player is tasked with parsing the various statements to figure out who the guilty party is. Clicking on a bot to make a guess not only reveals the culprit, but also color-codes all the statements for red (lies) or green (truths).
For video of it in action, head here. Or, to play it yourself, head over here.
This was the fourth Puzzle Keepers puzzle I created, this one on the occasion of my nephew’s 7th birthday. In this, I introduced an antagonist faction- the Knowledge Containment Initiative (KCI), as a sort of bureaucratic and vaguely fascist foil to the open nature of the Puzzle Keepers. The backstory for the puzzle was that a set of papers (“Folio XIII”) that had long been in the possession of the PK had been stolen by Knowledge Containment agents. The pages were blank, but both groups had good reason to believe that there was invisible writing that could be revealed by applying the proper substance.
KCI scientists worked at the problem, and were getting close. But luckily for our heroes, the information was liberated from a KCI facility and returned to the PK. However, since KCI is so committed to containing information, it was stored in an unconventional manner, on a series of slides. A KCI device for reading the slides was obtained as well, though it was unfortunately not in working order.
So, the puzzle had three components:
First, the machine had to be repaired.
Secondly, the machine could be used to read the slides.
Lastly, the information so obtained could be used to solve an online component and reveal what was written in Folio XIII
Lately, I’ve been working on a system to display virtual books in a browser as fully 3d objects using Three.js. While there are still lots of things I want to add, it’s finally at the point where I feel like it’s worth sharing.
The system loads data from archive.org and uses it to create a 3d model of a book. The book can be opened, and pages can be flipped, allowing the user to read the entire contents. The current iteration is hard-coded to load just one book (The Wizard of Oz), but I’ll be expanding it to pull from the rest of the Internet Archive’s extensive collection.
All of the geometry is procedural, allowing for books of any size and proportion. The texture used for the cover is also procedural, allowing for any color of book, and for proper rendering of title and author along the spine.
This was a quick little one-evening project where I challenged myself to grab a sprite set off of opengameart.org and do something fun with it.
I ended up grabbing a really awesome sprite sheet of pixel art pipes, and implementing a simple drawing app that lets you draw with pipes, and updates the pipe images as necessary based on the number of inputs to each cell.
Nothing too complex going on here, but a fun little experiment, nonetheless. To try it for yourself, head here.