Sunday, November 28, 2010

New Website

The new website is up and running. Any new posts will show up there.

Link: http://radicalbit.net/

edit: Okay, now that website is old and broken and unmaintained as well. I need a new place to put things.

Thursday, November 25, 2010

A Quick Update

I know things have been quiet here lately, but some new stuff will be coming along. I'm in the process of building a website that will host this blog as well as other information on Championship Ultimate. It will also be a source of information on my other games and projects.

There will also be a smallish update to CU coming soon. It won't have multiplayer, but there will be a number of nice little tweaks. Multiplayer is simply a huge project will take some more time.

Thursday, October 21, 2010

Versus.

The multiplayer code is finally looking playable. The gameplay elements are just about done, but there's still a bit of work to sync up team / game selection, sounds, etc.

But, here's the thing: Bluetooth performance has seemed pretty terrible during my own testing. I think I do an okay job compensating for the lag, but once in a while it will spike up and the disc will jump around, or your player won't catch the disc when it seems like it should. So, should I release the Bluetooth multiplayer, or just work on the GameCenter internet play which should (most of the time) yield better results?

I'm leaning toward releasing it. I think it will be fun, even if the performance isn't great. Thoughts?

Tuesday, September 21, 2010

TimeSync was a time sink

An important part of my networking code for Championship Ultimate is getting all the devices clocks synced up, so that they can talk intelligently about what time events occurred in the game. It turns out that this is not a trivial problem, and I spent a couple days working on it.

This question I asked on stackoverflow.com goes into more detail, and I got some helpful answers: http://stackoverflow.com/questions/3755208/measuring-time-difference-between-networked-devices

This wikipedia page was also helpful:
http://en.wikipedia.org/wiki/Precision_Time_Protocol

So, with all that info, I made a class to do the job that I'm fairly proud of. Perhaps it will be useful to someone else someday. Do whatever you want with the code, but it would be fun if you left a comment to say it was useful. The actual network communication stuff obviously needs to be changed to fit in your code.

TimeSync.h


//Call [timeSync startSync] on the client. The offset variable will be continually updated
//throughout the life of the program, and it will be sent back to the server also.



#define TS_DELAY_MAX 10000


@interface TimeSync : NSObject 
{
    NSTimeInterval t1, t2; //t1 is client time - server time, and t2 is server time - client time
    NSTimeInterval offset; //this doesn't get calculated from t1 and t2 until it's stabilized
    uint synccount;
}

-(NSTimeInterval)offset;
-(void)checkSyncStatus;
-(void)sendTimeSync;
-(void)sendDelayRequest;
-(void)sendDelayResponse:(NSTimeInterval)from;
-(void)processPacketType:(uint8_t)type TimeStamp:(NSTimeInterval)timeStamp;
-(void)sendSyncRequest;
-(void)publishOffset;


TimeSync.m


@implementation TimeSync

-(id)init
{
    if (self = [super init])
    {
        t1 = TS_DELAY_MAX;
        t2 = TS_DELAY_MAX;
        offset = TS_DELAY_MAX;
        synccount = 0;
    }
    return self;
}

-(void)sendSyncRequest
{
    [[Basket shared].connection sendPacket:PT_SYNC_REQ Data:nil Mode:GKSendDataReliable];
}

-(void)sendTimeSync
{
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    [[Basket shared].connection sendPacket:PT_TIME_SYNC Data:[NSData dataWithBytes:&now  length:sizeof(NSTimeInterval)] Mode:GKSendDataUnreliable];
}

-(void)sendDelayRequest
{
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    [[Basket shared].connection sendPacket:PT_DELAY_REQ Data:[NSData dataWithBytes:&now length:sizeof(NSTimeInterval)] Mode:GKSendDataUnreliable];
}

-(void)sendDelayResponse:(NSTimeInterval)from
{
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    NSTimeInterval diff = now - from;
    [[Basket shared].connection sendPacket:PT_DELAY_RSP Data:[NSData dataWithBytes:&diff length:sizeof(NSTimeInterval)] Mode:GKSendDataUnreliable];
}

