cosmic realms

a coder blog

Hand of Cards

About 2 weeks ago I launched my new web game World of Card Games

I started working on it back in December 2011. I took a month off here and there, so it probably took about 10 months of actual full time work.

One of the toughest problems I faced was getting a hand of cards to show up nicely fanned out in an arc. You know, like you would hold them real life.

My knowledge of math is pretty limited and things like cosines and tangents are totally foreign to me.

Thus, I spent many, many days on IRC and varous websites seeking assistance and learning.

After a ton of work, I was finally able to get this demo coded correctly:

Number of Cards:13
Card Spacing:0.20
Arc Radius:400
view source code

Notice how the cards stick to the base lines, regardless of how you adjust the sliders or which direction the cards are facing (NWSE buttons at top right).

This "stay in place" concept was critical. Without that it would have been quite difficult to implement into the game.

I'd like to say I learned a lot, but that would be dishonest. I still don't really understand the mathmatical concepts in use here well enough to know when or how to apply them to future problems.

My next game will likely be WebGL based. While the game itself will be mostly 2D, I'm almost certainly going to need to learn a lot more math in order to do the things I want to do.

I am actually looking forward to it though. I've always liked math and I enjoy learning, so it should be fun.

I want to thank the folks in #math on irc.freenode.net and David Gouveia for all their help.

Custom Cursor Support Gotchas

Looking to add a custom cursor to your web page or HTML5 game?

Be prepared for some significant pain... and not just with IE.

This post details the current state of custom cursor support.
Multiple browsers are tested on Linux, Windows and Mac OS X.

The following CSS is being used:


	.pointer {
		cursor: url("/cursors/pointer.cur"), auto;
	}

	.pointerDown { 
		cursor: url("/cursors/pointerDown.cur"), auto;
	}

	.arrow { 
		ursor: url("/cursors/arrow.cur"), auto;
	}	

Note: A small glitch may occur once during each test, while the browser loads the cursor. Thus each test should be tried twice.

To run each test, simply move your mouse over each grey box.

Simple Custom Cursor

For this test, we will simply show a custom cursor.

.pointer

Results
Firefox 2, 3.6, 8, 14, 18Works!
Chrome 21, 24, 25Works!
Safari 4.0.5, 5.1.4, 6.0.2Works!
IE 9, 10Works!
IE 6, 7, 8Works, but cursor is constrained to 32x32
Opera 12.14Fails - Custom cursors are not supported

Ok, not the end of the world. If we forget about Opera and restrict our cursor size to 32x32 for IE, we can support almost all browsers.

UPDATE 2-14-2013: Opera has decided to switch to WebKit for their rendering engine. This means we will likely see custom cursor support in the next WebKit based version of Opera!

Automatic Cursor Changing

This test will automatically alternate between two different cursors.

.pointer

Results
Firefox 2, 8, 14, 18Works!
Chrome 21, 24, 25Works!
Safari 5.1.4, 6.0.2Works!
Safari 4.0.5Fails* - Never changes after the first custom cursor
IE 7, 8, 9, 10Fails* - Never changes after the first custom cursor
IE 6Fails* - Changes to default arrow on first switch and remains that
Opera 12.14Fails - Custom cursors are not supported

Fails* - If you continually move the mouse around, then the cursor changes correctly.

Basically, mouse movement is required in many browsers in order to re-draw the correct custom cursor.

There is an open issue for Chrome about this: Issue #26723
However my tests with Chrome didn't show a problem.

Change Cursor on Mouse Down

Let's try changing the custom cursor when the mouse button is pushed down.

.pointer

Results
Firefox 2, 8, 14, 18Works!
Chrome 21, 24, 25Fails - Does not change on mouse down
Safari 4.0.5, Safari 5.1.4, 6.0.2Fails - Does not change on mouse down
IE 9, 10Fails - Does not change until mouse up, then shows the default arrow
IE 7, 8Fails* - Does not change until mouse up, then shows the down version
IE 6Fails* - Changes to default arrow on mouse down
Opera 12.14Fails - Custom cursors are not supported

Fails* - For IE 8 or less, if you move the mouse around, the cursor changes correctly.

This is where things start to get ugly. The ONLY browser that supports changing the cursor when the mouse button is pressed is FireFox.

So if you were hoping to have a cursor change while the user clicks on things... think again.

UPDATE 2-14-2013: A patch has landed on WebKit that fixes the bug that prevented the cursor from changing on mouse down.
This means future versions of Chrome and Safari should both support this feature soon!

Custom Cursor With Scroll Bar

Does the custom cursor work when using a scroll bar?

.pointer

 
Results
Firefox 2, 8, 14, 18Fails - Changes to default arrow when over scroll bar
Chrome 21, 24, 25Works!
Safari 4.0.5, Safari 5.1.4, 6.0.2Works!
IE 6, 7, 8, 9, 10Fails - Changes to default arrow when over scroll bar
Opera 12.14Fails - Custom cursors are not supported

