Jul 31

Some days it takes a herculean effort to force myself to sit down and work on my game. Some weeks it can be destructive to my entire schedule, while others its a complete non-issue. Overtime I’ve found prioritizing my tasks wasn’t enough to really Get Things Done. I needed a way to organize my daily tasks in such a way that would maximize my motivation to actually work that day, particularly after coming home from my day job. By taking my top priority items and then sorting them from easiest/most fun to hardest/most boring I think has helped my overall productivity.

I’ve resisted the temptation to try to squeeze in and finish off any low hanging fruit when I’m finishing up for the day and leaving it for the next session. Why? It increases the chances that I start on time the next day and get ‘into the zone’ faster for when I need to really concentrate on the harder bugs and features later into the day. It’s much easier for me to come back to an easy fix or feature. Whenever I have a really hard bug I tend to dread working on it before I’ve even sat down at the computer. Sometimes this can’t be avoided as some bugs can take days of work to finally be fixed, especially if you’re on a very limited time schedule with a day job and other obligations. I haven’t met many people who look forward to debugging some crazy hard bug when they start their day’s work. Once over the ‘hump’ when you’ve settled into just doing the easy things you can quickly ramp up and tackle the hard problems on your to-do with little fuss.

But when the day (or in my case, the night) is winding down, I try to save away some of those easy or fun 5 minute tasks for the next day to really help motivate me into starting on time. As for other tips on game development project motivation and such, instead of going into other aspects of it I’ll just link you guys to a post by Jake Birkett, of Grey Alien Games, that sums it up very nicely for indies looking to get ‘serious’ about their game development business. In particular, this bit:

I’ve run out of motivation

Well perhaps game programming isn’t for you but some other aspect of game production is? But maybe you just need to re-motivate yourself! There’s plenty of stuff about this all over the Internet. Try doing something that inspired you to make games in the first place – perhaps you need to play some of your favourite games, or boot up an emulator and play some old classics, or read some stories about other people’s success, or make a little fun minigame, or listen to some Commodore 64 tunes or Euphoric Trance music. Whatever gets you back into that space where you really want to have fun making and selling a game! Be sure to REPEAT this process whenever you feel your motivation dip.

Having a plan really helps out as you can chart your progress and see clearly what you need to do next. Also if you feel unmotivated, just START something, anything on your project and 5-10 minutes later you’ll probably be really into it.

That last bit is very important and speaks to the issues I encounter most often. For me, that ‘something’ is usually a 5-15 minute fun/easy high priority task that needs to get done. Planning this ahead of time helps as staring at a list of tasks and ‘cherry-picking’ when I’m in a state of lousy motivation usually ends up with me picking things that don’t need to get done right away and leaving more important tasks to linger on the list. Game development isn’t all fun, but with a little forethought and planning you can really help minimize the mundane feeling parts of software development.

Jul 26

I’ve had this issue in past 2D games all the time. The ability to interpolate 2D rotations for basic animations for anyone that doesn’t understand quaternions becomes a rather laborious task. I’ve done messy if-then statements to try to catch all the cases where rotation hits the ’360 to 0′ boundary and it’s always ugly and seemed like there had to be a more mathematically correct way to interpolate a circular value.

Well for anyone that sticks with it long enough, they undoubtedly run into quaternions. What are quaternions? I’m not about to explain it in detail, but I like to think of them as a way to express a 3D rotations and not having that annoying gimbal lock problem.

So how do quaternions help our 2D rotation needs? Well if you’re in a situation where you need to interpolate between the shortest path between 2 angles then Quaternions can help. You have a few choices to solve this problem:

  1. Use if-then clauses to try to catch all the cases when you hit a rotational boundary if you are rotating from, for example, 300 degrees to 2 degrees. You would want to rotate all the way through 360 instead of going backwards.
  2. Use quaternions, which are more applicable to 3D rotations, to interpolate between to angles using spherical interpolation (slerp for short).
  3. Use spinors, which are a very similar concept to quaternions, except they are more catered to 2D rotations.

You’ll eventually see that using quaternions is somewhat overdoing it as 2 axises are never used in any calculation in 2D. If you eliminate these 2 axises from the quaternion you end up with a spinor! Thanks to Frank, of Chaotic Box, who helped lead me down that direction for my own iPhone game.

To help test out the concept and make sure it’s working I ended up writing a Blitzmax quickie app using what little I know about quaternions. I’m certainly a bit iffy when it comes to dealing with complex numbers, as I don’t fully grok them as I do normal vector math, but I make do. So if anyone reads this post and sees some sort of logical error in my code, by all means leave a comment and I’ll improve the listing.

