Friday, December 28, 2012

Do game creators get holidays?


My hubby Raymond, a black fine line art drawing done with Manga Studio
Raymond - who is a Saint
Well, I sort of had some.

I tried to spend some quality time with my long-suffering hubby Raymond, and caught up with my in-laws for a big turkey lunch.

My last day at my current paying gig is not for a couple of weeks yet, but I said "Happy holidays" to my colleagues on Friday last week, and since then I have had a full week on my own recognisance.

In that time I've made a fair bit of progress on getting to grips with Cocoa, and with actually getting useful functionality into the GameCreator tool.

It has 4 screens: Rooms, Atoms, Aspects and Identifiers.  I've done 3 now, with the Atoms screen now pretty much working.  There's a couple of bugs with the Undo but I can add new Atoms to a room, delete them and so on.

I figured having done the Rooms one the Atoms would be easy: not so much.  When I select a room I want the Atoms screen to show only the Atoms for that room, and that turned out to be a real pain.

Cocoa bindings would not play ball at all and I had to refactor quite a bit to get what I needed working. The problem was that each screen is a seperate xib file, and its loaded by its own controller - I switch between controllers using a top-level screen.  Trying to communicate from one screen controller to the next turned out to be nasty.

I go back to work on Wednesday next week and have sort of two half-weeks before I'm full time on my own stuff.  Maybe I should take some of that time between now and when I go back to actually rest.


 *** Terminating due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[GameDeveloper rest]: target does not implement selector'
:-)

Monday, December 24, 2012

Traction

Finally starting to get some traction on the game creator having bullied CoreData, Key-Value coding, ArrayControllers and all the other mystical components of Cocoa into doing what I need.  Thanks to all who gave me encouragement!

Screenshot of game creator - 30% done


The game itself is still only partly set up to become data driven, but that I think will be a lot simpler than actually getting the data in there in the first place.  Because so much of it is about the rich world of objects, properties and descriptions the actual game content has to be data driven - hard coding it would have been a massive undertaking and very difficult to debug.

The buttons on the right are for creating exits from the room, and going ahead to the atoms screen to create the contents for that room.  These buttons, and the Atoms and Aspects screens are still on my todo list.  But I can use the room as a model and I'm sure it will be a lot quicker.

Things to add are a launcher button so I can launch the game from the creator, and have the game use [a copy of] the current view of the data as edited by the creator.

Re-org Your Source Tree in XCode

This is a video tut I just did on reorganizing your tree of source code in the XCode environment, so that it makes sense and plays nice with source control.  Its not rocket science but it gave me pause the first time I did it so maybe this'll be helpful for some folks.

Wednesday, December 19, 2012

Primal Scream

Right now I'm bogged down trying to get some infrastructure stuff done for my game and its very frustrating.

Later in January my time will be mine to schedule as it suits, but right now I'm still working days and coding on my game at nights.  It means I'm tired and not as on top of my game as I should be.

Things that seem conceptually simple and had looked like being fun to do, turned out to be a real pain in the neck.

And literally, as my home work setup is not ergonomically great.  Now I'm walking round like Quasimodo.

Its discouraging.  Why with all these amazing productivity tools can the simplest things be so painful to achieve?

I have a bunch of stuff hard-coded in the game and I'm trying to make it data driven.  The theory is I change a few values in a file, and hey presto the game springs to life with a whole new scene.  Minimal coding, just drop in the artwork and away we go.

Nuh.  Not so much.

To sum it up I've crossed a watershed in Objective-C where I know enough to start coding up things beyond the bounds of the tutorials and example code - and I absolutely have to do that because none of the things I want to do fit neatly into those examples.  So I can see what I need to do, but don't know it well enough to quickly write and debug the code to achieve it.

Things that ought to be simple - wiring up a few data structures to some UI elements - are painful beyond belief.  CoreData's magic binding stuff is not doing what I want, and even where I thought I had it nailed its not working how I thought.

There are a few API's and languages I know really well - those I am used to being able to express myself in quickly.  I can get stuff done fast.

And I will get to that point sometime with Objective-C but right now.... I want to throw the whole thing at the wall!  Grrrr!!!

Oh well.  Hopefully by the next blog things will be better!

Saturday, December 15, 2012

Preparing Scanned Line Art

For those times in your game where you need a more visual sort of element - like say the image that goes in an inventory for an RPG or adventure game - starting with a drawing is a good quick way to go.  Pixel art is great for small sprites, but if your image is going to be say 1/2 the screen size starting out clicking on pixels is going to take you a while.  For this kind of thing I often like to work with scanned in hand drawings.

