I’m Making a Game

I think this is the longest I’ve gone without a new blog post in several years now. Over the summer, I got YarnBuddy to a good, stable place—meaning people are now emailing me feature requests instead of bug reports. I still have a long list of features to add to YarnBuddy, so it is in no sense abandoned and I plan to begin working on it again soon, but in the meantime… I’m making a game.

People who have followed me on Twitter for a long time know that at one point, I was working on a game called Corgi Corral. It was an arcade-style game where you played as a corgi trying to round up as many wayward sheep as possible before a timer reached zero. It looked cute, but I had no knowledge of game design or how to tune the mechanics to make it truly fun, so I stopped working on it.

My son has been really into gardening/farming games recently. There’s one called Montessori Nature that he’s been playing on his iPad for years, but unfortunately it’s buggy and hasn’t been updated in ages. It also has several other points of frustration: namely, there’s not enough room to make a super gigantic garden, and the garden requires too much up-keep (plants wilt quickly, get eaten by pests, etc.). Charlie’s more interested in the design aspects of gardening—making something that looks cool, spelling his name in flowers, etc.

He has since downloaded and tried every single farming game from the App Store (I am not exaggerating). They are all either A) riddled with ads, B) super buggy, C) infested with IAPs or D) all of the above. Games like Stardew Valley, which are actually good, are too advanced for a 5-6 year old and include gameplay elements that he’s not interested in.

So, here I am, making a gardening game for kids. It will be called Charlie’s Garden, and it’s going to be the most chill, relaxing, do-whatever-you-want gardening sim. You’ll see different animals at different times of day and in different seasons, but the day/night cycle is quick enough to catch all of it in 30 minutes. There’s no experience levels, just in-game money (which will be easy to come by), so everything is unlocked from the get-go. There will be an element of exploration, maybe even some light crafting (what happens if I combine these items? Let’s find out!). I’m tossing around the idea of including a few mini-games. Scope-creep is real though, so I have a clearly-defined MVP that I will release first, before adding other stuff.

Here’s an early look at what I have done so far!

The game will be paid-upfront, with no ads or IAPs, and will work on super old iPads. I’m making it using SpriteKit, and drawing every single sprite myself in Affinity Designer. I’m hoping to have a build that can be tested by his birthday in mid-March (in other words…this blog post ends here, because I need to get back to work!).

Who uses SpriteKit/SceneKit?

Apple introduced SceneKit at WWDC 2012 and SpriteKit in 2013. Both frameworks have received updates over the past 3 years and have had multiple sessions dedicated to their new capabilities. Watching at home, however, I could never tell how many people actually attended those sessions. Is anyone even using SpriteKit? It seems like the majority of iOS games are built using cross-platform game engines like Unity.

If you’re an iOS game developer, I’m hoping you won’t mind answering this quick poll (not sure if it’ll show up in RSS readers):

[poll id=”2″]

Ever since Disco Bees was released, I haven’t heard a peep about any popular games made using SpriteKit or SceneKit. The reason I’m curious about this is because I want Apple to keep working on these frameworks, but I worry that they’ll be left to languish if no one is actually using them!

Comments are open on this one; please behave yourselves.

Status

Quick progress update: I’ve been treating Corgi Corral as sort of a SpriteKit/GameplayKit sandbox, as I really want to learn about everything these frameworks have to offer. Lately I’ve been exploring particle emitters, which means my winter scene now has falling snow and a small campfire! Next up: creating some more custom menu icons to reduce the amount of text in the game.

Using SpriteKit’s Scene Editor for Simple Animations

When I began working on Corgi Corral, I knew I wanted to keep the game as simple code-wise as humanly possible. I wanted there to be one “LevelScene.swift” file that would handle the game logic for all of the levels in the game, and I didn’t want to clutter up that file with level-specific code for animating background/decorative sprites. In fact, I didn’t really want to write that code anywhere.

Enter the SpriteKit scene editor.

I know many developers prefer positioning things in code over using tools like Storyboards or the level/scene editor, but I personally love the ease of drag-and-drop positioning and the ability to preview what things will look like without building and running the app.

This morning, I decided to create and animate some twinkling lights on the fence that encloses the sheep pen. Here’s the end result (and yes, the sheep are wearing scarves):

Snow scene

I could have written something like this to animate the fence sprites:

let textures = [SKTexture(imageNamed:"twinkle1"), SKTexture(imageNamed:"twinkle2"), SKTexture(imageNamed:"twinkle3")]
let twinkleAction = SKAction.animateWithTextures(textures, timePerFrame: 1.0)
fence.runAction(SKAction.repeatActionForever(twinkleAction))

