Game Development Journal 5: Refactoring the Flower Cards for Protocols

After I posted my last blog post, my code was bothering me. It had code smell.

I wanted to get something started knowing I would go back and refactor things, but it still feels kind of bad to post what I now consider to be bad code, but that is kind of the point of this series of posts.

Good code, to quote a friend of mine
, doesn’t spring from the mind fully formed like Athena from the head of Zeus. It is an iterative approach where you get something out there and you work with it and figure out what you didn’t consider when you were theoretically approaching the code as an abstract concept.

Separating the Responsibilities

Part of the issue I have with architecting this piece of software was figuring out how to represent things in code. I want to avoid spaghetti code. I also want to avoid making something overly complicated.

I feel that my initial foray stripped out some necessary complexity.

I was trying to keep my card class as simple as possible. Without looking at the rules too carefully, I initial felt that it was only necessary to track the suit and the type of card:

struct Card {
    let cardSuit:CardSuit
    let cardType:CardType
    
    init(suit:CardSuit, type:CardType) {
        cardSuit = suit
        cardType = type
    }
}

While I was going through the initialization process for these cards, I realized that there were a few edge cases I didn’t take into consideration:

  • Collecting all of the bird cards gives a bonus
  • The ribbons are different colors and collecting all three ribbons of the same color is worth more than three different colored ribbons
  • Some of the Junk cards are worth two cards instead of one

I tried to address that in the key I assigned each card. Every card is unique and needed a unique identifier, so I figured I would represent these edge cases in the key, but that was a really big mistake.

”Stringly”-Typed and Safety

I was making everything in my deck, as Justin Williams says, “stringly”-typed.

Stringly-typed occurs when you are using a key to correlate to something rather than a property that can be auto-completed. Core Image is (or at least used to be) stringly-typed.

I was basing all of my programming logic in this application upon the hope that I would remember my own naming scheme and not misspell anything. That is a bad assumption.

Additionally, I was separating out the responsibility in the wrong place. The card should know everything about itself. It should know its type. It should know its suit. If it is an edge case, it should know that too. It should not be the responsibility of the programming logic to know that a card has a blue ribbon or not. The card should know that about itself.

So how do I deal with that?

Optionals?

At first I thought optionals would be a good way to approach this. I want to know if an animal card is a bird or not. I also want to know what color the ribbon is and if the junk card is worth two or not. I can make these optional properties on my Card Struct:

struct Card {
    let cardSuit:CardSuit
    let cardType:CardTyped
    let ribbonColor:RibbonColor?
    let isBird:Bool?
    let isDouble:Bool?
    
    init(suit:CardSuit, type:CardType) {
        cardSuit = suit
        cardType = type
    }

    init(suit:CardSuit, type:CardType, ribbon:RibbonColor) {
        cardSuit = suit
        cardType = type
	 ribbonColor = ribbon
    }

    init(suit:CardSuit, type:CardType, bird:Bool) {
        cardSuit = suit
        cardType = type
	 isBird = bird
    }

    init(suit:CardSuit, type:CardType, double:Bool) {
        cardSuit = suit
        cardType = type
	 isDouble = double
    }
}

This creates a few different initializers to accommodate each of the edge cases. Great, right?

Not really.

As I figure out more and more edge cases, the larger and more complex this struct is going to get. Also, none of these edge cases overlap. There will never be a ribbon card that is worth double or will have a bird on it.

So what is a better approach?

Protocols

It makes more sense to, instead of having an enum of different card types, to create a Card protocol that includes only what every card will require and then create different structs for each type of card that can be tailored to its specific edge cases and requirements.

The simplest card type, the one that has no edge cases associated with it, is the Bright type. All a Bright card needs to know is that it is a Bright and what suit it is. Since I can make a Bright struct that knows it is a Bright card, the only thing the protocol needs (that I am aware of) is a suit. I can expand on that later if I figure out further into the project that this was too simple.

protocol Card {
    var cardSuit:CardSuit {get}
    var cardName:String {get}
}

I am adding a cardName property because I want to eventually incorporate these structures into a command line program and later add a user interface. I would like to have something to display in the command line and later have a key that I can use to assign the correct card in the UI. I had that in my previous implementation, but I want to move it into the class because a few cards will be duplicates and I want to not have to make unique identifiers for everything, especially when the cards are the same.

Now that I have a Card protocol, I can apply it to four different structs that are tailored for each card type and its own edge cases.

struct BrightCard:Card {
    
    internal var cardSuit: CardSuit
    internal var cardName: String

    init(suit: CardSuit, name: String) {
        cardSuit = suit
        cardName = name
    }
}

struct RibbonCard:Card {
    
    internal var cardSuit: CardSuit
    internal var cardName: String
    internal var ribbonColor: RibbonColor
    
    init(suit: CardSuit, name: String, ribbon: RibbonColor) {
        cardSuit = suit
        cardName = name
        ribbonColor = ribbon
    }
}

struct AnimalCard:Card {
    
    internal var cardSuit: CardSuit
    internal var cardName: String
    internal var isBird: Bool
    
    init(suit: CardSuit, name: String, bird:Bool) {
        cardSuit = suit
        cardName = name
        isBird = bird
    }
    
}

struct JunkCard:Card {
    
    internal var cardSuit: CardSuit
    internal var cardName: String
    internal var isDouble: Bool
    
    init(suit: CardSuit, name: String, double:Bool) {
        cardSuit = suit
        cardName = name
        isDouble = double
    }
}

If I am working on the game logic and find another edge case, I can easily apply it to its specific card type rather than making it a global optional or having to reflect it in the card’s name.

Since every one of these cards conforms to the same protocol, I can create an array of anything conforming to the Card protocol.

let deck:[Card] = [BrightCard(suit: .January, name:"JanuaryBright"),
                   BrightCard(suit: .March, name:"MarchBright"),
                   BrightCard(suit: .August, name: "AugustBright"),
                   BrightCard(suit: .November, name: "NovemberBright"),
                   BrightCard(suit: .December, name: "DecemberBright"),
                   RibbonCard(suit: .January, name: "JanuaryPurpleRibbon", ribbon: .Purple),
                   RibbonCard(suit: .February, name: "FebruaryPurpleRibbon", ribbon: .Purple),
                   RibbonCard(suit: .March, name: "MarchPurpleRibbon", ribbon: .Purple),
                   RibbonCard(suit: .April, name: "AprilRedRibbon", ribbon: .Red),
                   RibbonCard(suit: .May, name: "MayRedRibbon", ribbon: .Red),
                   RibbonCard(suit: .July, name: "JulyRedRibbon", ribbon: .Red),
                   RibbonCard(suit: .December, name: "DecemberRedRibbon", ribbon: .Red),
                   RibbonCard(suit: .June, name: "JuneBlueRibbon", ribbon: .Blue),
                   RibbonCard(suit: .September, name: "SeptemberBlueRibbon", ribbon: .Blue),
                   RibbonCard(suit: .October, name: "OctoberBlueRibbon", ribbon: .Blue),
                   AnimalCard(suit: .February, name: "FebruaryBird", bird: true),
                   AnimalCard(suit: .April, name: "AprilBird", bird: true),
                   AnimalCard(suit: .May, name: "MayAnimal", bird: false),
                   AnimalCard(suit: .June, name: "JuneAnimal", bird: false),
                   AnimalCard(suit: .July, name: "JulyAnimal", bird: false),
                   AnimalCard(suit: .August, name: "AugustBird", bird: true),
                   AnimalCard(suit: .September, name: "SeptemberAnimal", bird: false),
                   AnimalCard(suit: .October, name: "OctoberAnimal", bird: false),
                   AnimalCard(suit: .December, name: "DecemberAnimal", bird: false),
                   JunkCard(suit: .January, name: "JanuaryJunk", double: false),
                   JunkCard(suit: .January, name: "JanuaryJunk", double: false),
                   JunkCard(suit: .February, name: "FebruaryJunk", double: false),
                   JunkCard(suit: .February, name: "FebruaryJunk", double: false),
                   JunkCard(suit: .March, name: "MarchJunk", double: false),
                   JunkCard(suit: .March, name: "MarchJunk", double: false),
                   JunkCard(suit: .April, name: "AprilJunk", double: false),
                   JunkCard(suit: .April, name: "AprilJunk", double: false),
                   JunkCard(suit: .May, name: "MayJunk", double: false),
                   JunkCard(suit: .May, name: "MayJunk", double: false),
                   JunkCard(suit: .June, name: "JuneJunk", double: false),
                   JunkCard(suit: .June, name: "JuneJunk", double: false),
                   JunkCard(suit: .July, name: "JulyJunk", double: false),
                   JunkCard(suit: .July, name: "JulyJunk", double: false),
                   JunkCard(suit: .August, name: "AugustJunk", double: false),
                   JunkCard(suit: .August, name: "AugustJunk", double: false),
                   JunkCard(suit: .September, name: "SeptemberJunk", double: false),
                   JunkCard(suit: .September, name: "SeptemberJunk", double: false),
                   JunkCard(suit: .October, name: "OctoberJunk", double: false),
                   JunkCard(suit: .October, name: "OctoberJunk", double: false),
                   JunkCard(suit: .November, name: "NovemberJunk", double: false),
                   JunkCard(suit: .November, name: "NovemberJunk", double: false),
                   JunkCard(suit: .November, name: "NovemberJunkDouble", double: true),
                   JunkCard(suit: .December, name: "DecemberJunkDouble", double: true)]

