Retina Display, Open GL, and You!

Over the long weekend, I took some time to code support for the iPad and iPhone 4′s Retina Display into Red Nova. It was a fairly painless process, after Paul Pridham pointed me in the right direction.

If you are using OpenGL for your app on the iPhone and are using an Orthographic projection for your 2D bits, you shouldn’t have to change much of your code to get it “Retina Ready”.

Setting the View Scale Factor

First, your Open GL View class if you add the following in your init code it will tell the OS that you want to display your graphics at 960×640:

if([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")])
{
	if([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")])
	{
		self.contentScaleFactor = [[UIScreen mainScreen] scale];
	}
}

If you run your app at this point you should see the content running in the corner of the screen because your GL viewport is still running at 480×320. So that brings us to…

Setting up the Open GL Viewport

Note: If you haven’t already you may want to make a wrapper function that returns the current device scale factor. I did and it’s very useful in code that needs to properly deal with displaying your graphics at the right size.

Anyway, this is the next and pretty much final step.

Find your call to glViewport, and modify it thusly:

glViewport(0,0,usefulGetScreenWidthHelper()*usefulGetScreenScaleHelper(),
	usefulGetScreenHeightHelper()*usefulGetScreenScaleHelper());

Obviously change the width and the height to correspond to your app’s layout.

If the rest of your code sets up your projections (2D and 3D) based on 480×320, when you compile and run your app you should get glorious retina display goodness! You will of course have to adjust your 2D bitmapped assets (fonts and images) to reflect the higher resolution of the display, but the end result is that your app thinks in 480×320 (this is how Apple manages it with Cocoa Touch, as far as I can tell, amusingly enough) but displays at 960×640!

He Who Hesitates is Lost

This post doesn’t have much to do with software development, but I’d like to talk a little bit about motivation and start-ups. I’m sure most can relate (I mean about the motivation part), but it’s definitely something I’ve struggled with over the years.

To begin at the beginning, here’s a great quote relating to motivation and the origin of the title of this post:

“He who hesitates is lost. Swift and resolute action leads to success; self-doubt is a prelude to disaster.” -‘Cato’ (1713) by English essayist and poet Joseph Addison.

This is something my father used to say (well, more succinctly the first sentence), but I never really got to know him very well before he passed away. That being said, that saying has stuck with me throughout my life, and as I get older the more and more I’ve come to appreciate it. Sometimes (read: a lot of the time) I have not heeded its warning, but I really think that it’s an essential attitude to have in life in general, and especially when trying to follow your own path.

One of the biggest problems I’ve faced so far has been the so called “tyranny of choice” because all growing up I wanted to be a scientist, and that focus narrowed to Physics as I approached the end of my High School years. In the meantime I had also picked up a keen interest in computers and programming at an early age.

So I was faced with a decision. “What should I focus on?” I asked myself.

Unfortunately, I didn’t have an answer.

Part of me wanted to start a company making video games, but I felt that I probably wasn’t ready for that because most of my self-started projects would end up being too ambitious or I’d become distracted and start some other pie-in-the-sky project instead of trying to finish what I had started. Another part of me wanted to do the noble thing and pursue a career in Physics, to try and unravel the secrets of the universe. So, as a bit of a compromise, I told myself that I’d get a joint degree in Physics and Computer Science and delay making a decision until after I graduated.

So I graduated.

I was still in the same ridiculous situation.

I was too afraid to make a choice, because, “Oh god, what if I make the wrong choice?!” In retrospect, this was stupid, but stupid things happen. So I decided to get a job doing corporate software development so I could pull in some money while I sat on my hands waiting for an epiphany, or a sign, or maybe someone to come and hit me in the head with a shovel for being so ridiculous.

Another seven years or so passed of me coasting along, unmotivated to make a decision and take charge of my life. Part way through I even toyed with the idea of becoming a professional photographer, which did not help me make that decision in the least. Mind you, I would never count these years spent in university and in the corporate world as “wasted” as I did learn an awful lot about myself, computers and the world in general. That being said, I was in a rut, and sick and tired of not trying to do something about it.

So, as you may have noticed, I decided to try my hand at this video game thing. It may not be as “noble” as a career in physics, but if there’s something other than science that I’m truly passionate about, it’s computers and video games.

While many people might think it’s scary to try and start your own business, I think that at least for me, I would rather at least try and live with the potential of failure than end up living a life filled with regrets. Would you rather look back on your life and say “What if I had tried to do something exciting with my life instead of taking the easy route?” Sure I will have to look back and say “What if I had pursued a career in physics and/or academia?” but you can’t do everything at once, and I am genuinely happy and excited to be following this seemingly crazy path in life.

So, if you’re hesitating on doing something daring and exciting that you know in your heart you can do, don’t hesitate too long or you may live to regret it.

If you’re in a similar situation to me, I’d highly recommend reading the many essays by serial tech entrepreneur Paul Graham. One thing I definitely took away from his writing, that relates to motivation and doing your own thing, is the proposition:

“Economically, you can think of a startup as a way to compress your whole working life into a few years. Instead of working at a low intensity for forty years, you work as hard as you possibly can for four. This pays especially well in technology, where you earn a premium for working fast.”

I really like the idea of that, and he also talks a lot about doing what you love in the context of start-ups and working hard to make a comfortable living doing the things you love.

Mind you I’m not saying that my primary motivation in this is to get rich quick or some other malarky like that. What I’m saying is, if you can do something that you love, and turn that thing you love into a way to support yourself, then why not try and do that?

Another thing Paul talks about is not giving up, and he could not be any closer to the truth of the matter. Realizing of course that money is always an issue with these sorts of things, as long as you don’t give up, eventually you’ll succeed as long as you have good ideas and a passion for what you’re doing.

That being said, one thing that usually keeps me from doing anything too risky is that I’m a fairly shy person, though I do like to think of myself as more daring and brash than I probably am usually. However being the head of a start-up is not a place for shy people, so I am actually pushing myself outside my comfort zone on a daily basis. As odd as it sounds, I think I may be a closet extrovert. Would that be ironic? All I know is I do get a bit of a kick out of pushing my boundaries, even by a little bit, every day.

TL;DR

So, if this meandering beast of a blog post could be summed up, I think ultimately I’d like to say that you should never give up on your dreams and passions, turning your dreams and passions into your job might be scary but in the end you’ll be a better person for it, don’t be afraid to push your boundaries because you might actually enjoy it, and in the immortal words of a great physicist, trickster, raconteur and personal hero of mine, Richard Feynman:

“What do you care what other people think?”

Don’t let the fear of failure, judgment, or “what if?” smother your potential.

Don’t be lost.

Blender Export Scripts

Inspired by the idea behind iDevBlogADay I have decided to continue to blog more, as I enjoy writing and sharing useful (and not so useful) information.

Today I’m going to talk about adapting Blender for use in game development, specifically for exporting textured 3D models from Blender for use in our games.

I am assuming you know how to make Blender work and have created a mesh with a UV texture map. The problem you’re having specifically is getting that mesh out of Blender. You could of course use one of the built in exporters, but this way is more educational, also sometimes it is good to have control over the format your mesh data is stored in. The file described here is pretty basic, but hopefully this gives you enough working knowledge of Blender’s guts to use this as a springboard to create awesomer things. Another thing to take into consideration is that Blender and OpenGL use slightly different coordinate spaces, but it is not hard to work around.

Anyway, the language of choice for Blender is Python. If you like tabs, you will like Python. Much like how LISP was invented by parenthesis fetishists, I suspect that Guido van Rossum has a thing for tabs.

So, let’s get crackin’! Fire up your favorite text editor and do the following:

#!BPY
"""
Name: 'MyMeshExport'
Blender: 248
Group: 'Export'
Tooltip: 'Export a MyMesh File'
"""
 
import Blender
import bpy

What this does is tells Blender that it’s a Blender Python script named “MyMeshExport”, runs on at least Blender 2.48 (you can change this as you see fit), and goes in the “Export” group. The imports hook into a bunch of Blender specific stuff including the scene.

Next, we’re going to specify the “write” function for the script. This is what is run automatically when you choose this script to export it.

def write(filename):
	out = file(filename, "w")
	sce = bpy.data.scenes.active
	ob = sce.objects.active
	mesh = ob.getData(mesh=1)

What this does is opens a file for writing, and hooks it to out, takes the currently active scene assigning it to sce, the currently active object and assigns it to ob, and then assigns the first mesh in ob to mesh. This assumes you have selected your object before you exported, and that object only has one mesh.

Next we’ll put in how many vertexes and faces there are in our mesh into the file. This will make life easier for our file loader:

	out.write('%i Vertexes\n' % (len(mesh.verts)))
	out.write('%i Faces\n' % (len(mesh.faces)))

Next we insert vertex co-ordinates:

	for vert in mesh.verts:
		out.write('v %f %f %f\n' % (vert.co.x, vert.co.y, vert.co.z))

This goes through each vertex in the mesh and inserts “v x y z” where x, y, and z represent the co-ordinates of the vertex.

Finally we write in information for each face in the mesh, including what vertexes make up the face, the vertex normals for that face, and the UV coordinates.

	for face in mesh.faces:
		out.write('f')
		for vert in face.v:
			out.write(' %i' % (vert.index))
		out.write('\n')
		out.write('n %f %f %f\n' %(face.no[0], face.no[1], face.no[2])
		out.write('n %f %f %f\n' %(face.no[0], face.no[1], face.no[2])
		out.write('n %f %f %f\n' %(face.no[0], face.no[1], face.no[2])
		for uv in face.uv:
			out.write('uv %f %f\n' % (uv[0], uv[1])
	out.close()
Blender.Window.FileSelector(write, "Export")

This is where the per-polygon information is spat out into your file. For each face it outputs “f v1 v2 v3” where v1, v2, and v3 are the indexes of the vertexes we exported previously.

Next we output the normals. In this simple example we’re going to assign the face normals to each of the vertex normals. This is because whatever Blender thinks the “smooth” per-vertex normals are has no basis in reality what-so-ever. If you want to get smooth normals, you will have to compute them yourselves. The normals are encoded as “n fn1 fn2 fn3” on 3-separate lines (one per vertex) where fn1, fn2, and fn3 is the face normal.

Finally we output the UV coordinates of the texture map. For each vertex in the face we get “uv uv1 uv2” where uv1 and uv2 are the UV coordinates of that vertex.

The last line in the file tells Blender to open it’s File Selector window and call ‘write’.

Once you save your file with an imaginative name like ‘myfileexport.py’ you can copy it to wherever Python keeps its scripts. This is different under different platforms obviously, though you can get that information here, which incidentally I discovered after writing all this is practically identical to my post, except I cover exporting UV coordinates. Possibly because this is where I learned this over a year ago and subsequently forgot. Mea Culpa.

Anyway, let’s finish this up. So you’ve put your script into your scripts folder. Now you need to update the menus in Blender to tell it that it’s there. So you go to the Python pane and go to Scripts > Update Menus. Then you can go to your scene, select your object then go to File > Export > MyMeshExport to save your new mesh for inclusion in your game.

GameFontMaker

GameFontMaker Icon

GameFontMaker

July 9th Update: GamefontMaker is now at 1.0.0 beta 2 and it’s also been released under the GPLv2. You can find the latest version and source over here!

It’s been a while since I’ve posted anything to the blog, so I figured I’d do something a bit special to try and get into the swing of things. So, I present to you what I think may be the first native Cocoa bitmap font creation tool for games, GameFontMaker!

At least, I think it is… Maybe… I didn’t do a lot of research, but I have seen a lot of fellow iOS devs wishing something like this existed for OS X, as the only other alternative runs under Windows.

Even if it isn’t, I was getting sick and tired of my really awful bitmap font creation tool that used FTGL, SDL and duct tape and generally produced hideous bitmaps without a lot of fudging of numbers. This is much, much better than that.

Anyway, GameFontMaker is currently in “beta” so don’t come crying to me if your computer explodes or anything. Though in my defense it hasn’t caused my MacBook to explode, and it was way less stable when I started it about 12 hours ago!

This is also my first Cocoa app, so forgive me if it’s a bit rough around the edges.

That being said, if you do find a bug or have a suggestion you could always drop me an email at: colin[at]celsiusgs[dot]com.

So, you’re itching to create some decent bitmap fonts for your game? Well, GameFontMaker is pretty easy to use. From the main window:

GameFontMaker Main Window

GameFontMaker Main Window

You can select the font by clicking on the “Fonts” toolbar button, doing so updates the preview. Once you’re satisfied with your selection, click “Export Font” which opens a file dialog. Choose the file name here, it will automatically choose a .png extension. Once you make sure you’re not overwriting an important system file or your taxes or what have you, click “Save”. This will invoke an ancient spell designed to end the world (and generate fonts) and will cause GFM to spit out a PNG file with all the printable ASCII characters in a line, also it will produce <filename>.png.xml which is an XML file that describes all the character dimensions. It has the following format:

<?xml version="1.0"?>
<fontdata>
	<glyph>
		<character> </character>
		<width>7</width>
		<height>25</height>
		<offset>0</offset>
	</glyph>
...
</fontdata>

Right now the output isn’t ideal for using directly as a texture atlas, but hopefully the PNG plus the XML file can be put to some good use. Once I get some more time I will add support for defining the PNG size and altering the XML output.

Anyway, GameFontMaker is free to use for all sorts of purposes, however if you do find it useful you could always have a look at my games or maybe follow me on The Twitters. Enjoy!

Genesis

The Genesis Centre is in the Inco Innovation Building

The Genesis Centre

I just wanted to make a quick post saying that I am very pleased (and excited!) to announce that Celsius Game Studios is the latest client of The Genesis Centre. The centre is a technology start-up incubator run by Memorial University and seems to be a pretty awesome place to get my bearings as I try to develop and grow CGS as a company.

Also Chromodyne HD had a nice positive review from Simple Reviews last month, which is pretty cool! Thanks Parth!

In the meantime, my next mini-project is coming along nicely. I don’t want to say too much at this point as it’s very prototype-y but let’s just say it will involve shooting hot plasma death at evil aliens and blowing them the hell up. Oh yes.

I may have some screenshots by the weekend depending on how quickly I can finish these last few art assets to make it sexy and awesome.

Chromodyne Lite

Chromodyne Lite Icon

In an effort to try and increase the visibility of Chromodyne, I’ve done gone and created a Lite version! As it is FREE, I ask you kindly to check it out, as maybe you’ll like what you see :)

You can get Chromodyne Lite on the App Store here: itms://itunes.apple.com/us/app/chromodyne-lite/id369298294?mt=8

The Chromodyne Lite Press Release Follows:

Celsius Game Studios is proud to present Chromodyne Lite, the free version of its unique and exciting match-3 puzzle game, Chromodyne! Chromodyne Lite is available for the iPhone and iPod Touch, on the Apple App Store.

Chromodyne Lite features a brand new 5 chapter story introducing the player to the Chromodyne as they work their way through the Chromodynamic Academy’s accredited Accelerated Chromodyne Operator’s Course. Through this program, you too can learn the skills necessary to save the world from impending doom from outer space!

“Course?” You say.

“That sounds like it might be expensive…” You say.

You would say that, wouldn’t you?

Well, you might expect to pay tens of thousands of dollars and rack up years of crushing student debt at some “university” to learn how to save the world. Not so at the Chromodynamic Academy. No, you too can learn all this today for the low, low price of FREE!

Not only do you get this valuable training, but you’ll also find that Chromodyne Lite offers fun and challenging 3D match-3 gameplay, colourful and striking visual effects, and an awesome soundtrack by Kevin MacLeod.

If you’re saying: “Well, I can’t possibly go wrong with that! Plus I can’t argue with free… Especially when you put it in all caps like that!” I’d suggest you follow this link and give it a try: itms://itunes.apple.com/us/app/chromodyne-lite/id369298294?mt=8

Also Sprach Zarathustra

For shits and giggles I decided to try and emulate the opening of 2001: A Space Odyssey in Blender. I present to you Chromodyne: A Match-3 Odyssey. I think I did a pretty good job, don’t you?

With (many) apologies to Mr. Kubrick.

In other, more serious news not related to me cocking about making movies, I submitted Chromodyne Lite to Apple for approval in the wee hours of the morning. Here’s hoping it won’t be stuck there for long!

Did Not Finish

Cries of Hypocrisy Prevention Edit #2 (July 7, 2011): Due to IAP and free-to-play becoming a viable model for actually making a decent living on the App Store I have to say my previous rant just seems a bit too narrow-minded. While having a fixed price clearly still works, it is growing increasingly difficult as an independent developer to drive sales to a paid app. Free to play isn’t just a sales model, it’s an advertising model as well and it’s obviously working. Definitely food for thought, anyway.

Cries of Hypocrisy Prevention Edit (Nov 2nd, 2010): Just a note that due to the ever-evolving nature of the App Store and the whole Long Tail thing, I’m thinking there may be a place for $0.99 price points for older apps. Kinda like the PlayStation “Greatest Hits” and all that jazz.

They call it the “Race to the Bottom” on the App store, where everyone tends to price their app towards 99 cents because they feel that will compel people to buy their app because it’s so cheap. Well, I’m not so sure that is working anymore. Also with the new finish line apparently being set at $0, I think I’m going to pull out of this race.

Put a big “Did Not Finish” next to Celsius Game Studios in the Great Race to the Bottom as even if we reached the finish line, nobody is winning.

Partially inspired by this Gamasutra article “The 0.99 Problem” by Canabalt Co-creator Adam Saltsman, the huge amount of noise at the 99 cent level, and by the fact that if people want to play my games they’ll also more than likely pay a reasonable price for it, CGS games going forward will not be priced permanently at $0.99. To prevent future cries of hypocrisy I’ll state now that you may see a sale at $0.99, but at the very least that’s the new Free for a Day as far as I’m concerned.

On my part I promise I’ll continue to deliver games that are worth more than 99 cents to you, my wonderful audience.

To that end, the $0.99 “introductory sale” on Chromodyne for the iPhone and iPod Touch will be ending this weekend and as of Monday, April 12th, it will be priced at the still inexpensive $1.99.

Mark it in your calendar. Or not.

Mark it in your calendar. Or not.

Thank you for your continued support :)

Everyone Loves a Good Statistic or Two

Thanks again to David Frampton of Majic Jungle Software for providing a beta version of MajicRank with iPad chart support!

Day two has come and gone, and Chromodyne HD poked back into the (currently meaningless) category charts again during the day on Sunday. Thank you, people who bought my game, your appreciation did not go un-noticed.

As mentioned in my last post the reason these chart listings are meaningless is because there’s no way to view the Top 100 in any category for iPad apps in iTunes, and from hearsay at least, you can only view into the Top 50 on the iPad itself. Disclosure: I don’t own an iPad so I’m just going from what I heard from other people who do. Please correct me if I’m wrong :)

Let’s look at a graph shall we:

#75 in Arcade?! Exciting but meaningless.

This activity was caused by a grand total of 2 sales on Sunday. I mean, I increased my sales by 100% over Saturday, which is impressive (yay percentages!), however this still brings home a few… troubling conclusions:

1) Currently iPad developers can’t even rely on the Top 100 lists in categories to help them generate sales. This is bad for people with small advertising budgets.

2) There are quite a few games not generating any sales at all on the iPad side of the App Store currently. This is unfortunate :(

If people are still interested I’ll make the occasional post on this, but Chromodyne HD has since last night dropped unceremoniously out of the charts so I’m not sure I’ll actually be generating any useful statistics… certainly no one wants to see an empty line graph :)

In the meantime, my current plan is to keep supporting Chromodyne/HD and to forge ahead into other new projects with the hopes of making a living doing what I love while bringing awesome games into the world. Also, at least until things stabilize a bit, I think my primary target will still continue be the iPhone/iPod Touch but I will still continue to write my games with the intent of being portable to as many platforms as possible, including of course the iPad.

Until next time!

Too Good to be True (So Far)

So yesterday I started using a beta version of MajicRank by the most excellent David Frampton of Majic Jungle Software. MajicRank is a tool that scours the App Store for your apps and checks to see if they’re in the Top 100 in any of the categories on the App Store. It’s pretty awesome.

Yesterday being the launch of the iPad in the US, and I having Chromodyne HD available along with the launch of said iPad.

However, whereas the iPad launch was hugely successful, Chromodyne HD? Not so much.

Now from my frantic Twittering, you probably wouldn’t be able to tell… as for most of yesterday evening Chromodyne broke into the Top 100 in Arcade and Puzzle for iPad games. That felt great let me tell you!

Great right up until I got the daily sales summary this morning, that is! Apparently that slight surfacing into the top 100 amounted to 1 sale. Kinda sucks, hey?

I suspect the reason I’m ranking so high in those categories is that there aren’t that many games in those categories (yet) and that Chromodyne is near the bottom of the pile, but the bottom of the pile is so close to the 100 point that a single sale will do something like this. This is quite possibly also why Apple is hiding category views for iPad apps in iTunes and only showing the Top 50 on the device itself.

What sucks for me, with my currently lousy non-existent advertising budget and lack of coverage due to bigger titles getting the spotlight yesterday, is that I can’t actually take advantage of that placement in those categories. Nobody can actually see that my cool little game is in the Top 100!

I'm at the top, of the bottom!This is what excitement looks like.

It’s still early days yet and my porting of Chromodyne to the iPad was a fun experience, which effectively didn’t cost me anything except a few days of time. So I’m not upset or anything, and I wasn’t expecting miracles. There are a few pending reviews of Chromodyne so I hope they come out eventually, and that should help :)

In the meantime, I do want to thank everyone who shared my (misplaced) excitement last night, at least I can say that Chromodyne made it into a Top 100 list!