Pretty poor support for this. Oddly enough, Chrome and Safari (WebKit) are the winners in this test.
While not tested, my guess is select boxes will show similar problems with custom cursors.

Summary

As you can see, ALL the browsers have a long ways to go before you can rely on custom cursor support for something like a game.

I discovered these problems when developing my latest web game: World of Card Games

As a work around, I use a transparent 1x1 cursor and draw my own custom cursor image with an <img> tag.
On mouse move I use a CSS transform to translate the position of the <img> to the current cursor coordinates. This gives pretty good performance.

Future web games I create will be WebGL based and their cursors will be also drawn with WebGL and likely animated.

I don't anticipate browser support improving any time soon. Many of these issues have been known about for years.

UPDATE 2-14-2013: With Opera switching to WebKit and a patch landing in WebKit to fix the on mouse down bug, looks like things may be improving a lot sooner than I first thought!

Commodore 64 magazine game wallpaper generator

My first computer was a Commodore 64. I have fond memories of paging through Commodore magazines, eyes closely examining every inch of the game advertisements, dreaming of what adventures lie within the game.

About 4 months ago I came across a complete PDF collection of every Compute Gazette and Run magazine. These were the exact magazines that I grew up with as a kid.

I started browsing around the PDF's. A smile quickly came to my face. A smile which only grew larger, feeding off the fuel of nostalgia that was billowing up inside me.

After all, who could resist smiling at such classic game ads:

I wanted to feel this happy nostalgia feeling again in the future. So I decided I would create some wallpaper montages out of these game ads.

Being a coder, I certainly wasn't going to do it by hand.

So I fired up my favorite code editor (Sublime Text 2) and created a new project!

NOTE: A link to the code is located at the bottom of this post.

Step 1 - Extract the PDF pages as images

This part was pretty easy as I had done it in the past. I simply used the pdfimages program provided by the poppler package.

This produced a bunch of PPM image files which I easily converted to PNG using ImageMagick's convert program.

Extracting the pages from 187 magazine issues produced 23,079 PNG files.

Step 2 - Remove duplicates

The same game ad would often appear in multiple issues, so the next task is to elimnate any duplicate images.

Since these are scans from 30 year old magazines, we'll never have an exact pixel match, so we'll have to use a program to check similarity.

For this task I used the puzzle-diff program from the libpuzzle package.

It's a dead simple program. Feed it two images and it will give you tell you the similarity between the two. Simply compare each page to every other page and remove any that are so similar they are likely duplicates.

Step 3 - Remove non-ad pages

A majority of the pages in these magazines are not game ads. Things like articles and code listings are unwanted. Time to filter these out.

With the help of the NPM module node-histogram, I compared each pixels RGB values average and standard deviation and against some values I came up through trial and error.

This comparison told me if the pixel was 'colorful' or not. Unless a minimum percentage of pixels were colorful, the image was discarded.

Step 4 - Remove boring pages with lots of text

When I browsed the remaining images, I found numerous images that contained enough color to pass my colorful test, but were clearly not game ads:

So next I decided to use OCR to remove pages with too much text.

To do the actual OCR I used the tesseract library.

Any pages with too many words on them were discarded.

Step 5 - Final pass by hand

The scripts I coded had done a remarkable job.

They reduced the original 29,079 images to about 800.

At this point I decided to just visually inspect the remaining images to remove any remaining bad ones.

Step 6 - Constructing the final wallpaper images

At the end, I had 627 cool ads sitting in a directory.

I randomly split the images up into five directories, then used ImageMagick to scale them down and montage them into the final wallpaper images.

Each image is about 5200x5400 in size, give or take a few thousands pixels.

I wrote a script a while ago to randomly choose a wallpaper image for each of three displays whenever I log in. If the image is larger than the resolution of that monitor, the image is randomly cropped for display.

The final Commodore game wallpaper images are now part of this rotation and whenever they are chosen, I smile :)

Final Results!

Here are the final results! Click on the images for the full size versions:

Code

The code is a collection of node.js scripts that I created to perform all the tasks I mentioned above

You can find the code here: https://github.com/Sembiance/c64_magazine_wallpaper

NOTE: I haven't run the code in many months and I never intended to release it. It is unlikely to work "out of the box".

New Blog Code

So it has been almost a year since I last posted.

The main reason is because my previous blog code (Octopress) was in a broken state and after spending about an hour or two trying to fix it, I gave up.

Basically the ruby gem versions and ruby runtime version that Octopress required, were in conflict with the versions I had installed on my system. I tried using RVM, but that proved to be a huge pain in the ass.

I always liked the clean look of Octopress and that it generated static HTML files.

I disliked having to write my posts in markdown and felt it was too clumsy to write new posts and modify the blogs features/pages.

So I decided to code my own.