I know that dictionaries are faster than arrays to deal with, but this isn’t a situation where the array is going to constantly increase in size. These cards have been stable for a few hundred years, they are not going to dramatically change in any way.

Approaching this in this way has made my code a lot easier to deal with. I can sort all of the cards in the array by their type so that when I get around to writing the scoring logic it will be easier to simply pull out every card by its type. Anything I want to track, such as if a junk card is worth two, can be added to this set of code that I never have to touch again. I don’t have to remember how I named anything because I can track everything through its type and its properties. I kept the names so that when I read what cards I have in my hand I know what they are without having to remember what they’re called while I am doing my programming logic.

Conclusions

My new playground with the refactored code is here.

I wasn’t planning to refactor this code this early in the process, but I feel like this is a good illustration of why I am writing this series of posts.

I have seen many projects where they were built upon faulty assumptions. Rather than going back and rewriting the code, work-arounds were implemented making the code increasingly more complex and fragile.

Had I continued on the path I was on, the code base would have been incredibly difficult to maintain. There are probably still better ways to approach this, but I feel a lot better about the code currently than I did earlier this week. I want to idiot proof this code as much as possible and I stripped out some necessary complexity without thinking about how much harder that would make things for me later.

My next goal with this code is to figure out the best way to shuffle the array containing the deck. After I get that squared away, I need to figure out how to represent a player, a hand, and the game board. I also need to start writing unit tests for my code, but I will wait until later. No, I am not doing TDD. Jump in a river.

Until next time!

Game Development Journal 4: Representing the Flower Cards in Code

One of the things that drives me completely crazy about reading programming books is that I feel like there is a huge base of knowledge that no one ever talks about.

Over the weekend at Indie DevStock, Simon Allardice spoke a bit about how a lot of teaching materials are terrible because they bombard you with a bunch of facts. If you’re watching an instructional video about Swift the presenter will start showing you every single little menu in Xcode because it’s there and by the time you get to code you’re already irreparably lost and don’t really care anymore.

I see this too and have been guilty of it myself. Whenever WWDC comes around, I and other conference speakers obsessively look for whatever is going to be the new hot thing from the new version of iOS that we can pitch a talk on. We latch onto one thing and learn just enough about it that we can present a talk on it. We come up with convoluted reasons to use the new shiny object so that we can use it as an example in our talk. We go in and talk knowledgeably about this new thing and people come to see us and because we know more than they do (which is usually not a whole lot) and think we’re like experts or geniuses or something.

I almost never come out of a talk or a tutorial thinking about how this new API/tool/whatever is going to completely change my workflow. I will think it’s cool and will try to find reasons to use it, but I almost never have an organic reason for doing so.

There is almost always an easier way to do something than the way we choose. We choose overly complex solutions for things because we feel pressure to show off how smart we are. We write unreadable Swift code because having it look too imperative makes us worry we’re going to look like noobs and not be on the cool functional train.

My attempt to save us from ourselves is going to be contain in this series of blog posts. I am going to present part of an issue I need to solve in order to implement my game. I am going to go over several possible solutions and then explain why I chose the solution I did.

Sometimes I will be comparing an implementation in just plain Swift to using a framework provided by Apple. I hope to make all of this available on GitHub.

I would like to open up our conversations in programming from just “What is the new cool thing out” to “How can using this solve my problems?”

Choosing a Starting Point

The first problem is figuring out where to start. My initial inclination is to think about the user interface because that is the thing that most of us see and interact with, but that is the last thing that should be implemented.

I read a book a while back called Systemantics: How Systems Work and Especially How They Fail. At the first startup I worked at, they had implemented several systems to try and facilitate communication among all the employees about deadlines and so forth. We had about a dozen employees at that point, but we had multiple layers of systems. In order to update anything, you had to update it in about five different places. The engineers would look at the issue tracker in the Git repository and the managers would look at the Post-it notes on the SCRUM board. Their solution to this problem was to add another layer of systems on top of everything else.

All of these systems we put into place work against us and make us slower. It’s really important to only implement the most simple system you can that will fulfill your needs. Yes, once you read the size of a place like Apple you must have systems in place or else nothing will get done. But if you’re a small team of people, you don’t need a system as complex as one that Apple needs. You’ll spend all of your time maintaining the system and nothing will get done.

Another aspect of this book talked about how to build a system. This works for application architecture as well as for teams. The best way to implement a system is to build it out. You have to figure out what your most basic component is and get that up and running first. Once that is stable and tested and you feel good about it, then you can build out from there.

Since the UI is not the foundation upon which you should build your application, it is not the right place to start.

The most vital component to my card game are the cards. Having a card object in place and correct is necessary for me to build out the board representation, game logic, and UI.

So I am starting out building my card objects.

Creating My Flower Deck Structures

Next I need to really think about what my card objects need to do and what pieces of information they need to be able to carry and convey.

Godori does not use a traditional Western deck. Western card decks were outlawed in Japan, and so they developed their own deck that is the basis of many card games that originated in Asia. There are a number of differences between Asian flower decks and traditional Western decks:

  • 48 cards instead of 52
  • 12 suits of four cards instead of four suits of 13 cards
  • Not numbered
  • No court cards (King, Queen, etc…)
  • Each card must be one of four types: bright, ribbon, animal, or junk

Traditional decks are somewhat easy because most of the cards are numbered one through ten. In most Western games, court cards count as ten, so it’s relatively easy to assign values to the cards.

Flower cards are slightly trickier. You need to keep track of not only what suit a card is, but what type it is.

The 48 cards in a flower deck have the following composition: five brights, nine animals, ten ribbons, and twenty-four junk cards. Every suit has at least one junk card and at least two special cards. These are pre-determined and you can use a lookup chart to see what suits have what composition of cards, so this is not going to be a random or automated task.

Enums

The first thing that I notice when looking over these requirements is that there are two pieces of information that a card must know about itself: its suit and what type of card it is. Both of these pieces of information have a limited number of options. There are twelve possible suits and only four possible types. This seems like a really good place to create a couple of enums.

enum CardType {
    case Bright
    case Ribbon
    case Animal
    case Junk
}

enum CardSuit {
    case January
    case February
    case March
    case April
    case May
    case June
    case July
    case August
    case September
    case October
    case November
    case December
}

This sets up the way to track what special characteristics a card has that we care about for the game mechanics. Now we need to apply those to our actual Card data structure.

Class vs Struct

This is part of the whole value vs reference debate. Initially, I thought that I needed to make this a class, but I realized I was remembering it wrong.