-(void)sendSyncNotify
{
    [[Basket shared].connection sendPacket:PT_SYNC_NOTIFY Data:[NSData dataWithBytes:&offset length:sizeof(NSTimeInterval)] Mode:GKSendDataReliable];
}

-(void)startSync
{
    //get a first quick measurement, then only measure every 10 seconds
    //basically, a new offset will be published every minute
    if (offset == TS_DELAY_MAX)
    {
        [self performSelector:@selector(startSync) withObject:nil afterDelay:0.5];
    }
    else
    {
        [self performSelector:@selector(startSync) withObject:nil afterDelay:10.0];
    }
    [self sendSyncRequest];
}

-(void)publishOffset
{
    offset = (t2 - t1)/2.0;
    NSLog(@"TimeSync found delay to be %f", offset);
    NSLog(@"Ping was %f", (t2 + t1)/2.0);
    //reset so we can measure a new drift
    t1 = TS_DELAY_MAX;
    t2 = TS_DELAY_MAX;
    NSLog(@"Notifying server of offset...");
    [self sendSyncNotify];
}

-(void)processPacketType:(uint8_t)type TimeStamp:(NSTimeInterval)timeStamp
{
    NSTimeInterval timediff;
    switch (type)
    {
         case PT_SYNC_REQ:
             [self sendTimeSync];
             break;
         case PT_TIME_SYNC:
             timediff = [NSDate timeIntervalSinceReferenceDate] - timeStamp;
             if (timediff < t1)
                 t1 = timediff;
             [self sendDelayRequest];
             break;
         case PT_DELAY_REQ:
             [self sendDelayResponse:timeStamp];
             break;
         case PT_DELAY_RSP:
             if (timeStamp < t2)
                 t2 = timeStamp;

             synccount++;

             if (synccount % 5 == 0) //publish the new offset every 5 measurements
             {
                 [self publishOffset];
             }
             break;
         case PT_SYNC_NOTIFY:
             offset = -timeStamp;
             NSLog(@"Received notification of offset:%f", offset);
         default:
             break;
    }
}

-(NSTimeInterval)offset
{
    return offset;
}

Thursday, September 9, 2010

A Quick Note

I don't have much real news, but I am hard at work on some cool features. And, I'm looking to get support for GameCenter in sooner, rather than later. Yup, that means online multiplayer. I might focus all my work on that to try to get it out there even if it means pushing some other stuff back a bit. I'm excited to see if anyone can beat me at my own game!

Wednesday, August 25, 2010

Submitted 1.2

I submitted version 1.2 for review. Some fun facts:

Championship Ultimate is right now made up of 30,239 lines of code! The biggest file by far is Player.m which is 1699 lines.

Yesterday, August 24th, was the one year anniversary of the beginning of the project. Here are some comparison screenshots:

8/24/2009
8/24/2010
In a lot of ways, 1.2 is the game I wanted to make from the very beginning. But, I'm glad I didn't wait this long for the first release. I've gotten a lot of great feedback since it came out that has helped it evolve. So, many thanks to all of you for playing the game and spreading the word!

Here's the changelog:


Gameplay Improvements:
Much more realistic flight physics
Can put curve on throws (inside-out and outside-in)
Can alter the angle of attack (changes the height of throws)
Can optionally use simple throwing controls that require no pivoting
Tweak camera to show more action on the near sideline
Throws out of bounds come in where they went out
Pulls out of bounds respect the brick mark
Added Huck drill

AI Improvements:
Poached players cut more aggressively
Tone down AI poach defense and make throwers less conservative
AI will more intelligently chase your hucks
AI has better judgement of whether a huck is open

Graphical Improvements:
Better looking stadium
Added stadium lights
Added camera flyby to game intro
Added nicer looking sky
New buttons
New stall counter

New Teams:
OSU Leadbelly
CHS Varsity
Oberlin Preying Manti

Bug Fixes:
Player numbers looked wrong when pivoting (and related problems)
Holding down throwing arrow might lead to player switch
Other misc. fixes

A few things have been pushed back to 1.3, which should be a pretty exciting release as well.

Saturday, August 14, 2010

iOS 3.1 crash..and...new buttons!