So to get started I needed a way to represent a 2D rotation as a spinor. So I created a spinor type with some basic math functions (all of them analogous to how quaternions work):

[blitzmax2]
Type Spinor
Field real:Float
Field complex:Float

Function CreateWithAngle:Spinor(angle:Float)
Local s:Spinor = New Spinor
s.real = Cos(angle)
s.complex = Sin(angle)
Return s
End Function

Function Create:Spinor(realPart:Float, complexpart:Float)
Local s:Spinor = New Spinor
s.complex = complexPart
s.real = realPart
Return s
End Function

Method GetScale:Spinor(t:Float)
Return Spinor.Create(real * t, complex * t)
End Method

Method GetInvert:Spinor()
Local s:Spinor = Spinor.Create(real, -complex)
Return s.GetScale(s.GetLengthSquared())
End Method

Method GetAdd:Spinor(other:Spinor)
Return Spinor.Create(real + other.real, complex + other.complex)
End Method

Method GetLength:Float()
Return Sqr(real * real + complex * complex)
End Method

Method GetLengthSquared:Float()
Return (real * real + complex * complex)
End Method

Method GetMultiply:Spinor(other:Spinor)
Return Spinor.Create(real * other.real – complex * other.complex, real * other.complex + complex * other.real)
End Method

Method GetNormalized:Spinor()
Local length:Float = GetLength()
Return Spinor.Create(real / length, complex / length)
End Method

Method GetAngle:Float()
Return ATan2(complex, real) * 2
End Method

Function Lerp:Spinor(startVal:Spinor, endVal:Spinor, t:Float)
Return startVal.GetScale(1 – t).GetAdd(endVal.GetScale(t)).GetNormalized()
End Function

Function Slerp:Spinor(from:Spinor, dest:Spinor, t:Float)
Local tr:Float
Local tc:Float
Local omega:Float, cosom:Float, sinom:Float, scale0:Float, scale1:Float

‘calc cosine
cosom = from.real * dest.real + from.complex * dest.complex

‘adjust signs
If (cosom < 0) Then
cosom = -cosom
tc = -dest.complex
tr = -dest.real
Else
tc = dest.complex
tr = dest.real
End If

' coefficients
If (1 - cosom) > 0.001 Then ‘threshold, use linear interp if too close
omega = ACos(cosom)
sinom = Sin(omega)
scale0 = Sin((1 – t) * omega) / sinom
scale1 = Sin(t * omega) / sinom
Else
scale0 = 1 – t
scale1 = t
End If

‘ calc final
Local res:Spinor = Spinor.Create(0, 0)
res.complex = scale0 * from.complex + scale1 * tc
res.real = scale0 * from.real + scale1 * tr
Return res
End Function

End Type
[/blitzmax2]

One caveat in the above code is that any angle from 0-360 is mapped to 0-180 in the Spinor. What does this mean? it means if I want to represent the angle 270 I need to divide it by 2, creating the spinor with the angle 135. Now when I call GetAngle() it will return 270. This allows us to smoothly rotate the whole 360 degrees correctly. This is explained here in more detail.

So now I want to spherically interpolate (slerp) between 2 2D angles. Well, if I call Slerp() on the spinor type it’ll do just that, giving me another spinor that sits in between the 2 angles. I’ve read a couple of articles in the past on slerp and how to implement it, but in order to get things done I just used a publically listed code snippet and ported it to blitzmax. That whole article is worth the read and recommended, even if you’re just using 2D.

Now that the concept of spinors is encapsulated in the Spinor type I wanted just a basic convenience function that I can feed 2 angles and get another angle out:

[blitzmax2]
Function Slerp2D:Float(fromAngle:Float, toAngle:Float, t:Float)
Local from:Spinor = Spinor.Create(Cos(fromangle / 2), Sin(fromangle / 2))
Local toSpinor:Spinor = Spinor.Create(Cos(toAngle / 2), Sin(toAngle / 2))
Return Spinor.Slerp(from, toSpinor, t).GetAngle()
End Function
[/blitzmax2]
the ‘t’ variable is the time variable from 0 to 1 that determines how far to interpolate between the 2 angles. Giving it a value of 1 means you will get toAngle out, and a value of 0 is equal to fromAngle and anything in-between is just that…in-between.

Now I can call Slerp2D(300, 10, 0.5) And get the correct angle without worrying if I’m interpolating in the right direction :).