When you’re dealing with something where there will only be one thing, you use a class. For example, if you were going to describe a camera where there is only going to be one instance of that camera and it would be passed by reference through out the application, it should be a class. But in this case, I am creating multiple instances of my cards that are all going to be passed by value, so it should be a struct.

The struct should always be the default data structure you should use unless you have a really compelling reason to make something a class.

Each card needs to have two values associated with it: a suit and a type.

Knowing all of this, it’s now quite simple to put together the card structure:

struct Card {
    let cardSuit:CardSuit
    let cardType:CardType
    
    init(suit:CardSuit, type:CardType) {
        cardSuit = suit
        cardType = type
    }
}

Now that I have everything that I need to create a card, I now have to figure out how to create a deck of them.

Data Types: Representing A Deck

This is the most complicated part to represent from this initial foray into development. There are a lot of data structures that can contain a bunch of Card instances, but there are questions about what the best one is and additionally, what is the optimal way to populate that data structure with the card representations.

There are several collection types in Swift: Arrays, dictionaries, and sets.

Initially, I thought about making this into an array. That is kind of the default data structure when you have a lot of something that needs to be collected together.

A set would also work as well. Initially, the order of the cards in the deck really doesn’t matter, you just need to have a collection of all the cards. But I still thought there was a better way.

One issue I have with this game is that every card needs a unique identifier. I need to have an easy way to hook up each card to its graphical representation.

I thought about creating a name property for the card in the Card struct, but I realized that I could create this collection as a dictionary. I can assign a string name to each card as a key to access it rather than having to access its name property within the instance.

There are also several cards within the deck that have special rules associated with them. Rather than creating a bunch of optional properties within each card, it’s a lot easier for me conceptualize just using each card’s name.

The point I am trying to make is that there isn’t a right or a wrong answer for how to pick the collection type for the deck. I see many tutorials where people default to an array because that’s the first thing that comes to mind. There is no explanation about how the programmer decided to implement the programming logic and it seems like magic how the person figured it out. I want more people to think through what problem they are trying to solve rather than rote copying of code without any thought or context.

I have also spent a few days thinking through if there is any way to populate the deck using loops and conditionals. I was trying to figure out if there was a way to do this like you would if you were programming FizzBuzz, but the deck was not mathematically generated.

Initially I was going to create a function to generate the deck, but since the cards are not going to change, I realized that making the deck as a constant was a better way to proceed. It’s still a crap load of code, but it only needs to be done once and will not ever need to be changed.

I have, for the time being, set every card manually. I wanted to give each card a unique name and ensure that the cards are created properly.

let deck:[String:Card] = ["JanBright": Card(suit: .January, type: .Bright),
                          "JanRibbon": Card(suit: .January, type: .Ribbon),
                          "JanJunk1": Card(suit: .January, type: .Junk),
                          "JanJunk2": Card(suit: .January, type: .Junk),
                          "FebBird": Card(suit: .February, type: .Animal),
                          "FebRibbon": Card(suit: .February, type: .Ribbon),
                          "FebJunk1": Card(suit: .February, type: .Junk),
                          "FebJunk2": Card(suit: .February, type: .Junk),
                          "MarchBright": Card(suit: .March, type: .Bright),
                          "MarchRibbom": Card(suit: .March, type: .Ribbon),
                          "MarchJunk1": Card(suit: .March, type: .Junk),
                          "MarchJunk2": Card(suit: .March, type: .Junk),
                          "AprilBird": Card(suit: .April, type: .Animal),
                          "AprilRibbon": Card(suit: .April, type: .Ribbon),
                          "AprilJunk1": Card(suit: .April, type: .Junk),
                          "AprilJunk2": Card(suit: .April, type: .Junk),
                          "MayAnimal": Card(suit: .May, type: .Animal),
                          "MayRibbon": Card(suit: .May, type: .Ribbon),
                          "MayJunk1": Card(suit: .May, type: .Junk),
                          "MayJunk2": Card(suit: .May, type: .Junk),
                          "JuneAnimal": Card(suit: .June, type: .Animal),
                          "JuneRibbon": Card(suit: .June, type:.Ribbon),
                          "JuneJunk1": Card(suit: .June, type: .Junk),
                          "JuneJunk2": Card(suit: .June, type: .Junk),
                          "JulyAnimal": Card(suit: .July, type: .Animal),
                          "JulyRibbon": Card(suit: .July, type: .Ribbon),
                          "JulyJunk1": Card(suit: .July, type: .Junk),
                          "JulyJunk2": Card(suit: .July, type: .Junk),
                          "AugBright": Card(suit: .August, type: .Bright),
                          "AugBird": Card(suit: .August, type: .Animal),
                          "AugJunk1": Card(suit: .August, type: .Junk),
                          "AugJunk2": Card(suit: .August, type: .Junk),
                          "SepAnimal": Card(suit: .September, type: .Animal),
                          "SepRibbon": Card(suit: .September, type: .Ribbon),
                          "SepJunk1": Card(suit: .September, type: .Junk),
                          "SepJunk2": Card(suit: .September, type: .Junk),
                          "OctAnimal": Card(suit: .October, type: .Animal),
                          "OctRibbon": Card(suit: .October, type: .Ribbon),
                          "OctJunk1": Card(suit: .October, type: .Junk),
                          "OctJunk2": Card(suit: .October, type: .Junk),
                          "NovBright": Card(suit: .November, type: .Bright),
                          "NovAnimal": Card(suit: .November, type: .Animal),
                          "NovRibbon": Card(suit: .November, type: .Ribbon),
                          "NovJunkDouble": Card(suit: .November, type: .Junk),
                          "DecBright": Card(suit: .December, type:.Bright),
                          "DecJunkDouble": Card(suit: .December, type: .Junk),
                          "DecJunk1": Card(suit: .December, type: .Junk),
                          "DecJunk2": Card(suit: .December, type: .Junk),]

There are a few special rules in Godori where certain cards, such as the ones with birds on them, are worth a special bonus if you collect all of them. I did not want to put a bunch of optional properties on the card class for instances that affect only a few cards. I am tagging those cards in their name to try and handle those edge cases in the programming logic rather than hard coding it as a parameter. There are other edge cases I have not dealt with yet and I will go back and deal with that later.

This is part of the problem I see when people talk about the promise of Swift. Swift is really good at removing lines of code, but only in situations where you have certain kinds of programming logic.

If you are parsing a file or processing some kind of information or a few other situations, Swift’s pattern matching and protocols is fantastic and allows you to remove a lot of lines of code.

However, if you are interacting with the Cocoa frameworks or setting up something with a lot of customization, such as the user interface, there are a limited number of things you can pull out and automate.

Since the type of card in each suit does not have a pattern that I can detect, I don’t think I can automate this with loops and conditionals in any way that will be clear later.

I am planning to go through this project and refactor it periodically, so it’s possible I could figure out a better way to automate the deck generation than to manually create each card and add it to the collection. Until then, I am entering each card.

Wrap Up

I have pushed this playground to GitHub. I know that right now it doesn’t look like much, but big things come from small beginnings. This is the foundation upon which everything else will be built. I fully expect to expand on this and refactor it as I figure out better ways to do things.

Things don’t have to be perfect when you first create them. You should be going back and looking over code you wrote before and looking to see if you can make it better based on what you’ve learned since you wrote it.

I hope to post at least one blog post a week on what I have done on this project. I hope to make steady progress on this application and for people to be able to see it come together.

Thanks for reading.

Game Development Journal 3: Learning to Embrace Higher Level Abstractions

For the last few months I have been working on a project that required me to write a simple game and apply Gameplay Kit AI to the project. I chose a simple tic tac toe game because it’s simple. It’s tic tac toe. Three year olds play this game. It should be easy to implement, right?

Wrong.

I have been bashing my head against this stupid game for months because I was trying to figure out how to do it in Sprite Kit. (To be fair, I have also been rather burned out and little things have been incredibly difficult for me to deal with. Please do not judge me.)