Instead, I decided to make the fence sprites SKReferenceNodes (in case I want to use them in another level) and animate them using the scene editor. To do that, I created an .sks file that matched the dimensions of the fence and placed the fence inside it. Next, I opened the animation timeline at the bottom of the editor and dragged in an “AnimateWithTextures” action from the object library on the lower right.

SpriteKit animation editor

After that, all I had to do was tweak the parameters in the attributes inspector on the right. I set the duration for 3 seconds and dragged my textures from the media library to the “textures” box in the attributes inspector. Finally, I set the animation to loop forever. When I added added the SKReferenceNodes to my scene, they animated automatically. Piece of cake!

Tutorial Request: SKFieldNode

Attn: Lovely SpriteKit experts who write tutorials

I’ve been looking for a decent tutorial covering SKFieldNodes—a neat, recent (I think?) addition to SpriteKit that includes things like magnetic fields and radial gravity fields. Unfortunately, my searches have come up completely dry, and Apple’s documentation hasn’t been particularly helpful.

What I want to do is this: create a field node with a region matching the size of an SKSpriteNode’s texture. When physics bodies make contact with the texture/region, they’ll spin briefly out of control, much like hitting a banana in Mario Kart. I think I can do this using a small vortex field, but I’m not quite sure how and wish I understood all the various properties better.

So anyway, I’m hoping some kind soul will either write up a tutorial or create a demo app that shows each type of field in a separate scene along with physics bodies to interact with. Please?

In the meantime, if I figure it out, I’ll let you know!

February 15th – Progress Update

Corgi Corral iconYikes, I can’t believe it’s already been nearly two weeks since I’ve done this! I admit that I haven’t spent much time working on the game lately, mostly because I just haven’t felt very good. Besides the ever-increasing pregnancy discomforts, I’ve just been feeling sort of discouraged. However, I’m still determined to push through and release the game—no matter what!

Accomplishments

As you can see, I made an icon for the game along with a main menu screen:

Corgi Corral Menu Screen

The title falls from the top of the screen and does a little “bounce” when the app is first launched. As I was setting up the menu, I realized that if I used less text, it would be easier to localize the app into different languages. I switched “Options” to a little gear icon and “Leaderboards” to a simplified Game Center logo. I also changed the “Tap to Start” text to a tapping finger icon:

Screenshot 2-15-16

After that, I shifted my focus to finding the source of a small memory leak. According to Xcode’s debug panel, every time I restarted a level, the app would use about 1 megabyte more memory than it did the previous time. Eventually, I figured out that the app was holding on to a bunch of GameplayKit-related objects for no apparent reason. Like, all of the GKAgent instances should be owned by the sheep SKSpriteNodes, which should have been wiped out when the scene was set to nil. Instead, the game was holding on to their agents, their agents’ behaviors, and all of the GKGoal objects indefinitely.

Now, whenever the game enters its “Game Over” state, I explicitly remove all the GameplayKit-related objects. I think that fixed the problem…or at least, the Allocations instrument isn’t reporting leaks anymore.

What’s Next

Art, art, and more art! Probably going to work on Level 3 scenery, and maybe figure out how to draw a top-down view of a pig. :-)

That’s all for now…thanks for reading!

January 25th – Progress Update

It’s been a week since I last blogged; here’s what I’ve been up to!

Accomplishments

  1. I created some art assets for the second level/scene, which has an autumnal theme. The screenshot below shows a funny bug (now fixed) in which a sheep would spawn in the wheelbarrow and be unable to escape.

    Corgi Corral Level 2

  2. The corgi now blinks when idle and barks occasionally during the game.
  3. I created a struct called “LevelConfiguration” that reads information from a property list. The list contains information like how many animals should spawn, what the time limit should be, what sounds should be used, etc.
  4. For scene management, I decided to abandon the idea of a SpriteKit-only solution and ran back to something I’m more familiar with: UIKit and Storyboards. I set up bare-bones view controllers with simple UIButtons and UILabels that players can use to navigate to and from the main menu, options screen, etc. They’re not pretty, but they work, and now all I have to do is create art assets for them:

    Storyboard Layout

  5. After the timer for a level runs out, the game now waits 3 seconds and displays a score summary screen with options to retry the level, select a different level, or return to the main menu.

Under Consideration

Here are a couple of things I’m mulling over:

  • Whether to have the different levels/scenes progressively unlock, or to make them all available from the beginning.
  • Implementing a “medals” system similar to the one used in Flappy Bird with bronze, silver, and gold levels depending on how many critters you herd into the pen. And then maybe you’d need at least a bronze medal to unlock the next level? I don’t know. Still thinking about it.

What’s Next

Now that I have a very simple menu structure set up, it should be relatively painless for me to set up things like iAd, sharing a score via the share sheet, and adding an option to turn off the sound effects. My goal from now until the baby is born in March is to make it so that the only thing I have left to do is add the art, music, and remaining sound effects.