Also, I want to point out that the above code was just used in a quick proof of concept app. It’s somewhat sloppy and to be honest, I’m not sure I named the portions of the spinor correctly (real,complex), but it works. For clarity and to save time I didn’t inline the Slerp2D functions or the Spinor type methods, so it generates a lot of garbage. You would need to optimize this to use it in a tight loop somewhere. Any suggestions are welcomed.

As for references, I did some searching and got most of the ‘missing link’ materials I needed to bridge the gap between quaternions and spinors from:

…Adios…

Jul 18

I’ve been using Subversion even as a single developer for several years now. It’s invaluable to me and millions of other developers. If you’re a developer working on any project that lasts more than a couple hours and you aren’t using version control then you are shooting yourself in the foot. As a developer, we’re comfortable with juggling several things in our heads at the same time, it’s a fundamental skill we use everyday when developing software. But when you start to do ‘internal’ version control in your head while developing you are only slowing yourself down and it will ultimately lead to lesser quality code.

Don’t think you’ll need this chunk of code, but you’re not absolutely sure? Did you just rewrite method X but you want to keep the previous iteration around as a reference? And more relevant to me: Are you making a bug fix but are mentally keeping in mind how to revert that fix in case it doesn’t work?

All of those questions are red flags that you aren’t using your version control system (if any) to a meaningful capacity. That last question came up earlier this week when I was wrapping up the first alpha build to start testing with a small group of testers for my iPhone game, Tilt To Live. I wanted to implement a new collision algorithm in the game so the higher difficulty levels would run much more smoothly. Wanting to get this right ‘the first time’ (hahah ya right, another lesson learned) I first mocked the algorithm up in Blitzmax, optimized there and debugged it there. Of course, any debugging done in a different language for a mock up is fixing purely conceptual bugs rather than implementation bugs.

The Wednesday night deadline was quickly approaching and I just finished implementing the new algorithm. I start play testing for 5 minutes. 10 minutes. 15 minutes. 20 minutes, wow the game is performing really well! 25 minutes, CRASH! WHAT?! How can this be?

