Tap Zoo, the game that punishes you for not playing

I haven’t played Tap Zoo for a while, I was hoping I would eventually reach the max level limit to see what happens to the content with these kinds of games, however I eventually gave up, Smurf’s I gave up on a few month ago after I missed collecting crops and would have needed to harvest 40+ crops only to replant them.

Tap Zoo I logged back in to find out that it punishes you for not playing. Any animals you were breeding will become sick and the only way to free up the slot is to pay for stars.

Back at the beginning of the game you were given stars on level up, however after about 10 levels that stops. What a bunch of idiots, you do not punish people for coming back to a game, you’re suppose to reward them to keep them back.

A recent new called call Tiny Tower is starting to take over the top of the top grossing charts. The reason, in my opinion would be the fact you do not have to pay to gain the ingame bonus tokens, you just need to play.

The more often you play, the faster you will accumulate money, and you gain actual iOS achievement as well.

It also reminds me of SimTower, which is how I came by it in the first place. Just like all these Facebook games, it have little tasks to gain you small amounts of currency as well, delivering people to floors. These not only give you money, but give you people to rent apartments so you can give them jobs.

Occasionally, VIPs will turn up that will knock off time for restocking, building, and increase people arriving at your stores to buy things. As I have said previously, the key to making a successful Facebook game, is to make a game that works like an ordinary game but you do not have to play as well.

EVE Online uses this formula.

iOS Multithreading OpenGL

LEGO Vashta Nerada
LEGO Vashta Nerada

I’ve been meaning to do this in my engine for a while, but just never had a time.

Multithreading in OpenGL is simple enough as long as you are not accessing the same object as something on another thread.

In my case, I’m only using it for my loading thread so I will not be accessing any of the objects created until loading is complete, and I will not be rendering on the separate thread either, at least not yet, I could use it for render targets.

So first of all, the creation of a OpenGL context on iOS. The examples I’m writing here are just simple main() loops so simplify what has to be done.

int main()
{
	EAGLContext * mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
 
	// Make context active for this thread
	[EAGLContext setCurrentContext:mContext];
 
	//
	while( 1 )
	{
		// do some rendering
	}
 
	//
	return 0;
}

Simple enough, this code most people who have written any iPhone OpenGL apps will recognise, it creates an ES2 context and bind it to the active thread.

However, now we want a separate thread that does OpenGL commands. We could use the same context, but a call binding a buffer on one thread could override to bind on the other causing invalid or wrong calls, so we would need to synchronise the threads.

Instead we create a second context that shares objects with our first one.

//
//
EAGLContext * mMainContext = nil;
EAGLContext * mThreadContext = nil;
pthread_attr_t mThreadAttributes;
pthread_t mThread;
 
//
//
int main()
{
	mMainContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
	mThreadContext = [[EAGLContext alloc] initWithAPI:[mMainContext API]
					       sharegroup:[mMainContext sharegroup]];
 
	// Make context active for this thread
	[EAGLContext setCurrentContext:mMainContext];
 
	// Create second thread for OpenGL stuff
	pthread_attr_init( &mThreadAttributes );
 
	pthread_create( &mThread,
			&mThreadAttributes,
			OGLThread,
			NULL );
 
	//
	while( 1 )
	{
		// do some rendering
	}
 
	//
	return 0;
}
 
//
//
void * OGLThread( void * inParam )
{
	//
	[EAGLContext setCurrentContext:mThreadContext];
 
	//
	while( loadingSomething )
	{
		// other opengl commands
	}
 
	// Flush changes
	glFlush();
 
	//
	return 0;
}

With this second context, any calls to binding objects to the context will not affect the other thread’s context. the [API] just makes it so that I’m using the same ES version as the first context, the [sharegroup] is the shared resource group that will be used by both contexts.

However you must take care not to update an object that is in use in the main thread, and whenever you make a change that will affect the other thread, call glFlush() on the thread that modified, and then rebind on the other thread so the changes take place.

In my own engine I hold shadow states of all options set, so one problem with this system would be I would need to pass in the Context depending on the thread. Instead I wrapped a class around the context that holds the shadow states and the context, as well as a pthread_t object for the thread it is assigned to.