It looks like I started the Xcode project on November 20th, which means I’ve been working on this for a little over two months now (and sometimes only for a couple hours a week). With that in mind, and knowing that it’ll take me a long time to do graphics and music, I’m hoping it’s reasonable to expect the game to be ready to ship sometime before my birthday in July!

Herding Success

I finally found a decent fix for the GameplayKit/physics problem I’ve been fussing over for months (and that I wrote about yesterday). The good news is that it’s simple. The bad news is that it’s really only applicable to my particular game and probably won’t help anyone else that is looking for a way to get GKAgents to avoid the edges of the screen. Sorry! If it helps, I filed a radar about it.

Prior to figuring this out, I had just set my sheep to wander at a slow speed when they spawned. I set a low weight for the wandering goal because I mostly wanted them to flee from the corgi. I set the weight of each sheep’s fleeing goal high when the corgi approached, and back to zero when the corgi was farther away. I never changed the wandering goal.

The solution was to switch between the fleeing goal and the wandering goal, turning each completely on or off depending on the distance between sheep and corgi. I also assigned a higher weight to the wandering goal and increased the speed. Here’s the function that handles that logic:

func checkDistanceBetweenCorgiAndCritters() {
        enumerateChildNodesWithName("critter", usingBlock: { node, _ in
            let critter = node as! Critter
            let playerVector = CGPointMake(CGFloat(self.player.agent.position.x), CGFloat(self.player.agent.position.y))
            let critterVector = CGPointMake(CGFloat(critter.agent.position.x), CGFloat(critter.agent.position.y))
            let distance = self.distanceFromCGPoints(playerVector, b: critterVector)
            let maxDistance:CGFloat = 200.0
            
            if distance < maxDistance {
                critter.agent.behavior?.setWeight(100, forGoal: self.fleeGoal)
                critter.agent.behavior?.setWeight(0, forGoal: self.wanderGoal)
            } else {
                critter.agent.behavior?.setWeight(0, forGoal: self.fleeGoal)
                critter.agent.behavior?.setWeight(100, forGoal: self.wanderGoal)
            }
        })
    }

I call them critters instead of sheep so that I have some species-flexibility. ;) The above function borrows a method from Apple’s “AgentCatalog” demo project that calculates the distance between two positions. Now when the sheep get “stuck” along the edges, it’s only momentary because as soon as the corgi moves away, they’re super focused on wandering around.

https://www.youtube.com/watch?v=Grdr028WZFk

What’s Next
Here’s my short list of things to work on next:

  • Add some “flocking” behavior so the sheep tend to travel in cohesive groups.
  • Add a “run” animation for the corgi so it’s not just a legless blob.
  • Animate a little “+1” whenever a sheep enters the pen.
  • Add a pause menu with “resume” and “retry” options (and later an option to quit and return to the main menu).
  • Work on background art.

Spinning in Circles

I spent a long time messing with Corgi Corral yesterday. Too long, probably, because now I can hardly stand to look at it. I hear this is normal though, so I figured I’d take a break today and blog about it instead!

Awhile ago I wrote about the disconnect between GameplayKit’s agent system and SpriteKit’s physics world. I’m still working my way through these issues and have only managed to come up with partial, half-baked solutions. Specifically, I’m struggling with how to handle collisions between the sheep and the edge of the screen.

What Happens
When the sheep, who are part of the GameplayKit agent system, collide with the edges of the screen (an edge chain physics body), they “stick” to the edge and slide along it. Eventually, they all end up huddled against the edges of the screen.

What I’d Like to Happen
When the sheep collide with the edge of the screen, they should turn around and go the other direction.

My Failed Solution
I came up with something that almost works. When I detect a physics collision between the sheep and the edge chain, I run an SKAction that rotates the sheep in the other direction, like so:

sheep.runAction(SKAction.rotateByAngle(CGFloat(-M_PI), duration: 1))

That actually works really well in most cases. The sheep hit the edge of the screen, turn around, and go the other way. The problem is that when they hit the corners, or get pinned between the wall and other sheep, then they spin pretty much indefinitely, like so (tap/click to play the GIF, note bottom left corner):

spinning sheep

They currently have circular physics bodies, but I’ve tried a variety of other shapes and they still get caught in the Spin Cycle of Doom.

Why This Problem Even Exists
In essence, GameplayKit’s agent system and SpriteKit’s physics system are in constant conflict. In the “agentDidUpdate” method, the position of the sprite is always reset to match that of its agent after the agent carries out its goals for that frame. Therefore, the agent system essentially overrides the physics system. So what’s the point of giving sprites with GKAgents physics bodies at all? Well, mostly to prevent them from passing through other sprites and to be able to be notified of collisions.