Sprite Kit is good for a lot of things. It’s good if you are doing a platformer game like Super Mario Brothers or if you’re creating an endless runner. Sprite Kit is not as good at doing things like tic tac toe or card/board games. I was looking through my books and tutorials to try to figure out how to tell the app that a square area of the screen represented a specific square of a tic tac toe board. Most materials are glorified rewritten documentation or they focus on the easiest examples they can possibly figure out, which includes spawning enemies and having sprites removed from the screen when they collide with onel

This was driving me batty. I knew there had to be a way to do this, but I felt like I was fighting the framework because the framework wasn’t designed to do what I needed it to do.

This problem was completely roadblocking me. I couldn’t think about how to write the programming logic until I figured this out. I knew I should worry about the UI after I got the logic finished, but this thing was completely blocking my ability to conceptualize how to approach this problem. I was incredibly upset because I knew there should be an easy way to do this but I couldn’t find it in any Sprite Kit examples I was seeing.

My mental block finally crumbled a few days ago when I realized I should not be using Sprite Kit for this project. I should use UIKit. Instead of trying to figure out how to programmatically tell the app that a square area on the screen represents a square on a tic tac toe board, I should just create nine buttons.

In Paul Hudson’s Hacking with Swift book, he recreates the Four in a Row Gameplay Kit example with Swift. I looked at the Apple example and found it incomprehensible, so I was incredibly happy to find he walked through how to implement and design that example more clearly.

One thing he did in that example was he did his entire user interface in UIKit with stack views. One thing he showed that I didn’t know you could do was to create a tag for each button in the stack view and connect all of the buttons to the same outlet and action.

I have my name on books. I speak at conferences. I have worked for some fairly prestigious places. For the last year or so I have let my pride get in the way of me doing things I need to do to be a better developer.

I do not have a lot of experience. I was at Indie DevStock this weekend and I heard most of the other indie developers I look up to had 15-20 years of programming experience. I have three. I think I am a pretty good programmer for only having three years of experience, but I know that I could be a lot better than I am right now.

I have tried to find a normal job so that I can pay my dues and learn from people with more experience than I do, but with one exception, that has not happened. I encounter other people who are like me. We feel like we need to pretend like we know what we’re doing rather than acknowledge that we need to work on our fundamentals and that working on fundamentals honestly takes a lot of time. If you’re working at a company that expects you to work sixty hours a week and you have to spend all your time pretending like you know everything, you don’t have enough mental or emotional energy to go and learn stuff that you may have known at some point in the past but you don’t remember now.

Also, honestly, we feel intense amounts of pressure to convince everyone that we’re a programming ninja. No one can just be a good, solid developer. Everyone has to be a 10x engineer. Everyone has to be a ninja. We’re all competing with one another to prove that we’re hot shit and that attitude is actively stunting the growth of members of our engineering community.

When I first started out, no one knew who I was or anything about me. I knew I could not get a decent job if people didn’t know who I was. I went to a lot of effort to network and make connections. I wanted to attend a lot of conferences, but couldn’t afford to go. So I needed to find a job so that I could make enough money to attend conferences to find a job. That didn’t work. There was a work around, which was to be a speaker.

I didn’t want to be the dumb-ass pitching beginner talks to conferences on stuff I figured everyone already knew anyway. I decided to go big and started talking about GPU programming with Metal and GPUImage. I had some grasp of how these things worked, but I couldn’t think of anything I could do with them. I just wanted to know them.

I tried to learn these things without any real context for where they should be used. This is not a good way to learn something. It’s mentally exhausting and draining. You feel stupid and your mental state deteriorates. You feel like a failure but you can’t give up because you want to prove that you deserve to be around everyone else.

I recently had a conversation with Warren Moore where I told him I wanted to learn Metal better but I couldn’t think of a project to do in Metal that I couldn’t do in Scene Kit. He told me that was the point. They weren’t intending for everyone to jump into OpenGL or Metal. Scene Kit was designed to do almost everything you need to do and only once you exhaust what Scene Kit can do should you drop down to Metal.

I felt like this was the most obvious thing in the world and I have no idea why it took me two years and a few nervous breakdowns to finally figure that out.

I have been so obsessed with trying to convince everyone that I deserve to be here that I have been focusing on the wrong things. I make things more complicated than they have to be. I don’t look for the simplest solution. I jump into the most complicated thing I can so that I can find an excuse to learn something that may not be the right tool for what I want to do. I do that at the expense of getting comfortable and familiar with the easy solutions that allow me to get things done more quickly.

I have been on a path that leads me to places I don’t want to go. I want to be a great programmer. Knowing how to render a triangle to a screen in Metal does not make me a great programmer. It makes me a clever programmer. Writing clean code that anyone can read and understand at the highest abstraction level makes me a great programmer. Knowing the higher level abstractions well enough to know what they can and can’t do and when to drop to a lower abstraction makes me a great programmer.

Right now I am not a great programmer. I am a good programmer. I can do 90% of what most jobs need me to do, but I want to work towards being someone who is respected in the community for being able to solve problems.

I don’t want to keep seeking out really low levels of abstraction and create convoluted reasons regarding why I am using them when I could do things much easier in another way. That’s just stupid and I am not doing it any more. That path leads to mental ruin and despair.

Game Development Journal 2: Getting Stuck in Boxes

This post isn’t specifically about the project I outlined in the first post, but it is a persistent problem I keep running into, even though I know the problem is there.

I am working on a tutorial for Ray Wenderlich and I have been running into issues with it.

My issue is that I have program-specific logic. I am creating a very simple game, but one thing I didn’t think about was the fact that you have to explain every little thing to the application. There are so many connections your brain makes automagically that a computer doesn’t know. You have to figure out how to tell the app how to think. This is the underlying issue in machine learning, but on a much larger and complex scale.

One reason I wanted to do a game application over a more useful type of application is because of application specific programming logic.

One thing I find frustrating, that is actually a feature of iOS, is how many frameworks there are. Sometimes I feel like when I am writing an app that you are choosing a framework, reading the documentation, and then just setting a few properties on that framework to make your app do something. So like, if you are doing something in SpriteKit, you’re choosing the image for the sprite, then you choose where it’s boundaries are, and you set a bunch of properties on the SKSpriteNode.

I have found that I get into a mindset where I feel like the only tools I have in my toolbox are ones that are pre-baked by someone else. If there is’t a framework for it or a property for it, it doesn’t occur to me that it can be done. The app is basically a giant state machine where your Swift/Objective-C code is just some glue holding together a bunch of pre-baked parts.

Whenever I am presented with a problem that requires a lot of program specific logic, my brain freezes up. It gets used to the idea that I just go pull a piece of code out of a box and it does what I want it to do. When I have to actually engage my brain in figuring out what my application has to do it’s like exercising a muscle I forgot existed. It’s incredibly weird.

I know that all of programming is supposed to be about figuring out what you want the application to do, but most of us don’t think that way. There are so many fucking blog posts by people trying to come with convoluted reasons to create hieroglyphic looking Swift closures that you need a Rosetta Stone to interpret. Most blog posts and tutorials are around talking about the components of a framework and not what you can do with it. Every game development book I see talks about how to use the tools of something like SpriteKit or Unity, but not how to think through how you would solve a problem.

The thing that prompted my last blog post was my expressing frustration that programming books talk about tools but not how to use tools to solve problems. I got a bunch of sanctimonious assholes telling me that if I read a book on algorithms it would somehow magically solve all my problems and telling me that if I read a half dozen different books that somehow I could cobble together all of the stuff I need to do what I want.

I think there is a better way.

I feel very frustrated that we, as a community, don’t talk more about how to think through how to solve a problem. Yes, there are multiple ways of solving a problem. So why not talk about it? Talk about how you tried a few different ways and you ultimately chose one specific way because it was the shortest or the most maintainable or the most reusable, etc…

We don’t do this because it’s hard.

It’s a lot easier to write a blog post saying you did something simple with SpriteKit that looks super impressive but doesn’t give anyone a visceral understanding of what they can do with it.