But how do you get those drawings looking like the high-contrast, well defined rendered or pixelated images in the other parts of the game?  Maybe you don't and you want a more hand-drawn effect, but in this tut I'm going to show how I prep hand drawn images for import and coloring to use in my game.

Prepare the pencil based artwork on a nice big piece of paper.  Don't worry about the details as you'll work over these in pen later.  Here I just wanted the neural interface gizmo to look like it would go on a human head, so that head is just there to get the shape right - it will disappear in the final result.  Notice how I don't bother rubbing out either - when I want to reposition something I'll just draw over it in the new spot, and pick the right line when I ink it.  Also note that I have not used blue - you can but typically you don't need blue pencil, and black pencils come in more kinds and are cheaper.



Ink over the pencil using your favourite pens.  I use Mitsubishi uni-ball ink pens which are nice and fast and dark, and Pentel chisel point art-markers.  I have some crow quills and a tub of ink somewhere but they're so messy.  Fibre tip fine pens are OK, but I find they scratch and split too much as I always press too hard.  Ball tips are fine as long as you start out with a big piece of paper.

Don't fret too much about mistakes as we can correct a lot of things digitally later.  The main thing is to get the ideas out onto paper.  Make your inking fairly bold and go over outlines to strengthen them up.  Areas with more ink I use the marker, sometimes I can get away by using the edge of the chisel-point, other times I have to go over the lines several times with the ball-tip.

Time to scan.  I just use a cheap CanoScan LiDE 25 USB scanner that works fine with my Mac gear.  Scan at 600DPI, and use the color setting, not the black and white.  I find if you try to go that way you'll lose too much detail from the drawing.  Its much better to threshold it in the drawing program as I'm about to show below.  Crop out unnecessary blank paper using the scan dialog if needed.  This will make the sketch load into Gimp a lot quicker.

For my art work I use a mixture of Manga Studio Ex for full comic spreads, and the Gnu Image Manipulation Program or GiMP for detail work.  MSEX is good but expensive.  And for some jobs GiMP is just as good.  If you're on Mac and haven't used GiMP for a while it has gotten really good, thanks to the work of the Free software community - it now runs natively and does not require an X server.  Its also a lot faster and many of the weird mouse-focus issues are fixed.  Obviously if you're on Windows or Linux, your mileage may vary.  For this article I'll be using GiMP, but the principles and tools apply to most platforms and other drawing programs even tho' the actual commands and menus may change.

Load up the image into GiMP.  Notice how the yellowy paper and pencil work is visible right now.  That's fine and you want to be able to pick and choose what stuff you leave in and out.

You should have a large image - mine came out 2310 x 2284.  If you get a small image - say 1024 x 768 or similar then your line work is going to get eroded by the threshold which is not what you want.  Either you need to get a bigger bit of paper and draw bigger, or check your scan DPI and ensure its 600DPI or maybe try a higher setting.  The images here have been scaled down to make for smaller uploads so don't go by their sizes.

Now for thresholding.  Right click on the image in GiMP to get the menu and choose Colors > Threshold.  If you're lucky the auto setting will be about right.  If there is too much unwanted stuff, or not enough ink, move the sliders around until you're happy.



Now that we have just the inked line art, we need to get it onto a transparent layer so that color can be applied.  The actual color will be done in another article/tut but getting the setup right as I'm about to show should apply to almost all methods of coloring that you might want to do.  The way it is right now looks OK, but the problem is any fills you apply will not appear to go right up to the edge of the line.  What you want is the line art on top of the color so that you can avoid white pixels where the lines edges are aliased.

Right click on the drawing to get the GiMP context menu and choose Select > By Color.  Click in the black line work, and after some time you should see all the ink selected as below.  It takes GiMP a while even on faster machines as it has to color match every pixel and we have a big image here.  Once its selected, choose Edit > Copy.  Now create a new layer, by clicking the anonymous little white "New Layer" button in the bottom-left corner of the layers dialog.  Name your layer "line-art".  Make sure the layer is transparent (not background color).


With the new layer selected choose Edit > Paste.  In the Layers dialog you will see a "Floating Selection".  Click the Anchor button on the Layers dialog to anchor it to your new layer.  Try turning on and off the eye icons - you should see that you now have a layer with just the linework and a transparent background.  Its hard to see what's going on with the linework, because of how transparent layers are displayed.  Next we'll add a white background to fix that.