There's a problem with iOS 3.1 and CU version 1.1. I've submitted a fix and it looks like they'll review it on monday. Sorry about that!

Here are the new buttons I've made. I can't decide if they are too colorful. Maybe they should all be gray, and just labeled A,B, or C?

Thursday, August 12, 2010

1.1 Is Out! And...some mood lighting.

1.1 has finally been approved for the app store. Scooops!

I've added some subtle stadium lights to the newest version. It doesn't jump out at you, but I think it does provide some nice graphical depth.  Actually, I think it also helps with gameplay, because depth perception is a little easier, as areas of light or dark become good reference points to judge distances.

Overall, the field does look a bit darker, but I think it raises the drama.

Love it? Hate it? Can hardly tell the difference?

Comparison pictures: Original (Above) and Lit (Below)


In other news, lefties should make it into 1.2, and I've started work on multiplayer, but I need access to another ipod/phone to really make good progress there.

Friday, August 6, 2010

Git 'er done!

A few weeks ago I started using Git, which is a source code manager, or a version control system, or maybe it has five other names. Essentially, it keeps track of every code change I make and it makes my life a whole lot easier! I can branch off in different directions for everything I do, and then merge everything back easily when it's ready. It's free and open source, and was started by Linus (the guy behind Linux). It's way superior to CVS and SVN and everything else.

Here's a screenshot of my git tree for Championship Ultimate:

1.2 Materializes

I had to resubmit 1.1 a few days ago because of a bug I found. But again, I hope it comes out soon.

The delay hasn't stopped me from working on version 1.2. It's going to have some pretty awesome and fundamental changes, and ideally it'll be ready to submit right after 1.1 is approved.

For 1.2 I dramatically improved the disc flight physics. Now it flies much more realistically. You can now throw the disc at an angle and have it curve. You can also alter the angle of attack, which means hucks can either be fast, low flying throws, or you can make them sail into the air. Short throws can be either quick, zippy passes, or you can float them into a space.

Sound complicated? Well, yea, it should, because throwing a real frisbee is a complicated process. I want the video game to have all the flight options that a real disc has.

However, I also added optional, simplified controls. A new player can pick them up and play without much practice. An experienced player might even like them if they don't care much about the attack angle or pivoting or throwing hammers.

There's also some AI improvements and a handful of bugfixes.

Friday, July 30, 2010

Update Submitted!

I submitted version 1.1 to the App Store. I think updates get reviewed faster than new submissions, so hopefully it's out within a few days.

Here's the changelog:

Added iPad support
Can now throw hammers and blades
Simplified throwing and turning controls
New help files to better explain the controls
AI controlled players are more likely to chase down hucks that fly near them
When jumping for the disc, your player has better judgement of whether to jump up or layout
Added layout D drill
Made a more informative tournament screen
Can now run game in both landscape orientations

fixed bug: Switching to running player caused them to stop
fixed bug: Fast devices would run demos too fast
fixed bug: Couldn't reliably turn left when holding disc
fixed bug: Sometimes turnover in endzone would incorrectly result in a score
fixed bug: Sometimes targeting control arrow would "stick"

Other small fixes and tweaks

Phew! It was a lot of work to get everything looking good on the iPad.

Now that I'm done with that, what should go into the next release? Any great feature ideas? Any hated bugs that should be fixed?

Off the top of my head, I'm thinking...
Inside out / outside in forehands and backhands, to add some curve to throws and pulls.
Lefties
Mini-frolf course type training drill?
Some iPhone 4 hi-res support

Add some stuff to the list!

Sunday, July 25, 2010

Simplifying the controls

I took some time recently to change the throwing controls a bit. I think the new controls make it much easier to turn and find a target, and also make everything conceptually simpler.

The old controls (as seen in the current release, version 1.0) consisted of:
1. A "rotater" control to turn and find a target.
2. The DPad, which was used for pivoting.
3. The targeting pad, which was either used to throw short passes (high release backhands and push passes) by itself, or was used after pivoting to throw full power backhands and forehands.

