I’ve been reading Anna Anthropy‘s Rise of the Videogame Zinesters
and I just came across what (to me) may be the most important message in the entire book.


Perfection isn't a useful goal; if anything, it keeps amateurs
from getting their feet wet and authors from finishing their works.
- Anna Anthropy. Rise of the Video Game Zinesters. Page 125. 2012 ed.
I cannot agree more. When I met my wife and she was getting to know me, I told her “I make games”. That wasn’t entirely true. What I should have said was “I try to make games” because my struggle for perfection constantly got in the way.
I thought there was one right way to make games, and because I didn’t know the way that I should not even try. I abandoned every game I tried to make.
It wasn’t until the last few years that I finally understood that there is no one right way to make games. That the best way to make games is just do it. Give up on perfection. Expect to make mistakes. Use bubblegum and duct tape to piece your game together and cover it up in attractive gift wrap.
People don’t see your engine (the source of my anxiety, the fear that my coding abilities would be criticised). They only see your game. Don’t try to be perfect, just make something to the best of your ability. You’ll surprise yourself.
Just a quick example of serializing and deserializing a series of strings.
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class GEncode {
String serialize(List strings) throws UnsupportedEncodingException {
String serialized = "";
for (String s : strings) {
serialized += URLEncoder.encode(s, "UTF-8") + "&";
}
return serialized;
}
@SuppressWarnings("deprecation")
List deserialize(String serialized) {
String[] strings = serialized.split("&");
for (int i = 0; i < strings.length; i++) {
strings[i] = URLDecoder.decode(strings[i]);
}
List list = Arrays.asList(strings);
return list;
}
public static void main(String[] args) throws UnsupportedEncodingException {
List strings = new LinkedList();
strings.add("Old & New");
strings.add("Once upon a time!");
strings.add("Yes, there is a monster in the closet");
strings.add("Another string? Why, I don't mind if I do!");
strings.add("She said \"Yes\"");
for (String s : strings) {
System.out.println (s);
}
GEncode g = new GEncode();
String s = g.serialize(strings);
System.out.println ("\nSerialized:\n" + s + "\n\nDeserialized:");
List newStrings = g.deserialize(s);
int i = 1;
for (String ns : newStrings) {
System.out.println (i + ": " + ns);
i++;
}
}
}
Output:
Old & New
Once upon a time!
Yes, there is a monster in the closet
Another string? Why, I don't mind if I do!
She said "Yes"
Serialized:
Old+%26+New&Once+upon+a+time%21&Yes%2C+there+is+a+monster+in+the+closet&Another+string%3F+Why%2C+I+don%27t+mind+if+I+do%21&She+said+%22Yes%22&
Deserialized:
1: Old & New
2: Once upon a time!
3: Yes, there is a monster in the closet
4: Another string? Why, I don't mind if I do!
5: She said "Yes"
A very minor update, barely worth mention.

You’ll notice the entire wall segment is enclosed in the radius around the ‘player’, that yellow circle at the center. The significance here is that the top-left point of the wall segment isn’t included in the list of accessible nodes! Why not? Because, the player can’t see that node (it’s on the other side of the wall segment). Another good thing in the image above, the yellow dot is flush with the two red nodes meaning it has the same x-axis as the node to its left and same y-axis as the node above.
It’s all theory, but I believe I’m close to achieving my goal. A little recursion to jump from one point to every other point in its line of sight, adding together all the places that the orange ‘light’ can shine on, and I should finally have my map of accessible areas. Remember, it’s the idea of having a string anchored to a location, and then mapping out only the locations that the tethered string can reach.
It’ll all become clearer when I get it working. You’ll see.
Trying hard to figure out an efficient way to do the following:

And so far, only coming up with something like this:

Imagine a thread of fixed length N stuck to a location on your desk. Now picture a coffee cup in the path of that thread. Now fill in only the area that the thread can reach.
I’ve tried to work it out on a whiteboard but that was only getting me so far with the subject. Now I’ve got a hunch that if I iterate (and recurse) the points within the line-of-sight from the closest to furthest points from the player that I can calculate the accessible region based on the player’s position, and how far the player can move (the length of the thread).
That brings me to Comparators. In PHP there’s a handy function called usort. It takes an array for the first argument, and the name of a function as the second argument. The function as a second argument is one usually written by you, the developer, to tell usort how to compare two elements in the array.
In Java you can accomplish usort via the Comparator interface which usually works out to something like the following:
int compare(a, b) {
if (a == b) return 0;
return (a < b) ? -1 : 1;
} |
In this case I’d compare Point objects and sort them from closest to most distant locations from the player. For reference, this page was informative enough to show how to create and use your own Comparator.
This weekend I finished version 2 of the LOTRO Craft Assist. Changes include:
- Recipe list filter
- Full stack button
- Reduced AJAX
The filter, as you expect, narrows the list of recipes down to whatever you’ve typed in the filter box. Typing “cup” will shrink the list down to: Cup of Red Tea, Cup of Spring Barley Flour, etc, cutting out the items that don’t have the “cup” in its name.
The quantity box, used to find the cost of a specified number of items, now loads with the value 50 which is usually the size of the stack when dealing with cooked food. Likewise, a “Full Stack” button is present which, when clicked, resets the quantity box back to 50. I’ll be storing the actual stack size of items in a future release so it’ll no longer default to 50 but rather whatever the actual stack size is.
The first version was written from the ground up in Javascript. That was all fine, and a fun exercise, but it was impractical. When your local internet connection was slow, sometimes the recipe list or individual recipes failed to load. Now the entire catalog is loaded once, reducing bandwidth limitations.