One reason I am running into problems learning Metal is because I don’t know what I am supposed to do with it. Almost anything I need to do in Metal can be done with something like SceneKit. I keep trying to learn the framework with no context as to why it’s important and what problems it solves. I get people hassling me by telling me it’s up to me to figure out why it’s important and that’s bullshit.

Programming isn’t an objective thing where every single app is a special snowflake. They all require us to think through why we’re doing what we are doing. I have fallen into a pit the last year where I have just automated that process in my brain where if I encounter a situation that doesn’t fit into a neat box my brain can’t deal with it. That’s fine for most of what most employers need, but I don’t want to be like this anymore.

I miss thinking about how to solve problems. I miss working on a portion of a project where I actually get to touch things and see how they connect rather than being told to pay no attention to the man behind the curtain because the code base is so fucking massive and poorly documented that no one knows how it works.

I am trying to shake away my mental cobwebs and remember that programming doesn’t have to be an automated process or something where you get into a pissing match with other people to make the most convoluted code you possibly can without breaking the compiler.

One of the goals with this series of blog posts is to explain a problem I am trying to solve and walk people through my thought processes in the hope that we, as a community, put more effort into talking about how we approach problems rather than seeing who can be the first person to get something running on the Apple Car, whenever it comes out.

Chocolate Covered Cherries

The following is a really bad metaphor, for which I apologize and will try to explain in better context later in this post:

Pretend you are walking down the street and you see a candy store on the corner. You weren’t really planning to get anything, but after you see the candy store you have an overwhelming desire to eat a chocolate covered cherry.

You impulsively decide to visit the candy store hoping they have chocolate covered cherries.

The man behind the counter greets you warmly and asks you what you want. You tell him you want a chocolate covered cherry. He says sorry, but they don’t have those today.

You’re kind of disappointed, so you thank him politely and turn to leave.

“We have vanilla cremes. Those are like chocolate covered cherries.”

You don’t want a vanilla creme. You wanted a chocolate covered cherry. You say sorry, but that you don’t want a vanilla creme.

“What about raspberry creme? That’s even closer to chocolate covered cherries.”

You politely but firmly tell the guy you don’t want a raspberry creme, you just want to leave.

“What about this hard sour cherry candy? Or this soft cherry candy?”

You start to get upset because you didn’t even really want any candy an hour ago and they don’t have the thing you want and now they won’t let you leave. You start to get angry and frustrated and upset because nothing you say will get this person to leave you alone.

The guy behind the counter gets angry with you and becomes vaguely threatening. “Look, I don’t understand why you’re being so upset. I am just trying to help you here. You have a problem and I am trying to fix it, so why can’t you be grateful to me for trying to solve your problem for you.”

You wind up buying a bunch of candy you don’t want just to get this person to leave you alone. You feel sick and shaken. You throw the candy in the trash after you finally get to leave the candy store and the man behind the counter smiles because he feels he did a good deed today by helping you solve your problem.

Not Listening

I have had so many issues over the last few years of people not listening to me. I get that in programming people want to solve problems, but sometimes a problem is not solvable. No one wants to say they just don’t have the answer to something, so they try to get super helpful and solve your problem for you even if all you want them to do is say “Sorry, I don’t have an answer.”

I understand that everyone wants to feel helpful. I understand that a lot of the esoteric problems I muse about do not have easy answers. By aggressively throwing a billion suggestions at me that I have to cobble together you are not helping me. You are upsetting and frustrating me because you’re not hearing that I don’t want a cobbled together answer. I want a chocolate covered cherry, not three different candies that are almost like a chocolate covered cherry. If there are no chocolate covered cherries, then I would rather be able to hear “What you want does not exist” rather than “Take these five solutions and mash them together.”

I also want to be able to tell someone they are not answering my question without them getting in my face and telling me I am being rude to them when they are verbally assaulting me with advice I don’t want. I’m sorry that you’re being presented with a problem you can’t solve, but bullying me into telling you that you’re being helpful when you’re not isn’t fixing the issue and you shouldn’t get to feel good about yourself at my expense.

I have the right to my own thoughts and feelings. I am not obligated to fight with you to be understood when it’s exhausting to me. I have the right to walk away, especially if I get to a point where I am emotionally disturbed without being further harassed because you feel I am being an ungrateful bitch for not accepting your well meaning advice. If I get to that point, the only way you can solve my problem leave me the fuck alone.

Game Development Journal 1: Planning Stage

I find myself with a period of time when I do not have large-scale immersive projects for other people that are absorbing all of my time and energy. For the last two years I have perpetually been working on a book, or trying to finish a project for someone else. As soon as I am done with one project, another one pops up. Work is like oxygen, it will fill every space in a room.

I have been dealing with some anxiety the last few weeks because as of right now there are no projects popping up immediately after I finish this current one. I am realizing that this is actually an opportunity to do something I have not done before, which is actually spearhead and complete a project of my own.

I keep meaning to work on my own projects, but then something amazing will come up and I will feel I can’t say no. Then I work too hard and get burned out and have no time for projects of my own. I feel like I can’t say no to amazing (paid!) opportunities working with amazing people for a gamble on a personal project.

There has been a lot of doom and gloom about how you can’t make a living as an app developer anymore because the market is too crowded and people don’t buy apps anymore, but I am realizing there are a lot of long term benefits to taking a few months to do an app.

Project Organization

One of the biggest complaints I have about working for other people is that they seem to not really know what they want. I have had a number of projects come to a grinding halt because the product owner keeps changing their mind about what they want. There is no point in implementing something if you’re just going to change it tomorrow anyway.

This also leads to project bloat. Once you start changing things or don’t have a plan in place to begin with, it’s really easy to add just one more thing. That “just one more thing” eventually becomes an endless laundry list and nothing ever ships.

I wrote a blog post recently about how this mentality completely destroys my mental health. I like to break my projects up into manageable tasks and I like to have an end, success goal when the thing is done.

I understand that as an app developer your code is never done as there are changes in languages and frameworks, but to me maintenance is different than active development. Adding a feature is another separate project apart from initially shipping.

By running my own project, I can control the features and the development schedule. I can firmly decide what features I want to have and prevent the project bloat. I can also figure out which tasks need to be done first and how to build upon those.

I want to avoid this situation. I like the idea of Agile, but in practice it’s usually terrible. I am really bad at reading other people’s minds about what they want and most people are really bad at expressing what they want. It’s like truthiness. It’s a feeling more than a concrete set of goals.

I am hoping that by actually setting out goals for a project and completing it I can help clients in the future focus their goals into something that has a chance at success. If I fail then I hope to at least get a perspective about why most projects seem to degenerate into chaos.

Why a Game?

I am choose to write a game. No, I do not plan to earn a dime from my application.

I am choosing a game because it seems to be more immune to the issues I talked about earlier. It has a set of rules. It has limited stuff that can be tacked onto it without fundamentally changing the nature of how it works.

I also want to dive more deeply into the Apple game frameworks and some of the Apple frameworks in general.

When you’re looking for a small, self contained project, it’s really easy to pick something that only uses UIKit, like a todo app or a Twitter client. A lot of companies want you to have knowledge of Core Data, but most don’t really seem to use it.

I want to get more comfortable with diving into an unfamiliar set of frameworks and getting something working. I could probably do this faster in something like Unity, but I would like to stick to the Apple frameworks. I might port it to Unity in the future as another project, but it’s not the goal for this one.

Godori

I am not going to be designing a game from scratch. That alone would take a lot of time. So I am going to implement an already play tested game I am familiar with.

I never was into video games, but I did very much like turn based games. I liked board games and card games where you had to think through things.

I used to play chess as a kid, but I really got bored with it because there were no random elements. It was possible to play the same game over and over again. That got boring quickly and I got into games with some more random elements.

There was a shareware game I played a lot as a kid called “War of Flowers.” I did some research on it over the last few years and found it was an implementation of a Korean card game called Godori.