Then whenever I do anything that will alter my shadow states, I make a call to pthread_self() to get the current thread, and find the relevant context.

struct MyContext
{
	EAGLContext * context;
	ShadowStates states;
	pthread_t thread;
};
 
MyContext mMainContext;
MyContext mThreadContext;
 
MyContext * GetCurrentContext()
{
	int ret = pthread_equal( pthread_self(), mMainContext.thread );
 
	if( ret == 0 ) // 0 means not equal when using pthread_equal()
	{
		return &mThreadContext;
	}
 
	return &mMainContext;
}

There is only one object so far that I have found doesn’t share between contexts, and that is a Vertex Array Object (VAO).

For now I’m just making my code think the extension isn’t present when multithreading is enabled, but I need to come up with a solution to generate the VAO for each thread it gets used on.

Catalyst

Catalyst Title Screen

Whilst working on animation support for Athena for Courage, I began working on a game for the iPhone called Catalyst last weekend.

I was thinking about a game I had played about a month or two before called Polygonal Fury, and realised it would port nicely onto the iPhone.

Catalyst - A circle explodesSo I started a OpenGL ES project (and discovered the new version of the iPhone supports shaders), and started with just making some circles bounce around.

Since the collision of a circle is easy, they seems the easiest to setup for interaction with touching the screen.

Catalyst - A chain reactionInitially I just made them “die” if tapped, but later I added the ability of shapes to spawn reactions.

All sprites within the game are triangle fans, but I will probably change them to quads with a texture due to the break that occasionally appears in the geometry, and alpha glow around the edge.

Catalyst - Still three "clicks" leftIt is not much, but it is a start, I plan to add some more particle types, and maybe a few different upgrades than the ones giving in the Flash version.

The background needs changing, I was thinking of something going on in the background like in another Flash game I played, Spewer, with maybe cut scenes like the Nintendo DS game Contact had.

iPhone 3.0 Beta 2

Connect to iTunesWith the release of iPhone 3.0 Beta 2, which automatically unlocks tethering as well as fixes a few other bugs with Beta 1 that were annoying me, I finally got around to upgrading.

However, during the process of the upgrade (I selected Update instead of Restore this may have been what caused it), an error occurred. Fearing I may have just bricked my iPhone with a firmware changed, I quickly ran Restore, only for it to fail with an Error 1611, or maybe it was 1602 or 1604.

Searching the interwebs, I found various people who had the same problem with earlier version of the iPhone firmware, and one recommended putting the iPhone into DFU mode… BIG MISTAKE! It turns out that MacOSX doesn’t recognise an iPhone in DFU mode, treating it like an iPod and giving Error 2001 messages. But not only that, but I was stuck in DFU mode (which btw is a black screen with no way of knowing if it is turned on or not).

The only solution at the time I could find around this was a piece of 32bit Windows software, which wouldn’t work with my 64bit OS. Luckily I came by some instructions the next day, which said to exit DFU mode, all you have to do is hold power and home for 10 seconds. I don’t know if it was this however, since I think my iPhone had run out of power, I might have just been turning it back on.

To fix the original problem, all I did was delete the ipsw files in “/<user>/Library/iTunes/Device Support” directories. Restore didn’t work until I manually Restore using Firmware 3.0 Beta 2 (probably something gets changes which is why you can’t downgrade through normal means).

iPhone 3.0

iPhone TetheringApple recently released the iPhone SDK for 3.0, which for developers means that they can get an early release for version 3.0 of the OS (though it is possible to get ahold of the OS without being a developer through shady means). One great thing about this, someone browsing around the new iPhone OS found tethering, a much wanted feature of iPhone since its first release.

And so as usual, a fake upgrade was made, which enables it. I’ve already gave it a whirl myself, and it works great. However, I haven’t ran it for extensive periods since there is nothing in my O2 contract about tethering, which means O2 could charge me for using it. I wonder if there is a way I could get it added in…

I look forward to the actual release of tethering. There are still many other great features being introduced in the iPhone OS 3.0 for me to play around with, and I don’t really need tethering at the moment, everywhere down here seems to have WiFi close by. Maybe I should get a WiFi detector instead.