So I quickly restart the game to see if I can figure out any clues as to why it is happening. 5 minutes in I crash again, but it’s still seemingly random. And the debugger isn’t spitting out any useful information to help pinpoint the bug. Knowing the only code I had introduced was replacing a call to the new algorithm I knew just replacing a single line of code would revert me back to the ‘previous version’ (this should have been red flag #1). I start debugging for hours to try to find the cause of the ‘BAD_ACCESS’ fault that is most likely coming from a null pointer somewhere in the new collision algorithm, that seems to still happen ‘randomly’.

Anyway, hours pass and then the next day I spend a few more hours on it to try to see if I can fix it before I start trying to compile an alpha build. Failure. I simply just need more time to get this fixed without releasing the alpha build with a critical bug (red flag #2).

In the end, I had to revert to the slower n-squared collision algorithm for the alpha build. Using SVN, it was trivial to revert back to the previous version, quickly test it, build, and release. Yet, there is a much better process to avoid this very time-sensitive issue of getting bug fixes into a build without compromising the stability of the build. It’s called branches.

Now, I’m no stranger to branches, as I use them to catalog releases, but to incorporate them into my daily development routine is new and is something I’m going to try to implement to avoid this issue in the future. Jeff Atwood, co-creator of StackOverflow.com,  has a rather good summary of different branching patterns for on-going development. As a single developer I’m going to try to adopt the ‘trunk is sacred’ (Branch per Task) method and try to merge features into it from development branches.

What’s the benefit? Always being able to release something that is relatively stable regardless if you’re in the middle of something or not. And you don’t have to worry about ‘auxiliary’ changes you made leading up the current fix that may also break the build. I’m finding that as I draw closer to a more complete game, I need to be able to release builds on a weekly or bi-weekly basis for testers to play test. Knowing that there is some glaring bug that is a showstopper is a head ache for you and your testers.

I’ve been researching different version control systems outside of SVN to see if there’s something that could make branching and merging more seamless and integrated into my work-flow. I’ve found that distributed control systems such as git, and Bazaar, supposedly make this fast and easy. Although,  I’m not ready to give up subversion yet; mainly because it is working. But I may test those systems out in the future for smaller projects. TortoiseSVN’s merging dialog can be a little more clearer, as it stands now it is rather confusing the first time you use it. I’m currently testing out Versions (Mac Only) since I’m developing mostly on the Mac for the iPhone game, and it seems to be a little more intuitive in branching, but can’t comment on merging yet as I’ve yet to look into it.

And now I’m off to enjoy the rest of my weekend :).

Update: Looks like Versions won’t suit my needs. Neither will Cornerstone. SyncroSVN Client seems to support basic things like switching, merging, and branching while the other more ‘fancy’ looking apps don’t do anything beyond committing/updating/branching. Except that SyncroSVN’s GUI isn’t any easier than the command line for merging/switching. Looks like I’m going to the command line or revert to using Tortoise SVN (on windows) for the time being while these Mac apps sort themselves out and mature a bit…

Jul 13

wxMaxThe title of this article says it all. I’m currently working on the next ‘iteration’ of Gunstyle with a fellow developer and over the past weekend we were in need of a GUI library to help develop our map editor. In the past maxGUI ‘worked’ more or less….emphasis on the less. The design of maxGUI left me with a bad taste in my mouth. It’s a procedural library that is cobbled together with some weak OO on top that didn’t provide much flexibility (not to mention it wasn’t exactly ‘native’ UI on different platforms). Either way, it was a good library for small projects and prototypes.

Now we’re working on something of a little bit bigger in scale, and needing a more heavy duty gui library to go with it. So we chose Brucey’s wxMax GUI Module for Blitzmax. Just picking it up over the weekend has been a joy to work with. It’s object-oriented from the get go so it’s a bit easier to integrate into already established OO code.  It also boasts being cross-platform (Win/Linux/Mac), but I’ve yet to test or need this functionality yet. It’s also wrapping a rather solid and established library, wxWidgets.

One of the main requirements was for us to develop a GUI around a game framework that would allow us to switch in and out of an editor on the fly. To test this type of functionality I whipped up a basic test file that switches from the standard Blitzmax graphics window to a wxMax GUI with a GLCanvas and back again several times. Below is the actual source for doing that type of switching, in case anyone wants to do something similar:

[blitzmax2]
SuperStrict

Framework wx.wxApp
Import brl.glmax2d
Import brl.standardio
Import wx.wxFrame
Import wx.wxPanel
Import wx.wxGLCanvas
Import wx.wxglmax2d
Import brl.max2d
Import wx.wxTimer
Import brl.pngloader

Global app:TestApp = New TestApp
Global imgTest:TImage
Global imgPath:String = “myTestImage.png”

SetGraphicsDriver(brl.GLMax2D.GLMax2DDriver()) ‘ needed in order for the normal gfx driver to run
SetGraphics(Graphics(800, 600)) ‘ set context back to main window

‘ test switching between max2D and wxMax
‘ while loading an image that is shared between the two modes
If FileType(imgPath) = 0 Then
Notify “invalid path for image. file does not exist”
EndGraphics()
End
End If

imgTest = LoadImage(imgPath)
SetBlend(ALPHABLEND)

RunBmaxGraphics()
app.Run()
RunBmaxGraphics()
app.Run()

Function RunBmaxGraphics()
SetGraphicsDriver(brl.GLMax2D.GLMax2DDriver()) ‘ needed in order for the normal gfx driver to run
SetGraphics(Graphics(800, 600)) ‘ set context back to main window
While Not(KeyHit(KEY_ESCAPE))
Cls
If KeyHit(KEY_D) Then
Exit
End If
DrawImage(imgTest, 100, 100)
Flip
WEnd
EndGraphics()
End Function

Type TestApp Extends wxApp
Field frame:wxFrame
Field panel:wxPanel
Field canvas:TMax2DCanvas

Method OnInit:Int()
frame = New wxFrame.Create(,, “Test”, 0, 0, 1024, 768)
frame.Center()

panel = New wxPanel.Create(frame, wxID_ANY, 160, 0, 1024, 768)
canvas = TMax2DCanvas(New TMax2DCanvas.Create(panel, wxID_ANY, GRAPHICS_BACKBUFFER | GRAPHICS_DEPTHBUFFER, 0, 0, 1024, 768))

frame.Show()

Return True
End Method

End Type

Type GLFrame Extends wxFrame
Field canvas:TMax2DCanvas

Method OnInit()
canvas = TMax2DCanvas(New TMax2DCanvas.Create(Self, -1, GRAPHICS_BACKBUFFER | GRAPHICS_DEPTHBUFFER))
ConnectAny(wxEVT_CLOSE, OnClose)

End Method

Function OnClose(event:wxEvent)
GLFrame(event.parent).canvas.timer.Stop()
event.Skip()

End Function
End Type

Type TMax2DCanvas Extends wxGLCanvas
Field timer:wxTimer

Method OnInit()
SetBackgroundStyle(wxBG_STYLE_CUSTOM)
timer = New wxTimer.Create(Self)
wx.wxglmax2d.GLMax2DDriver().SetBlend(ALPHABLEND)
timer.Start(100)
ConnectAny(wxEVT_TIMER, OnTick)
End Method

Method OnPaint(event:wxPaintEvent)
Render()
End Method

Method Render()
SetGraphics CanvasGraphics2D(Self)

Cls
DrawImage(imgTest, 100, 100)
Flip

End Method
Function OnTick(event:wxEvent)
wxWindow(event.parent).Refresh()
End Function
End Type
[/blitzmax2]

The main benefit of the above setup is seen in the switching between ‘RunBmaxGraphics()‘ and ‘app.run()‘. I can switch from my normal game logic, to an editor logic, but still use the same rendering routines! Now I’m not 100% positive that resources such as TImage will persist after a graphics change (in my case they do, but I don’t think that’s universal) so you may be required to reload textures.

Jul 11

I just recently got back from the “Video Games Live!” concert. In short, it was AMAZING. If they are performing in your local area, no, your state I highly recommend you take the effort to make it to one of their shows. It’s an all day event of games, contests, and meeting other gamers that’s capped off with a fun and amazing performance.

Jul 11

I’ve settled into my new apartment and job and trying to get a decent schedule for working on my different game projects. For now my iPhone game is my ‘main’ project which I spend Monday through Friday working on in the evenings. Weekends I devote to side projects such as Gunstyle. Trying to make progress is getting increasingly harder as my time has become extremely limited to about 1 maybe 2 hours a night during the week. Trying to debug a complex issue in 1 hour is usually not possible for me. And the constant stopping/starting between 1 hour sessions a day apart really hurts productivity when trying to run down a difficult bug. In the end I’m still making progress at least, though a bit slower than a few months ago.

Cutting the Fat

Since I’ve moved I’ve kind of been borderline obsessed with planning, time management, and scheduling. Just a couple of things I’ve come across over the last few weeks that’s helped me:

  • When planning a development schedule for your ‘free time’ in the evenings, take how many hours you think you have to dedicate to a project and cut it in half, if not more. I’ve found that while there’s a 3-4 hour window of time it for me to do work, 2 of those hours are typically eaten by a) random phone calls from family/friends b) my cat c) misc chores that need to get done d) laziness.
  • Remove garbage from your life and daily routine. Over the past couple of weeks I’ve been very aggressive in stopping habits that simply waste time, or cutting back significantly on a lot of things.
    • TV? Cut. Only time it’s on is in mornings while eating breakfast.
    • RSS feeds? I’ve cut most of the spammy, useless news/time-waster ones. Every couple of days I scan my list and if I find a feed that I’m simply constantly putting aside from reading then I deem it not important enough to follow and it’s cut.
    • Games? Sadly, yes :<. My Xbox 360 currently isn’t even hooked up. On the weekends I play quick games of QuakeLive, DeFraG, Tribes 2, or any other multiplayer game. I choose multiplayer because the investment isn’t long term (like a 40-hour epic single player game) and it’s easy to ‘unplug’ from the game and any commitments to it.
    • THE REST OF THE FUCKING INTERNET. I’m still bad at this, but improving. If AIM is on or I stumble on a somewhat interesting link it becomes a HUGE time sink. When you are working on a project with extremely limited time the internet is your sworn enemy.