Godori is like Korean poker, to the best of my understanding. The rules are somewhat simple. It uses a flower deck rather than a traditional playing card deck. The flower deck has twelve suits with four cards in each suit. Each card has specific aspects associated with it that affect scoring.

You also have the option to continue playing if you think you can accrue more points before the end of the hand.

This affords a decent amount of complexity and strategy without getting overly bloated. It has set rules it must comply to in order to work as designed. I don’t need to play test the rules because the game has been around for a really long time.

Components

I sat down and made a list (no specific order of importance) of all the parts I think I need to create to make a polished, nice application:

  • Game Logic
  • Artwork assets
  • Card Objects (the list of attributes and values for each individual card)
  • Playing Area
  • Setting up Game Center for people to play one another
  • Game AI if you want to play by yourself
  • Animations, sounds, and various polish
  • Cross Platform compatibility for at least iPhone and iPad

Some of these components build upon one another. It would be stupid to try and set up card animations before making sure the game logic works.

By trying to lay out concrete components that I expect the application to have I am hoping to avoid adding bloat to the project. I am also hoping to focus myself so that I don’t get overwhelmed worrying about how I will get the animations and stuff working before I even get the base programming logic in place.

Learning and Developing

I have a slightly tricky path I want to walk here. I have not really worked with SpriteKit or GameplayKit. My iOS experience is all over the board.

I know I tend to fall down rabbit holes and I am afraid I will get so absorbed in learning everything about SpriteKit that I will never get anything done.

I think I need to dedicate a certain amount of time to learning new stuff. I think that the entity-component system is probably the best way to implement the different values of each card, but I have not used it before. If I was just doing it in Swift I would probably have an enum or a protocol, which might work better, but I don’t know. I would like to have information about all of the tools I have available out of the box before I waste a bunch of time rolling an implementation that I didn’t have to.

I am planning, at this point, to alternate between working on tutorials/research and active development. I want to try to alternate days until I exhaust the tutorials and research. Then I might replace it with generating the art assets.

Long Term Strategies

One reason I want to alternate things is because I feel I have a crop rotation mentality for doing work. If I work on one type of thing too long my brain burns out. I need to have some variety in what I do in order to keep from exhausting the part of my brain that does code.

One issue I have had with contracting is that everyone only wants you to do the most labor intensive aspect of software development. There is no ability to stagger tasks with less demanding ones so you have a chance to recover. It’s like sitting there during a workout and doing only bicep curls. There are a limited number of bicep curls you can do. I would like to do my bicep curls, then go for a jog and then work on my legs. There should be a way of setting this up with programming jobs, but no one wants to do that. They want to force you to do the difficult stuff constantly until you burn out, then they replace you with someone else. Or even worse, you never get to work with anything because you’re too busy talking about what you would do if you did work with something.

I want to see if it’s possible for me to work in the way that is best for me and still earn enough money to support myself. That is the long term goal. I do not want to burn out after five years and then get promoted to management because I hate code and never want to do it again. I don’t think this game will earn me a dime, but I am hoping the professional things I learn from doing it will help me develop long term career strategies.

I hope to document every aspect of this on the blog. I want to explain how I solved various problems and implemented various parts of this application. This is probably overly optimistic, but I would like to to complete this in two months. I hope to not get derailed by mental health issues or just plain getting distracted by shiny objects.

If I work consistently for two months on this and it doesn’t get done, I am okay with that. I just want to develop a work ethic and strategy where I get things done every day without hurting myself.

My “official” start date on this project is September 19th. I am finishing my project tomorrow, but I am traveling to Tennessee for Indie DevStock. I also have a short contract after that and a tutorial to complete. So not completely free, but significantly less busy.

If you have been through this process and wish to share advice, I would welcome it. Get ‘er done.

Follow Up to How Not to Hire an iOS Developer

I got a lot of feedback from my post yesterday. One aspect of that feedback was people letting me know that I didn’t necessarily express what I was thinking and feeling quite properly. Wanted to clarify some of my ambiguous statements so that I don’t just come off as an entitled special snowflake.

First off, I did not mean to imply that I was doing this as a practice interview where I had no intention of ever taking the job. I talked to a recruiter a week earlier and was incredibly enthused about the job. I want to work on connected hardware/software products, which is still a rather niche field. I have realized that I will have to consider bigger companies with budgets large enough to do research and development in that area and a lot of what I heard sounded fantastic and right up my alley. But after I had a chance to look into this company I had some deep reservations about going to work there.

The recruiter said all the right things. I have several things on my list of things that I absolutely need to have if I accept a job. Some of those are easier to fulfill than others. I have accepted jobs based on the word of the person I was talking to that those needs would be respected and a lot of times they were not. I actually had someone say to me “Oh, you were serious about that? We thought you were joking.”

In the past I have had more freedom and flexibility to walk away from a bad situation. I live in a relatively cheap area where my burn rate is really low. I could go back to working in customer service or doing something that isn’t programming if need be to pay my bills. I could even swallow my pride and go to my parents with my hand out and ask for a loan, but that would be the absolute last resort. I would prefer not to, but that is preferable to me to moving to the West Coast. My monthly expenses here including my house and my car payments are significantly less than rent anywhere in any of the cities on the West Coast.

I feel that a lot of companies use the relocation stuff as a means of control. There are places where you’re expected to sign a two-year lease on an apartment. Companies pay to move you out there with the understanding that you stick around for a few years or else you’re on the hook for your moving expenses. You think you’re getting paid an awesome salary, but it doesn’t go as far as you think it will and you wind up living paycheck to paycheck. This puts you in potentially abusive situation where your company knows you can’t quit and that gives them carte blanche to abuse you because you have no choice.

I do not like being in situations I cannot leave. I would prefer to be in situations where I don’t want to leave, but I do not want to be trapped in a city thousands of miles away from my support structure with no way to leave if I am being abused.

I would like to move into integrated hardware/software products and design. The nature of hardware, especially proprietary hardware, means that you generally have to be on location. It is the nature of things. However, I will not sacrifice my physical safety and well being to pursue something I can just do as a hobby in my basement.

I acknowledge that if I want to do the things I am interested in doing, I will probably have to relocate at some point. I just do not want to settle and accept the first position that comes along without any assurances that doing so will not result in me jumping off a cliff. I can afford to wait things out and wait for the right thing to come along, and I am going to do so, even if it means taking a non-programming job to get by.

We’ve been conditioned to believe that abuse is a normal cost of doing business. If you want a tech job you have to tolerate being treated badly and run ragged in order to pay your dues to get to the next thing. That’s bullshit. It is not a necessary cost of being a programmer. This isn’t the Hunger Games. We supposed to be working towards creating a product, not trying to survive the harassment and abuse of our coworkers and managers while still putting on a show in the Productivity Theater while not progressing our skills any further. Fuck that. I am speaking out against it because it’s wrong and it is destroying our community and we need to fight back against this and insist upon being treated like human beings worthy of respect. If that makes me a diva, then so be it.

Another worry I have about moving is dealing with my dogs. I have one of my dogs certified as a service animal for emotional support issues. The other one is just certifiably insane. She can’t be left alone for long periods of time. One reason I have tried to get remote jobs is so that I can receive the benefit of therapy time with the service dog while not neglecting the non-service dog or letting her destroy my house.

Talk to anyone who lives in the Bay Area and they will tell you that no one wants a tenant who has animals. I can force the issue for Delia because of the law around service animals, but I can’t for Olive. Finding a suitable living space for both of my dogs would increase my housing costs tenfold.

I will not abandon my dog. When I adopted her from the pound I made a promise that I would keep and love her forever until she died. You don’t just dump animals at the pound when they become inconvenient. That is sociopathic and horrible.

Additionally, by living where I do, I have parents who can watch her while I travel for conferences, which is something I would give up if I moved to the West Coast. I would also have to find another doctor that I don’t hate. I went without a regular family doctor for five years because I could not find one that would actually listen to me. One told me that I probably fell down the stairs and forgot about it when I had weird bruising I was coming in about. Another one violated HIPPA by gossiping in the hallways with other doctors about a local patient who had to be taken to a mental institution. It’s a really stupid, small thing, but it’s that and a million other small inconveniences that make moving to another city a real pain in the ass that you don’t think about until you get there.