The problems with the old controls...
1. The "rotater" was awkwardly placed above the DPad, making it slow to go from turning to pivoting. It was also visually complicated.
2. The targeting pad was too tempting for beginners. They would (understandably) use it to throw the disc without pivoting first, but that would result in short throws. I.e., "I'm dragging the arrow out pretty far, how come the disc isn't going anywhere?"

Once I added hammers, I knew I had to unify all the different throws. Instead of separating the short throws from the long throws, I would put all of them (forehands, backhands, high release backhands, push passes, hammers, blades) conceptually on the same level.

The new controls consist of:
1. The DPad, used for pivoting as usual UNLESS the red Action Button is held down.
2. The familiar red Action Button. If pressed, it will enable the DPad to turn the player.
3. The targeting pad, which only pops up once the player has started pivoting.

Benefits of the new controls:
1. Got rid of the "rotater", and found a new use for an existing button. The fewer buttons to learn about the better.
2. The left thumb is always positioned over the DPad; no need to move it up in order to turn.
3. The throwing pad is no longer a big problem for new players. Instead of, "Don't use it if you haven't pivoted first", the recommendation is, "Whenever you see it, go for it!".

Here's a visual explanation of the new controls:



What do you think? Is this better than the old controls?

Barring any strong objections, the new controls will be available in the upcoming 1.1 release. I might include even simpler "beginner controls" as an option in a future version of the game.

Thursday, July 22, 2010

U Can't Touch This

Let's see...I guess I promised I would add more fun stuff to the next version. What should I do? Hmm...

Oh right. Hammers. Everyone loves hammers.


Saturday, July 17, 2010

Episode IV: A New Version

I've almost finished the first update of the game. Although it will mostly benefit people that want to play it on iPad, there will be a few more things that everyone should like.

Firstly, here's the team edit screen completely redesigned to take advantage of the big iPad screen:


Here's the rest of the change log as it stands now:


When jumping for the disc, better judgement of whether to jump up or layout
Added layout D drill
Can now run game in both landscape orientations
Fixed bug: switching to running player caused them to stop
Small fixes and tweaks

I think it will take another week to finish the ipad stuff and test it all. But, during that time, I might throw in some more fun stuff... Stay tuned.

Tuesday, July 6, 2010

iPad

Still no word on when the game will be reviewed for sale on the app store, but I have made good progress on the iPad version.

I'm about halfway done reworking everything to fit in the bigger screen. After that, I could make some tweaks to take advantage of the extra space. I'm not sure whether I should bring the camera out a little to show more of the field. Right now it just seems nice to see more detail. I think I'll have to actually get hold of an iPad and play around with it to see how the bigger screen feels.

I noticed that I can actually see the disc design now, so I'll have to add in different designs. Maybe as rewards for beating the game or certain training drills?

Tuesday, June 29, 2010

Submitted!

Championship Ultimate has been submitted to the Apple iPhone App Store. I don't know how long it will take for them to approve it, but I put in a tentative release date of July 2nd. Over the past month I've put in a LOT of work finishing and polishing the game, and I think it really shows.

Wednesday, June 2, 2010

Tuesday, May 25, 2010

AI Gameplay Video

I've done a lot of work recently on the AI. In fact, I completely rewrote the decision making system from scratch. It's much more reliable and has fewer bugs now.

I recorded a video that shows the AI playing a point without any human interaction. Obviously it can still get more sophisticated (especially on defense) but it's a good start. I'm also showing off the new menus.

Sorry about the bad video/sound quality.

Tuesday, April 13, 2010

Various Bits

I'm closing in on a release, and while I'm still hard at work, all that's really left are a bunch of smaller details. So, I'm going to cut down the number of updates here, because it's really only fun to write about big features.

But anyway, here are some things I've worked on recently:

Improved camera calculation (often closer now), added more drills, fixed bugs in input system, added demo playback speed setting, most of the time layout d's will knock the disc away, fixed throwing bugs, tweaked flight physics and AI throwing power.

Made super cool animated menus, added documentation for the controls.

I'd also like to get back to writing about other things, so this may be less of an iphone specific blog soon enough. But, rest assured that the game is still being worked on and will be ready "soon".