Let's add two more layers: one will be transparent - call it "color" as this is where our color will go; and the last one will be white - call it "white background".  I always make a practice of naming my layers as they can quickly get out of control in a larger piece of art.  Make sure the line art is on top, with the transparent color layer and white background underneath.  You can turn off the original import by clicking the eye, as you don't really need it.  Turning it off should make your image appear just the same as after thresholding.  Now your layer dialog should look like this.


This is a good time to save your work.  Make sure that you save it in the .xcf format, by putting the characters ".xcf" as the file name ending.  This is GiMP's native format and it will preserve all your layers and so on.  Think of this as like the "raw source code" of your image, and you will "compile" it later by exporting to other formats such as .png.  If you don't have the xcf around its hard to recapture the structure of your drawing, so save to .xcf, save early and save often.

OK now we want to start cleaning up the image.  This involves a few GiMP skills that I will try to describe in more detail in another tutorial, but here is the guts of it:

  • do a lassoo select around your line art and then choose Select > Invert so that your next operation will apply to everything outside your linework.   Now use a really large eraser to clear out all the little dots and blobs from the background.
  • zoom in to your work with + and go over the lines with the Ink tool - press K to get it quickly and switch between Ink and Eraser (Shift E) as you clear up the lines
  • try using the "smooth" setting on the ink tool to help stabilise your ink strokes, and experiment with the settings.  I prefer a hard edged brush so check the brush settings if you're getting an effect that doesn't look right
  • to get long smooth lines you can use the Path tool and tell it to trace the path in Ink.  This works well but is complicated to get right and is the subject of a tut all by itself
  • fix up larger issues like scale or perspective by lassoo'ing the offending chunk of linework and using the rotate, shear and other transform tools.  Save is your friend.  command-Z is undo.

This shot shows removing splash around the linework using inverse-select and a large eraser.  (The screen grab didn't capture the eraser but its as big as the whole line art and clears the page in a few swipes).


Here I have cleaned a lot of linework with the Ink and Eraser tools - see around the nodule thing on the right hand side especially - and also the underneath chrome part has been rotated so its perspective is a bit more correct to the rest of the device.  (I took the inverse-select screenshot after doing this cleanup so to see the effect compare it with the post-threshold image above).

Save the .xcf file again at this point and use the "Save a copy" feature so that you can revert back to your good line art if something goes wrong.  Give it a name like "my-device-line-art.xcf".

At this point you would go ahead and start applying your layers of color on your "my-device.xcf" working image file.  Make sure to use separate layers, and not to mess up your line art layer.  Just to show the beginnings I have blobbed some color onto a couple of layers - the blue (which would become a metal chrome color job) is on the "color" layer from before and the orange I have put on a layer above that called "lights".


Anyway - that's all for this one, and hope you have fun GiMP'ing your line art.  

Monday, December 10, 2012

Customizing the core data store.

CoreData is a pretty awesome way to manage and persist your game objects, especially for a game with complex inter-related items, such as an adventure game.

Trouble is there is a helluva learning curve getting going with CoreData.  I just solved one little thing that was driving me crazy and wanted to share: how do you customize aspects of the CoreData store?

Image of apple core courtesy of http://www.wpclipart.com/


In my game I have two project targets: one is the game itself written in Cocos2D, and the other target is a game data editor written in Objective-C & Cocoa for the Mac.  They share a lot of classes, and the idea is that I can edit the games data, save it out as a SQLite file (which is one of CoreData's persistence formats) and then when someone goes to play the game for the first time they get a fresh instance of that data as the initial game state.

Trouble is, how do I tell the Mac Cocoa gui, to create my custom instance of an SQLite database, instead of popping up a dialog - which is the default thing you get using XCode's CoreData enabled app wizard?

And for that matter how do I get my database of game objects into my Cocos2D app?

If you're a CoreData beginner like me I suggest:
  • The answer begins with having to understand the bare essentials of CoreData.  For that I recommend Bob Uelands video tutorials.  He has a patient and careful manner that is a bit frustrating but his clarity is hard to beat.  If you've some familiarity with CoreData you can probably fast forward or even skip his stuff.
  • You could try Ray Wenderlich's tutorials - but I find they're a bit too specific and don't always give me the "why am I doing this" answers I want so I can build my own stuff.  But have a look and they may just have exactly what you need.
  • Go and run through Apple's CoreData command line tutorial.  It builds a CoreData app up from first principles all inside main.m.  If its all gobble-de-gook to you, then maybe skipping patient Bob's tutorials was a bit hasty...
What is great about the Apple CoreData tutorial is that the final result - a CoreData app that does not start with any of AppKit or UIKit, or any XCode scaffolding - is exactly what you need for dropping CoreData into a Cocos2D app.  If you have the time and want a good understanding work through the tutorial building up the code in the order given, and resist the temptation to just past the whole source.

Seriously - if you're used to skipping the boring documentation in the Apple developer site you're missing a buried gem with this tutorial.  They give the steps to building a whole data persistence stack.

I found working through these gave me the answers I needed.  So for example to solve my problem with customising the data store, I took the code from Apple's CoreData tutorial managedObjectContext() function and overrode the managedObjectContext function in the NSPersistentDocument sub-class I was using in my Mac OSX game editor GUI.

Edit:  OK, this looked like it was working but wasn't - my apologies.  Basically you can use this code, but you need to create your own window controller and UI class, not use the NSPersistentDocument - which is built to handle arbitrary "documents", not one well-known path for a database.  Sigh.

That let me specify the details of my store:

- (NSManagedObjectContext*)managedObjectContext
{
    static NSManagedObjectContext *moc = nil;
    if (moc != nil) {
        return moc;
    }
    
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc]
                                                 initWithManagedObjectModel:[self managedObjectModel]];
    
    NSString *STORE_TYPE = NSSQLiteStoreType;
    NSString *STORE_FILENAME = @"GameData.sqlite";
    
    NSError *error;
    NSString *path = [[PreferenceValues sharedPreferenceValues] saveGamePath];
    NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];
    url = [url URLByAppendingPathComponent:STORE_FILENAME];
    
    NSLog(@"Setting up the store with type %@ - at %@", STORE_TYPE, [url path]);
    
    NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE
                                                            configuration:nil
                                                                      URL:url
                                                                  options:nil
                                                                    error:&error];
    
    if (newStore == nil)
    {
        NSLog(@"Store Configuration Failure\n%@",
              ([error localizedDescription] != nil) ?
              [error localizedDescription] : @"Unknown Error");
    }
    
    moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [moc setPersistentStoreCoordinator:coordinator];
    
    return moc;
}