So in essence, as an indie developer with a day job I think an argument can be made that your most important asset is your time. Being a one man crew or a small team, you are working under very tight constraints and you constantly have to be on the look out for creating a more efficient production schedule. I have some nights where literally every minute counts because not finishing off a feature that night essentially means another day lost to that feature.

Estimating And Scheduling Times

Another issue I’ve come across lately is when it comes down to actual implementation details and estimating how long a feature will take to implement, I tend to draw a blank. Before, when I was on a less ‘strict’ schedule in college I would just work ‘until it was done’. Now with me working with a little more urgency and trying to put together weekly development plans it’s become an ever increasing problem. From the past couple of months here is what I gathered and hopefully may help someone else:

  • Take a task or feature and determine if it’s something you can do in one sitting. If not, break it even further down unil you think a single item can be done in one sitting/session.
  • I find that I over-estimate my coding abilities A LOT. My main flaw is I greatly under-estimate the time needed for debugging and optimization. I tend to finish the initial implementation of features fairly quickly, but then I spend the next 90% of the time debugging, optimizing, or tweaking it. And since this is usually not in the same session, I have to spend time reading my own code to get back up to speed on where I was prior to leaving it. I now take this into account when planning my weekly goals.

This post is pretty much an obvious ‘duh wtf’, but getting some of it into a list may help a few trying to find things to create that extra 30-minutes or hour so they can get just a tad bit closer to finishing their own game :). Adios.