Geomorph Theory

*Random Crazy Person Thought of the Day: Ultra-specialized Geomorphs and Naming Conventions*

Standard Geomorph

A geomorph has 4 sides, and connects to all for sides via two entryways or “ports.” It looks a little bit like an octothorpe/hash with the center filled in (#).


Base2 Geomorph Sets

While Standard Geomorph tiles are cool, theres no way to close the system. To do this, you need to introduce the concept of a side being open (has two connecting ports) or closed (has no connecting ports).

Since there are only two options per side, we can represent each side with a binary number- 0 for closed, 1 for open. By using binary, we can now represent our tile as a four digit binary number. A four digit binary number has 16 possible states (0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, etc).  If we allow for rotation, we can reduce the total number of unique tiles needed, i.e. 1000, 0100, 0010 and 0001 can all be represented with the same one-sided geomorph by turning it.

With the addition of rotation, we can reduce our 16 down to 6 unique configurations:

0000= Sealed Geomorph
0001= One-sided Cave Geomorph
0011= Two-sided Corner Geomorph
0101= Two-sided Tunnel Geomorph
0111= Three-sided Edge Geomorph
1111= Four-sided Standard Geomorph

Layer #8Layer #4Layer #5 Layer #9Layer #7 Layer

Suppose we wanted to create store hundreds of tiles with these configurations. How would we store them? The most logical way is to create directories based on their configuration, which could be named after the binary number above. if you needed a eastern wall, you could translate it to 1011, which is simply a three-sided Edge geomorph with a 90 degree clockwise rotation. You could then snag a random one-sized edge tile from 1011/ and simply rotate it.

Base4 Geomorph Set

While this is neat, you can take it a step further with segmented geomorphs, which track the state of individual left and right ports:


00= both closed
01= first open
10= second open
11= both open

The addition of these two new states forces us to use 2 bits to represent state per side, or 8 bits total to represent a tile.


This means there are 256 different configurations for tiles. This can be reduced not only by rotation, but by flipping:

10 00 00 00 = Top left open
01 00 00 00 = Top right open (the above tile, flipped on it's Y axis)

(Also note, flipping along the X and Y axis has the same effect as rotating 180 degrees.)

00 10 00 00 = right top open
00 01 00 00 = right bottom open (flipped along X axis)
00 00 00 01 = left top open (flipped along Y axis)
00 00 00 10 = left bottom open (rotated 180 degrees)
00 00 00 10 = left bottom open (flipped along X and Y axis)


By the time you add in flipping and rotating, we end up with significantly less than 256 tiles. How much? I have no idea, the math is beyond me right now without drawing them all out. What I can say is that we can represent them with Base4 notation:

0= both closed
1= first open
2= second open
3= both open

Layer #8Layer #10 Layer #11Layer #4





This allows us to represent every tile category with only 4 digits. Looking at what we’ve represented previously:

0000= Sealed Geomorph
0003= One-sided Cave Geomorph
0033= Two-sided Corner Geomorph
0303= Two-sided Tunnel Geomorph
0333= Three-sided Edge Geomorph
3333= Four-sided Standard Geomorph

But we could also represent things like:

  • a pinwheel configuration: 1111
  • a crooked fork in the road:   0302
  • a narrow corridor  0102

PINWHEEL Layer #3 corridor

Among others.

Base8 Geomorphs

Lets take it another step- lets say that the solid center part between the two ports was changeable, essentially giving us 3 ports; three binary positions giving us a total of 8 combinations per side.

000 = all closed
001 = right open
010 = center open
011 = center and right open
100 = left open
101 = left and right open  (standard geomorph)
110 = center and left open
111 = all three open

With 3 bits per side, that gives us a total of 12 bits to represent a geomorph; If I remember my Base2 properly, that’s 4096 possible configurations (again much less with rotation and flips). We could still represent our standard configurations with only 4 digits if we use octal:

0000= Sealed Geomorph
0005= One-sided Cave Geomorph
0055= Two-sided corner Geomorph
0505= Two-sided Tunnel Geomorph
0555= Three-sided Edge Geomorph
5555= Four-sided Standard Geomorph

In addition we could create neat things like plusses, crosses, Y’s, trees, etc.

onesideelbowLayer #6 Layer #14 Layer #13

treeLayer #2 Layer #1 fatladder ladder

Base32 Geomorphs

If we wanted to take this one last insane step further, we could introduce the idea of ultra-specialized. where the 2 solid edges of each side were turned into ports. This means there are 5 binary areas (open or closed) per side, which translates to 32 configurations per side, meaning we can use base32 to encode each of the four sides with a simple four-letter code.

To this end, you could represent a “regular” geomorph side with the binary representation, i.e. 01010, which is 10 in decimal and A in base32. This means a regular geomorph tile would be encoded as AAAA.

0000=sealed Geomorph
A000= One-sided Geomorph
AA00= Two-sided Corner Geomorph
A0A0= Two-sided Tunnel Geomorph
AAA0= Three-sided Edge Geomorph
AAAA= Four-sided Standard Geomorph

So, the final tally? Five binary on 4 sides is 20 bits of data per tile; That’s over a million different variations. My brain hurts now.

Until I sat down and did the math, I thought 5bit-sided geomorphs were doable. Now I see how wrong I was.


The Key to Creating Good, Tileable Images (in GIMP)

I’m writing this as a general guide both for future reference, and to get feedback from others.

Often when using an image manipulation program such as GIMP or Photoshop, you’ll need to create large swaths of consistent texture. The easiest way to do this is with a pattern fill tool, however most programs only include a small set of patterns. The good news is that you can make your own with relatively little grief.

A quick note- While you may occasionally want an obvious tile (e.g. tiled floors), this discussion will focus on tiles that try to appear seamless.

Choose a Texture


For our example, I took a photo of the dirt outside. As you can see, it’s not perfectly uniform, but we’ll take care of that in a moment.

The first step is obviously to decide what you’d like to have as a texture- dirt, cement, gravel, treebark, marble, and leaves are all good examples of common textures. Your texture should be relatively consistent. While some variation is needed to give it flavor, it needs to be somewhat symmetric (i.e. a baseball in a tile of grass will make tiling obvious), however you may be able to cover that up.







Crop Inconsistencies


Here you can see I cropped out the large flat top right corner and dark bottom left corner. It’s starting to look a lot more consistent, however there’s still a few pesky details that stick out.

Sometimes your source picture will have an anomaly on one side, such as the edge of a sidewalk on a dirt texture, or stick in a field of grass that wasn’t quite out of frame. The simplest way to deal with this is to crop it out. Save as much as you can of the original image, but make sure to completely remove the inconsistency. Judicious cropping can also help you determine your focus- is your pattern a field of grass or blades of grass?









Remove Anomalies


Here you can see I removed quite a few wood chips, the twig, some tree buds, and a small sprout The consistency is coming along nicely at this point.

Should your texture has some type of anomaly (like the baseball mentioned above) that is too far in to safely crop, you can often use a combination of the rubber stamp tool and healing tool to copy a more generic spot over the anomaly and blend it into place.









Offset and Wrap


We were relatively lucky with the dirt; the seams are barely noticeable.

Now that our tile looks fairly consistent, lets examine the seams. For this we’ll need to offset the entire image by half (Layer->transform->offset or ctrl+shift+o) along the X and Y axis. This should give you a nice cross where the edges will meet in the final product. Quite often you will find color variation between the two sides- sometimes you can get lucky and dodge or burn the image to get them closer shades, sometimes it’s far more tricky (and beyond the scope of this document).


Using the four quadrants as a baseline, you can use the rubber stamp and healing tools to cover the seams- with any luck this process will be fairly simple and painless. Remember, the goal is to make the seams disappear, so be sure to feather it in unevenly, and not with a straight line that will still be visible.





This image should be seamlessly tileable at this point.

Once complete, we need to verify we didn’t accidentally damage leave any artifacts need the ends of the seams. To do this, do another offer, but only offset the Y by half; this may reveal a small horizontal seam near the center. Take care of that and perform a final offset, transition X by half. This should leave a small vertical seam. Once it’s resolved, you should have a nice, seamless texture… but we’re not done yet.









Unfortunately we do see some banding along the top and middle of the image; this could be corrected with some dodging and burning, but we’ll call it good for now.

Quadruple It

The phrase “can’t see the forest for the trees” applies here. We’ve seen what one intersection looks like- how about several? If we increase the image canvas size and duplicate time layer 3 more times, we can set them side-by-side and merge them down to identify redundant features that escaped us previously. Things you might see include:

  • That small twig may have been unnoticeable with one tile, but with many tiles it betrays the redundancy
  • There may have been an ever-so slight variation in color that was previously unnoticed
  • The area surrounding the original seams was not as well blended as previously thought
  • A small area that is simply too unique and sticks out just enough to be noticeable.

You have a choice at this point; you can either undo back to the single image, or choose to keep it quadrupled. If you keep it quadrupled, you can ad ever-so-slight modifications to each quadrant to help disperse the redundancy.


The final step is to export (File->export as… or ctrl+shift+e) and save the pattern as a .pat file.  This should be kept in your GIMP patterns folder (on linux ~/.gimp-2.8/patterns/)

The next time you refresh your patterns box, you should see your new texture.

Holy Cow it’s too Big!

Oh, all that work we just put in? It may be worthless; I shoulda mentioned that up front.

Here’s the problem: If your base texture is 2500×2000 pixels, don’t be surprised that your pattern is gigantic when you try to use it. As of right now, GIMP doesn’t have a built-in way to scale patterns (although there are plugins that claim to do it). Your best bet is to scale the image down before exporting it to a pat file, just be warned that the scaled image may have seams reappear from the scaling interpolation, so you may need to run through the offsets again to verify that it’s acceptable.

Final Note…

  • No, I cannot tell you how to do this in photoshop.
  • I despise capitalizing GIMP. it I understand why it’s supposed to be, but it still feels super lame.
  • If you have feedback, please leave a comment below- I’d love to improve my process.
  • If you liked this tutorial, please consider supporting me via Patreon

Fix for Sonar Breaking After Upgrade

Upgrade is not supported. Please use a production-ready database.


If you’ve ever seen this message after a yum update, you know how infuriating it can be. I was sure I was already using mysql rather than the default h2 database, but everything indicated that was the problem.


It turns out the error was caused when they replaced /opt/sonar/conf/sonar.properties with a default configuration. If you vimdiff it against /opt/sonar/conf/sonar.properties.rpmsave you should see the issue.


Let me know if this helps.

Prunecluster’s Stories, Volume 1, Part 1: Cragmaw Cave.

So there we were… Cragmaw Cave. We’d just killed a bunch of goblins and had located their leader, known only as “the big one.” The ranger peeks into the small cavern to appraise the situation, then returns to us. “There’s a Bugbear, a worg, and… a goblin in a jester outfit.”

“Whut whut?” I ask. I take my craft seriously. There’s no way the goblin is a properly trained jester. At best he does some pratfalls and slapstick. He ain’t no artist. I cannot let this travesty stand. I fly into the room alone with a series of cartwheels, leaving my fellow travelers dumbstruck. I demonstrated some dance moves and ended with a challenge.

“I CHALLENGE YOU… TO A JEST-OFF!” I spat at the ugly like hack. The worg starts to get up, but the bugbear stops him, enthralled by my performance, “Proceed,” he tells the goblin.

I bust out my iron golem dance while the goblin goes for the snake. *Pssht*, the snake. Anyone can do the snake- hell, my grandma taught me the snake. Figures that a stupid bugbear would like it better. Realising the brute only valued physical prowess and not nuance, I decided to display my acrobatic skills.  The bugbear was awestruck by my ending flourish.

“You’re fired,” the Bugbear said to the goblin, motioning to the worg, who leapt on to the goblin and ripped out his throat.

“You ready for my next trick?” I asked, and began weaving an intricate version of the Dwarven Aristocrats, with just a tinge of magic. Had it worked, he’d have been doubled over on the floor, laughing uncontrollably… unfortunately, he found dwarven culture too refined for his tastes. The bugbear grew violent, at which point I beat a hasty retreat out of the room with bugbear and worg hot on my heels. Boy were they surprised when they found my friends waiting for them around the corner…


If there’s one thing I hate more than an hack jester, it’s an ungrateful crowd.

Greatest Marketing Pitch Ever

El Monterey, I have the perfect marketing pitch for you:


Scene: Dining room table, happy music plays in the background.

Mother, father and two children walk in door carrying fast food bags

Father opens container to find a smashed, nasty, dried out cheeseburger. Music stops.

Mother opens her fish sandwich to find it swimming in tartar sauce.

Everyone appears grossed out and disappointed when suddenly there is a loud thump

Cut to  refrigerator. *thump* it moves.

Refrigerator door opens and a rainbow spin of colors comes out, revealing someone like the Katamari King. scene cuts change to an old japanese fight movie.

In his hands is a small microwave which shoots burritos out like a tommy gun.

Steaming burritos land on plates that magically appear in front of them.

“Thanks burrito overlord!” the family cheers in unison.

Camera cuts to burrito overlord who gives a two finger salute, before jumping, spinning into a rainbow and zapping back into a freezer.

Happy mexican celebration plays while the family digs in.

Text and voiceover both reinforce:

“Always have a Plan B. El Monterey.”




Curse of the Goat

I’m not sure why the idea hit me, but my brain has focused on it and it won’t let me move on until I write it down.


Curse of the Goat

When afflicted, a goat appears from nowhere and proceeds to follow you around, constantly bleating. The goat is immortal, never sleeps, and cannot be lost. It will keep you awake, give away your position, and generally be annoying. If pushed off a cliff or otherwise separated, it will reappear within minutes, often headbutting the afflicted from behind.

“Maeh-eh-eh-eht…  Maeh-eh-eh-eht.”


Curse of the Golden Goat – The only way to silence the goat is to feed it gold coins; a gold coin will by you 10 minutes of silence.

Curse of the Ghost Goat – The goat is incorporeal. Can’t be locked in another room, can’t be used to wedge a door closed, and spooks living animals.

Curse of the Silent Goat – It doesn’t bleat, it just stares at you and makes you feel bad about your life choices. Seen as an ill omen.


Google+ Comments Widget

Lets see if this cuts down on the random spam.

The Case of the Truncated Syslog Program Field

The Problem

Data was going in to my logging server and getting mangled somewhere along the line. To complicate matters,  only the windows hosts were affected, and even then it was sporadic. The truncated data was in the middle of the string, which left me to believe logstash was trying (and failing) to parse it.

To fully grasp my setup, perhaps a diagram is in order:


My wonderful pocket logserver

The flow went something like this:

NXLog -> Rsyslog -> Logstash -> Redis -> Logstash -> Elasticsearch -> Kibana

When manifested, this was spit out of rsyslog into a temp logfile:

Jul 2 10:40:25 dep1w1us001.derp.com Microsoft-Windows-TerminalServices-RemoteConnectionManager[2272]: Remote Desktop Services: User authentication succeeded: User: jesse.morgan Domain: derp Source Network Address:

And this is what ended up in rediss (note the missing bold):

Jul 2 10:40:25 dep1w1us001.derp.com Microsoft-Windows-TerminalServic Remote Desktop Services: User authentication succeeded: User: jesse.morgan Domain: derp Source Network Address:

For some reason, the middle of the line was missing!

The Culprit

With the help up my trusty sounding board Will, “Logstash guru” thegreenrobot, and nxlog dev b0ti, I was able to figure out the root cause- the problem wasn’t with Logstash at all, it was broken when rsyslog handed it to logstash. Complicating matters was when rsyslog was munging it- when it wrote the entries to a temp file, they were fine, but when it passed them to logstash, it truncated them on the way out the door.


Why? Because they’re invalid in the first place!


NXLog (the logging forwarder on windows) was collecting eventlog data and shipping it out with the full program names despite it being too long. That’s right- Section 4.1.3 of RTF3164 states:

This has traditionally been a freeform message that
gives some detailed information of the event.  The TAG is a string of
ABNF alphanumeric characters that MUST NOT exceed 32 characters.

While you could (and I still do) consider this a bug in nxlog, b0ti pointed out that fixing this bug could potentially break many stable implementations to fix an edge case. While I don’t fault B0ti for not fixing it, I still needed to work around it.

The Fix

We need to shrink down that program name to 32 characters or less before it leaves nxlog… but there’s a catch.

It’s not *just* the program name, but the PID as well that gets truncated. So we have to adjust accordingly. The msdn documentation says the PID is a DWORD, which turns out to be an unsigned 32-bit integer, which can potentially be 10 characters.  Add on another two for brackets and one for a colon and you’re already losing potentially 13 characters of the 32 characters allowed.

To help stretch our remaining 19 characters, lets see what we can axe. Most of the Microsoft processes either begin with “Microsoft_” or “Microsoft-Windows-“, which we honestly don’t need on the program name.  By removing those, we get down to the nitty gritty of the actual program name.

Since it may STILL be too long (I’m looking at you Microsoft-Windows-TerminalServices-RemoteConnectionManager[2272]:), we need to strip those off the front, THEN take the 19 character substring of what remains. The result is an eventlog input in nxlog that looks something like this:


<Input eventlog>
 Module im_msvistalog
 Exec if ($Channel == 'Security') drop(); \
 if ($SourceName =~ /^Microsoft[-_]/) $SourceName = substr($SourceName, 10);\
 if ($SourceName =~ /^Windows[-_]/) $SourceName = substr($SourceName, 8);\
 $SourceName = substr($SourceName,0, 19);


And with that, rsyslog no longer truncates, logstash can parse the string, and all is right with the world (as far as I can tell.) A big thanks to everyone who’s helped me troubleshoot this issue.



If you found this useful, please let me know in the comments.




rsyslogd-3003: error -3003 compare value property – ignoring selector

If you ever come across this message:

Jun 27 10:52:52 detc6ut002 rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="30899" x-info="http://www.rsyslog.com"] start
Jun 27 10:52:52 detc6ut002 rsyslogd-3003: error -3003 compare value property - ignoring selector [try http://www.rsyslog.com/e/3003 ]
Jun 27 10:52:52 detc6ut002 rsyslogd: the last error occured in /etc/rsyslog.conf, line 65:":programname, regex, 'ASA-[65432]-' ~"
Jun 27 10:52:52 detc6ut002 rsyslogd: warning: selector line without actions will be discarded
Jun 27 10:52:52 detc6ut002 rsyslogd-2124: CONFIG ERROR: could not interpret master config file '/etc/rsyslog.conf'. [try http://www.rsyslog.com/e/2124 ]

Make sure you’re using double quotes on your regex string.

:programname, regex, "ASA-[65432]-" ~


This took me far longer than it should have to figure out. Let me know if you find this helpful.

And For My Next Trick…

Presuming I get my Alston guitar properly set up and playable, I’d like to try building another kit. Before I do that however, I need to figure out what I’ll need.

  1. A painting booth. Lacking a proper garage, some type of enclosed booth to hang the guitar in would be ideal- This video demonstrates how to build a temporary paint booth for ~$50. That in addition to a stand of some sort that I can hang the guitar from should be sufficient.
  2. A proper painting mask. The flimsy mask I had was passable in a well ventilated area, but I should get something better before I paint again.
  3. A Drying space. I need to make preparations before hand to have a spot to let the paint dry after the initial painting.
  4. A timeline. x days for sanding, priming, painting, clear coat, assembly, etc.
  5. Sanding sealer. This will help make sure everything is smooth.
  6. Proper sanding tools. I cut too many corners rather than using a proper sanding block.

I’ll add to this list as I think of more.

The second half of the equation is finding a kit that I really want to do. With the *relatively* low prices, it’s feasible to do another once I get a place to work on it. Kits I’m currently looking at:

No favorites yet, but it’s all I could find.

Go to Top