I also did not mean to imply that somehow understanding how the computer works is somehow useless. I am not a script kiddie. I care deeply about computer and software architecture. I am learning assembly language. I am learning how integrated circuits and computer chips are designed. I literally want to go all the way down to the metal to understand how things work.

However, I honestly don’t think asking people to implement algorithms in Java is the best way to gauge how good of a programmer someone is.

Code is a tool to solve problems. By focusing on people who are memorizing a list of common questions we use to filter people out of programming, you’re not getting a good feel for how they approach and solve problems.

Maintainable software is a problem I hear almost no one talking about. There are books by people like Michael Feathers and Martin Fowler talking about how to refactor and support long term projects, but we don’t talk to people about that.

Algorithms are especially a stupid thing to ask an iOS developer. I would say 90% of the work out there involves pulling data off of a server and putting it into a table view. You need to have a good grasp and understanding of UIKit and NSURLSession. Those are things you will use every day. Asking how to implement a linked list shows you have some knowledge of computer science but does not demonstrate that you know jack shit about the iOS ecosystem or its architecture. It might be a good programming question, but it’s not a good iOS question.

When you go and interview at a company, it’s a two-way process. I keep hearing people yelling at me about how the company has to do something to make sure I know how to write a for loop and I am not just a poser. It’s about protecting the company from hiring a fuck up.

There is more that I could do to establish myself that I am working on. I know I need to put more code out on GitHub. I know that I have been writing more about the social aspects of programming this year than on actual technology. I want to rectify that.

I have done as much as I can to show that I am not a fuck up. I am the coauthor on several books on programming. I write about tech on my blog. I present at conferences. Those credentials are clearly displayed on my resume. If you Google me there is a wealth of information about the projects I have worked on.

The fact that this company did not take five minutes to look into anything I have done (or even bothered to look at my resume before interviewing me) signals to me that this is not a good place to work. If they’re not willing to do the bare minimum to find out anything about me then I find it offensive that I have to prove to them that I know how to code.

I do not want to work for a company like that. I especially do not want to disrupt my whole life to move to another city to work for a place that does not do the bare minimum of having an interviewer who has a modicum of understanding about the job they are interviewing me for. If the guy interviewing me knows nothing about what I do then how can they make a determination about whether I am a good candidate or not? None of their candidates might be good. I have lived through that experience and it sucked.

When you get a bunch of programmers together who are all pretending to know what they’re doing, it results in a toxic situation where the incompetent people try to sabotage the competent ones who know they are full of shit. I do not want to risk moving my life to another city where an incompetent blow hard can sabotage my job and my career in a misguided attempt to save their own neck.

Taking any job, especially one that requires relocation, is a massive risk. There is a lot of potential for long term personal and professional damage by taking any job and I have been bitten in the ass often enough to be incredibly careful about fully vetting any company I think about working for to make sure I will not be quitting in two months and looking for something else.

This past year I have taken a lot of jobs that did not work out the way I wanted them to. I did not accomplish what I wanted to. I do not want another year like this. I want to do work I am proud of and not just collect a paycheck. I will not stop looking for that or demanding that the people I work for believe in what they are doing.

This company is probably thinking they dodged a bullet by not hiring the girl who doesn’t know what a linked list is. I am thinking I dodged a bullet avoiding a company where I would be miserable. Isn’t that the point of an interview, to figure out that you don’t actually want to work together after all?

How Not to Hire an iOS Developer

So my current contract ends on Friday. I have spent the last year bumping around figuring out what I don’t want to do and I now have to figure out what I do want to do.

As of this moment I would really like to make a real go of setting off on my own as a contractor and eventually producing my own products, but I know enough people who have not succeeded in doing this to be wary about my chances of success. Recently my father got drunk and trapped me in a car for an hour telling me to stop trying to be special and to attempt to find a real job with a 401k and health insurance.

So, in the interest of figuring out what I want to do with my life, I applied for a corporate job. I figured that it was stable and they pay regularly, so it might not be as bad as I had been lead to believe.

I had a phone screen with someone from a company today and I would like to share my experience with this.

The first part of the interview was awkward, but manageable. The guy asked me about some other projects I worked on. He asked me about a time that I didn’t agree with a manager and how that turned out. I probably should have come up with a different example than one where I got into a blowup fight and was fired, but it’s too late to fix that now.

At no point in this process was I asked anything specific about iOS. He did not ask me about my books or any of the other credentials I have on my resume. I realized that he did not look at it. Awesome.

Then we got to the part of the screen that I didn’t realize we were going to do: The Whiteboard Interview.

I have never done a whiteboard interview in my life. Never. I think they are bullshit and I decided a while ago that I would never participate in one. If you’re reading this and thinking of hiring me, I am not doing a white board interview. Be forewarned!

I had deep reservations about doing this. I know I know how to code, but code isn’t something you just regurgitate on command. It requires context and problems that need solutions. I decided before the interview even began that I did not want this job because it required me to move, but I thought I should at least attempt to get through the interview. I was beginning to deeply regret this decision.

We used a software application to do the white boarding. There was a drop down list of languages. I went to select Swift, but there was no Swift. Strangely, there was no Objective-C either.

Huh. You’re interviewing me for a job without being able to let me write in either of the languages you need me to be an expert in. Interesting.

I looked through the list and tried to find the next one I was most familiar with. After some deliberating, I chose C over Python.

“Don’t choose C.”

The interviewer did not want me to choose C. I asked why not.

“I’m an Android guy and I would really prefer that you pick Java because that’s the only language I know.”

You’re interviewing me for an iOS position and you only know Java. You won’t let me write in the language I am comfortable with because you don’t know how it works. Splendid.

He told me to write a linked list. I told him I didn’t know what a linked list was. I said I never got a computer science degree and that I was a hacker who learned programming by writing applications rather than learning algorithms and data structures you only use to pass code interviews at corporate entities that you forget and never use again.

At this point the interviewer was like, “Oh, so you’re not a programmer. You’re more of a management type.”

I have written books. I have presented technical talks at conferences. I have held down a programming job, more or less, for the last two years. I spent the first half of this interview explaining hardware software integration and architecture to this guy, who still at this point decided to tell me I am not a programmer.

At this point I had had it. I ended the interview as best I could. I told him I was not interested in the job and I got off the phone and had a good laugh.

I am writing about this on my blog because apparently these places don’t read my blog anyway, so it really doesn’t matter.

If you’re going to hire an iOS developer, let them write in their own language. Also, the power of iOS isn’t in the language, it’s in the frameworks. Don’t make someone write a fucking linked list in Java to see if they know how to write an iOS application. Ask them what frameworks they’ve used and how they find information and have them talk you through how something works.

This call annoyed me, but it also made me feel a lot better. As bad as I feel about not being as good a programmer as some of the other people in my circle, at least I am not a Java guy interviewing iOS people for a large company that clearly doesn’t know what it’s doing. I’m sure they’ll find someone who memorized “Cracking the Code Interview” to fake their way through the interview and panic on the job when they realize they don’t know what they’re doing. Hopefully they’ll buy my book.IDontKnowWhatImDoing

Depression and Engagement

One of the major issues I have dealt with so far in my short career is lack of engagement on many of my projects. My managers, for whatever reason, are not around to see what I am doing. They are on business trips. They are swamped with entirely too many other responsibilities. The product owner is ambivalent about what they want to do so we’re waiting around for them to make a decision about something. Not poking at anyone in particular, this has been an issue I have seen a lot of places.

As programmers we’re supposed to be self motivated. We’re supposed to be given a problem and we’re supposed to run with it and get it done. We complain about micromanaging and how it’s hampering our ability to get anything done.

When you get left alone on a project, initially it can feel freeing. You can work without being disturbed. But then at a certain point you realize that you have been given no guidance on what is wanted. It’s like creating an app with no auto layout. You kind of know that there are some components that someone wants, but you don’t know how they want them arranged.