I did it with node.js and it took me about a day. I replicated the look and feel of the Octopress theme and kept the same URL format (so Disqus comments would carry over and RSS feeds wouldn't break).

All the code underneath this blog is open source and available here: https://github.com/Sembiance/cosmicrealms.com

Note: I didn't really make the code for others to use, so I don't really have any instructions on how to use it. I don't expect anyone to actually use it anyways :)

Now that I have a functioning blog again, I have 2 or 3 blog posts I've been wanting to posts for a few months. Those will be coming soon :)

Benchmark of node.js JSON Validation Modules

I need to validate JSON in a node.js project I am working on.

Speed is critical in my project, so I decided to benchmark several node.js JSON validation modules.

I only included modules that support the JSON schema described here: http://json-schema.org/

The following modules were benchmarked:

Two JSON objects and schemas were used, one basic and one advanced. The source code for these are at the bottom of this post.

Due to varying module support, I had to create both a v2 and v3 schema document.

Results






Conclusion

Looks like JSV is the slowest, even more so when dealing with V3 of the JSON schema. Also note that we are using a pre-processed JSV JSON schema. When that wasn't used, JSV was an additional 20 times slower.

So easy conclusion right? Use json-schema or schema as they are the fastest?

Well, it turns out that bothjson-schema and schema lack supprt for serveral properties mentioned in the spec such as divisibleBy, uniqueItems and format.

For my project I'm not currently using any unsupported properties, so I'll be choosing json-schema for it's speed.

In the future if I need to use an unsupported property, I can always just add it to json-schema myself and send a pull request :)

Modules not used

These modules were NOT tested due to each having a custom JSON schema format:

Lastly this module was also not tested because it lacks support for the 'required' attribute:

Source Code

Here are the JSON data objects and schema used for the benchmarks:

Web Traffic Time Analysis by Server, Client and Client IP

Traffic analysis for World of Solitaire shows more visits on the weekdays compared to the weekends.

I suspect that this is due to people playing solitaire from work and school. I wanted to see at what hour of the day people are visiting to see if it is during normal work and school hours.

Measuring with just the server time however wouldn't give an accurate measurement of what time of day it truly was at the visitor's geographic location in the world.

I measured each visit three different ways:

  • The server's time
  • The client's actual local time (read by javascript in their browser)
  • The client's IP address (converted to a city/time zone using GeoIP)

The data was collected over a 1 week period from Sun Oct 16 to Sat Oct 22.

Here are the visits broken down by day:

All three show pretty much the same thing. Most of my traffic comes from the states and my server is located here, so it looks like at a 'day' level, using the server time is reliable.

Let's break it down by hour:

Now this is much more interesting! It shows that measuring with just the server time is not an accurate reading of what time of day people visit.

There is a 20% drop in visits between 4PM and 6PM, right about the time people would leave work and school.

The above graph was for the entire week. What about looking only at weekdays and weekends, will we see something different?

The weekday chart shows an even bigger drop between 4PM and 6PM, 27%.

The weekend only shows a tiny 3% drop during this same period. On the weekends the traffic doesn't drop until about 9PM, bed time for many people.

It looks like using the GeoIP version of the client's IP address is an accurate way to measure the client's actual local time.

Can we also say that people are visiting from work and school? The data seems to point in that direction, but it isn't definitive proof. People may be playing from home while their significant others go to work and then stop when they arrive home.

Massive Decrease in Memory Usage With Redis 2.4

I love redis. It's blazingly fast and wonderfully atomic.

Back in December 2010 I converted the database behind World of Solitaire to redis 2.2

It's currently holding over 21 million keys and handling over 1,100 commands per second.

Over the past 9 months RAM usage has slowly been increasing as more and more keys are inserted. A few days ago I realized I was very short on available RAM and had to do something sooner, rather than later.

Before throwing more RAM into the box, I decided to try updating to redis 2.4 as I had read a blog post that it was more efficient at storing sorted sets.

I was SHOCKED at the reduction in RAM usage:

It was such a dramatic reduction, I questioned whether or not data had been lost in some way.

Comparing the same dump in both 2.2 and 2.4 yielded the exact same key count: 21,085,659

Am I really storing that many sorted sets? I decided to write some code to see how many keys of each type I was storing and what the average length of each type was.

My first attempt in node.js ended pretty quickly with a memory allocation fault with node.js, so I decided to code it in C.

Data type breakdown:

Average Length:

Over 10 million sorted sets with only 1.5 entries on average per set.

Thanks to redis 2.4, I won't have to worry about RAM for a while :)

Here is the hacky C code I coded up to gather redis key type stats:

First Post!

Over the past decade or so of coding I’ve had several coding related ideas I wanted to research or experiment with. In many cases I felt that the outcome of the research or experiment would be interestering to others. This blog will be a place where I can post the outcomes of these endeavors.

I hope they prove to be useful to someone someday :)