What Now?
I have three hazy ideas for solutions, but I could really use some help. Here’s my thought process so far:

  1. Maybe there’s something I could do in the agent delegate methods? There’s got to be a use case for those besides just setting the position of the agent and the sprite.
  2. Another idea was that after rotating the sheep, I could apply an impulse to propel it away from the wall. The problem is, I need to know which direction to propel it, and I don’t know how to figure out which edge of the screen it hit. I’m also wondering if this could cause a similar problem with the sheep bouncing around the corners, unable to break out of the back-and-forth pattern.
  3. I could find some way to use the agent system itself to keep the sheep away from the walls. So far, adding the edge chain as an “obstacle” and ordering the agents to avoid it doesn’t work—I suspect because the edge chain is just a line instead of something with actual volume. I could add some large, clear rectangular sprites along (but mostly outside) the bounds of the screen and add those as obstacles maybe?

So yeah, I don’t know. The documentation on GameplayKit is still lacking and the dev forums are pretty much dead. I’m hoping this year’s WWDC will bring some clarity and new features to this otherwise nifty framework.

Got an idea for me? Tweet at me: @bhansmeyer.

Creating an Outlined Countdown Timer in SpriteKit with Swift

There’s a reason that most game developers don’t use Apple’s tools: they’re very limited. For instance, with UIKit, you can create a label and easily adjust its stroke color and stroke width. With SKLabelNodes in SpriteKit, those properties don’t exist. Therefore, it is (as of iOS 9 and Xcode 7.2) impossible to create an outlined SKLabelNode without doing some extra work.

I want my countdown timer in Corgi Corral to be white with a black outline. I combined two excellent tutorials to do this: Creating a Countdown Timer in SpriteKit with Swift and Outline Text in SpriteKit. Here’s the end result:

countdown timer with outline

In order to do this, you’ll need to use the great custom class ASAttributedLabelNode by Alex Studnicka. Just download the zip file from GitHub and copy the ASAttributedLabelNode.swift file into your project.

The timer tutorial has you create a custom subclass of SKLabelNode, adding several functions that compare dates and allow the label to update itself. I changed it to be a subclass of ASAttributedLabelNode instead and added two extra functions: one that formats the time as M:SS (single digit minutes and seconds) and one that sets the attributes of the string (stroke width, color, font, etc.). Here’s the full class:

class CountdownTimer: ASAttributedLabelNode {
    
    var endTime: NSDate!
    
    
    func update() {
        let remainingTime = timeLeft()
        attributedString = stringFromTimeInterval(remainingTime)
        
    }
    
    func startWithDuration(duration: NSTimeInterval) {
        let timeNow = NSDate()
        endTime = timeNow.dateByAddingTimeInterval(duration)
        
    }
    
    func hasFinished() -> Bool {
        
        return timeLeft() == 0
    }
    
    func createAttributedString(string: String) -> NSMutableAttributedString {
        let font =  UIFont(name: "Futura-Medium", size: 65)
        let textAttributes = [
            NSFontAttributeName : font!,
            // Note: SKColor.whiteColor().CGColor breaks this
            NSForegroundColorAttributeName: UIColor.whiteColor(),
            NSStrokeColorAttributeName: UIColor.blackColor(),
            // Note: Use negative value here if you want foreground color to show
            NSStrokeWidthAttributeName: -3
        ]
        return NSMutableAttributedString(string: string , attributes: textAttributes)
    }
    
    func stringFromTimeInterval(interval: NSTimeInterval) -> NSMutableAttributedString {
        let interval = Int(interval)
        let seconds = interval % 60
        let minutes = (interval / 60) % 60
        let timeString = String(format: "%01d:%02d", minutes, seconds)
        return createAttributedString(timeString)
    }
    
    private func timeLeft() -> NSTimeInterval {
        
        let now = NSDate()
        let remainingSeconds = endTime.timeIntervalSinceDate(now)
        return max(remainingSeconds, 0)
    }
}

Next, all you have to do is create a new CountdownTimer in your game’s scene class (by default it’s called GameScene.swift). Assuming your timer is named “timer”, whenever you want the timer to start, call timer.startWithDuration(seconds). In the scene’s update method, you can simply put timer.update().

Note: The end result of this is that you get an SKNode that you can do all sorts of SpriteKit-y things with. However, since it’s not actually an SKLabelNode, the vertical and horizontal alignment methods won’t work. You’ll have to position it like a regular node.

Obviously you can change the font to whatever you want, as well as the time format. And if you want to be able to have multiple timers with different attributes, you could always override the initializer to take a font name, size, color, etc. In fact, I might do that just to make it more flexible. Anyway, hope this helps somebody!