This is the point where things start to affect my mental health.

I start to encounter mental friction where I can’t make any decisions because I don’t know what people want. I know that there is one way they want something but they’re not around to tell me what that is or they don’t know to begin with.

This triggers feelings of depression and despair. I start to feel that success is impossible. I try for a while to do my best, but at a certain point I shut down. I am overwhelmed by choice because I don’t know which one is right. I can’t function. Nothing I do is going to result in success, so why bother?

I feel tremendous amounts of failure and self loathing. I think that I can’t hack it. I should give up on programming. I should go back to working at a call center where there is a script and no decisions to be made. There is no pressure from coworkers trying to sabotage you or pretending like they know more than you do because no one gives a shit and they’re just there to collect a paycheck. You don’t have to pretend like you care about anything other than not getting fired. It’s soothing and restful.

I have had this happen often enough that I can see it coming. I try to engage but so far that has never been successful.

What I need to pull me out of this state is to have something I can solve or get engaged in. I have noticed I will be on the verge of a complete shut down when something will catch my attention. A small light will appear in the darkness and my deprived attention will fixate on trying to solve it. Then my brain comes alive again and I wake up and everything is okay again if only for a little while.

I want to talk about mental self defense here.

I have learned to find things I can do that will pull me out of this state. Usually it’s working on a tutorial. It’s a set of directions with an end goal. You feel like you’re getting something done. It will engage my tired and exhausted brain and lead it like a trail of breadcrumbs back home. It’s not open ended so I don’t get overwhelmed trying to get something working from scratch. I know other people can do that and I can too sometimes, but not when I am engulfed in mental darkness.

Managers don’t want you doing stuff like this. I have tried to talk to them about what I can do to pull me out of this state. I can’t work on the current project. It is causing me to shut down. Is there anything else I can work on so I can mentally recover?

They will purse their lips and say they really need me to keep working on the current project. It doesn’t matter that I am unable to make any real progress on it or that anything I write is going to be buggy as fuck, they want the illusion that I am working on their project.

If you’re working with a manager who isn’t giving you enough constraints to figure out what a successful end condition is, don’t mentally collapse. Try to recognize when you’re starting to shut down. Find things that can pull you out of it.

I know it’s hard to do. You feel yourself getting further and further behind. You’re in a mental terror that you’re going to be fired for not finishing your project. You need to calm down. You need to prevent yourself from going under at all costs. If you break yourself your project is not going to get done. You’re no good to anyone if you can’t function.

If you do break, it will take a while to recover. I see a Reiki therapist who helps me recover from my breaks, but she always tells me to take it easy after she helps me.

I have gotten better at going back to my “analog” hobbies to get away from a computer screen when I feel myself going under. Cooking and doing cross stitch are tactile and engaging and give me a project that I can see progress on so that I don’t go completely insane. It can feel like doing projects is a dodge or a waste of time, but it’s vital time that I need to help my brain recover so I can keep working.

I never think that I am going to feel better. I think that there is no point in trying to do a tutorial because I should just give up and accept that I am a failure. Sometimes I am too broken to work on it, but when I have had a chance to rest, I come back and I feel my brain slowly wake back up and I feel better.

The biggest reason I wrote this is to try and give hope to anyone who feels consumed by mental darkness. I have felt that a lot over the last few years. When you’re in the middle of it you feel there is no hope. You feel you can never do anything great ever again. You feel broken, like everything has been stripped from you and it can be hard to try and engage in something because you’re convinced you will fail.

Please know there is hope. Rest mentally and take baby steps. If you can’t engage in anything, then you’re burned out. Sleep, rest, hike, whatever. Then come back and pick up something structured and engaging.

Engagement is so important to what we do. We mentally need to feel a sense of accomplishment. We need to have tasks that we can complete and see progress in the work we are doing. Creating those meaningful milestones and discrete tasks takes time and mental energy, but it’s necessary to maintain mental health and stability.

A developer career is a marathon and not a sprint. If you injure yourself you need to rest and work your way back up to training again. You don’t want to force yourself over the finish line and wind up in a wheel chair.

Know that you’re not alone. There is a way out of the darkness. It’s not just you.

Off the Shelf Rapid Prototyping

One of my interests over the last few years has been to move more into hardware. My first real job was working with robotics systems and I fell in love with hardware. It was magical to be able to push a button and make something move and know that I am the one that programmed the directions to tell that thing to move.

I have been trying to get some traction in this area, but there is big signal to noise ratio.

One problem I personally have is what I like to call “If you give a mouse a cookie.”

Push the button! Do it! I dare you!

Push the button! Do it! I dare you!

Basically, I get consumed with figuring out how everything works. I get an Arduino and rather than just building something with it, I get consumed by trying to figure out how it was designed, why the chip they used was selected, how does the chip work, what other chips are out there, how do you design a circuit board…

I have been trying to figure out why this derails me so quickly. I realized that I get ahead of myself.

When I am trying to make myself turn an LED on with a button, I feel like it’s not hard enough. Anyone can drop fifty bucks on an Arduino and some LEDs and resistors and do what I am doing. I feel that it’s valueless and that I need to find some way to add value to differentiate myself from everyone else.

That’s getting way ahead of the game.

If you get a group of programmers and engineers together and have them look at something cool, they immediately start thinking about how they can monetize it. We just do. It’s part of our DNA. We can’t just do something cool because it’s fun. Everything has to have a purpose. If you’re doing something cool, there must be a product somewhere in it and you have to figure out how to make something cool before someone else has the idea so you can cash out on it.

Then there are people with the exact opposite approach. They will take something that is really simple, but looks complicated and they will try to monetize it immediately. Sometimes they get lucky and can cash out on a fart app or something simple, but a lot of times you wind up with garbage products on the market that are basically a sensor connected to a Bluetooth connector that talks to a bare bones app.

I want to spend this coming year more fully exploring this space. I think there is a lot of potential out here, but there are a few things to navigate.

  • What would make a good product?
  • What do I need to know?
  • How do I order the things I need to know so I don’t focus on a thing I need in five years before the thing I need tomorrow?
  • How much off the shelf stuff can I use?

The off the shelf question is the part that prompted this blog post. This is a wonderful time to get involved with hardware hacking. Arduino has really opened up things to everyone by providing a consistent and well documented rapid prototyping system. Companies like Adafruit have built successful businesses around the Arduino form factor and programmable LEDs. I think these things are really cool, but they seem to be toys and learning materials rather than serious tools with which to build embedded products. It’s going to take a leap from tooling around with pretty light rings to figuring out an actual real world application.

The other off the shelf question I have is with not just hardware, but services as well.

I recently bought a developer kit for the Particle Photon. So far I am really impressed with this device. It’s connectivity is through Wi-Fi rather than Bluetooth LE. It has an online IDE from which you can flash devices remotely. It is set up with IFTTT so that you can use it to build your own Amazon Dash Button among other things.

This is really cool. You can get a lot of stuff up and running in just an hour. However, I would not feel comfortable using this as a basis for a product I would develop because it has a single point of failure, which is that the hardware only interacts with servers that are controlled by the Particle people. This makes it really easy to get something up and running, but that means that if Particle was ever bought by someone like Facebook, like they did with Parse, you’re at the mercy of a vital service that could be discontinued at any point in time.

It’s really cool to be able to use an off the shelf component to get up and running, but it’s also important at some point to move beyond it. An Arduino is a generically designed device that is supposed to work with a lot of different things. The Trinket from Adafruit and many other development boards are “cheap” but they are not specifically designed for your purposes. I think that I need to be better about embracing these off the shelf solutions so that I can get a better idea about what I want to do and how to get something working, but I also need to keep in mind that if I develop something with these off the shelf solutions, I need to avoid single points of failure. But right now my single point of failure is putting the cart before the horse and worrying about these problems before I am at that point.

I am going to try and be more relaxed about embracing these tools for what they are and use them to learn before over complicating things. Life is a marathon and not a race.