Wait, what is that PreferenceValues thing doing in there? That is my own NSUserDefaults front-end. More on that in another post.

How do I get my data into Cocos2D?  I'll show you how I did it, but that's for another blog post.  Subscribe - give me feedback and I will post more!  Thanks for reading!

Coming Out

It feels so good to be out of the closet.  Here is my big admission!

I am a wannabe indie game hacker!!!
The crowd shuffles nervously.  Is she for real?  Wow - brave to come out like that, but geez those folks who think they can be indie game coders - soooo llaaaaaammmme.
Well if I ever worried what people thought I would never do anything.  :-)

Here's a screenshot of very early days game screens, just to show that I'm not completely delusional.

Ethex Screenshot (C) Sarah Smith 2012

What's it all about?  What kind of a game is it?  What's the tech stack, platform, genre?  How did you create that artwork?  Well - keep posted, subscribe to the blog and all will be (incrementally) revealed.

So this blog post marks the beginning of a few things for me:
  • I am officially taking my indie game coding efforts seriously
  • This right here is going to be my development blog
    • updates on progress
    • screenshots
    • insights on the game design process
    • sez-cam: developer eye view of game dev in the raw
  • I will also post random tutorials, learnings and snippets
  • Commit to posting here at least a couple of times a week
And, when my game gets to the point I can publish, you'll know it right here, first thing.

Why would I do all this?  Haven't I got a game to write?  Well, yeah - but its hard hacking away by yourself in a room.  This blog is my way of letting you all in to shine a little light, keep me sane, and maybe lend some encouragement on the way.

In return I hope there's some useful stuff, some entertainment and a few lessons.

Oh, and quick note to the "borrowers" looking for free game art and resources - my definition of success here is that my game makes money.  I don't want to give away my art for free.  I want to make a living out of making games so I can keep doing it.  So this is not a site full of free stuff: if I post some images here or any other game resources, unless I say otherwise they're not for folks to dump into some knock-off game and call it their own work.  Didn't I use Free technologies, and other free stuff from kind people?  Yes!  Doesn't that mean I should in turn give away what I do?  No!  Hey, I hope that is obvious.  Any questions about this contact me in the comments.

Code is an exception mostly: in general in code I post here will have a notice on it that you can use it for whatever you like.  The full source code for the game is not going to be open-sourced, but I have a plan to make as much of the framework of it as I can open-source eventually.  That is I want to split out the artwork and content from the machinery - but that has to be a secondary goal to making a real working game.

So welcome.  And please keep up the commentary - here or on my Google plus account, check the side bar for details of that.