Tuesday, May 05, 2015

Movie Reviews: Avengers II, The Imitation Game, Whiplash, The DUFF, The Little Death

Avengers: Age of Ultron: Marvel be Marvel, eh?

The plot: a big fight of some kind with little explanation results in the retrieval of Loki's staff. Said staff is used by Iron Guy and Bulk to create "the ultimate" shield to protect humanity against future extraterrestrial threats, but they somehow didn't anticipate that the AI would decide that the best way to ensure peace on the planet is to exterminate all humans. Which is odd, because that's the plot of every other movie featuring AI that's been made since ever. Of course, there is no sandbox testing environment, no tests, no kill switch, no safety features, no network isolation, etc, etc, etc, like every other movie that apparently knows nothing about computer security. Some more fights, massive destruction of lots of property in the middle of cities without a single death, and roll credits.

The AI mcguffin is as dumb as it was written, but the idea of humans are hoist on their own petard is a little easier to swallow than the extraterrestrial threats of the last movie. And a big part of the final resolution involves trying to minimize civilian deaths, which is unusual. All of the main characters have screen time, including the "humans" Black Bubble and Mawkish who seem so out of place in the group. Then we get a bunch of new X-Men/d/d/d/d/d I mean avengers; it's the same kind of freak show (with some of the same characters) that made up the X-Men. The two franchises now look pretty similar.

Some more nitpicks: I'm still not sure why a god (Sore) is so un-godlike. The smart alec quips come in the middle of every fight scene, erasing any tension in them. I'm not sure why the best "safe house" is Mawkish's actual unprotected family home - with wife and children. The sudden love pairing between Bulk and Bubble comes from out of the blue, especially since I thought one of them had a girlfriend already. The absence of main characters from the specific movies (no Jane from Sore, no Pepper from Iron Guy) is glaring. And sure, everyone has a different special power, but they all amount to the same thing: blasting or blowing things up, so it all kind of washes together.

But the rest is fairly solid, as goes Marvel: the acting is fine, the directing is fine, the choreography and effects are top notch, and the story is serviceable.

The Imitation Game: Benedict Cumberbatch plays Alan Turing .We see him grilled and booked by the police for the 1950s indecent act of being a homosexual, interspersed with scenes of how he created Enigma to break the German codes ... and then played the mathematical game of how to HIDE the fact that he created Engima from the Germans, so as not to alert them that their codes were broken. This feat was a major component in the Allies winning WWII. Yet a decade later, Alan had to struggle with his orientation in a society that didn't accept it. The movie is ok, and educational if you don't know the history of Alan and Engima, but not a must see.

Keira Knightley plays a spunky anachronistic woman who serves no particular benefit to the movie except to be a woman, and to be Alan's most sympathetic friend; she also has to hide who she is, since apparently being a woman who knows math was as freakish to the 1940s as homosexuality.

Whiplash: Hmm. This move has little plot, which is not a bad thing. Instead it concentrates on the emotional dynamic between drumming student Andrew (Miles Teller), who is ready to endure everything to be great, and band leader Fletcher (JK Simmons), who is ready to abuse everyone in order to a) appear great, or b) find someone great. The performances are amazing and the abuse is highly abusive.

The drumming sometimes seemed pretty awesome, but sometimes seemed rather cacaphonic; from what I've read, it's not as perfect as the movie makes it out to be (but we hear that about every movie that depicts the struggle for excellence, so whatever).

I'm bothered by the movie, for a number of reasons. One, is it really entertaining to watch abuse on film for an hour and a half when the abuser doesn't get any comeuppance at the end? It's painful to watch if you've ever suffered abuse. Two, and this is the biggie: the movie seems to side with the abuser. Spoiler alert: In the end, the movie essentially says that the abuser got what he wanted and was right all along. WTF?

Three, the major plot "twist" of the last half of the movie revolves around Fletcher setting up Andrew to publicly fail on stage. But Fletcher sets him up to fail while he, Fletcher, is conducting, and Fletcher's motivation was supposed to be that he doesn't want anyone in his orchestra who would make him look bad. So it doesn't really make sense that he would do that. Four, it doesn't really make sense that Andrew would go along with it; he could have simply not played, rather than play badly. So I wasn't convinced by the final scenes at all.

But anyway: intense. Well acted. Kind of sickening.

The DUFF: A pretty standard teen romcom, with Mae Whitman, Robbie Amell, and the usual cliches. Perhaps the only non-cliche elements is that the two BFFs are pretty and have the vocal patterns and style of bitches, but they never actually act bitchy; instead they're nice and supportive. Which is pretty unusual for a teen movie, I suppose. Otherwise it's fairly predictable, but watchable.

The Little Death: This little 95 minute indie movie is drenched in sex talk (which you should know from the title, which is a translation of a French idiom for orgasm) and pathology (but no nudity). It's a Robert Altman-like film with five distinct couples (all white and straight, sorry) who overlap only very, very briefly; so it's really five different short films about sexual dysfunction.

For the first 70 minutes, we see four of the couples. Some parts are funny, some are predictable and dull, and one is offensive: not because of any prudery on my part, but because it involves a woman lying and manipulating her husband by intentionally causing him to feel sad (which turns her on). I guess this type of cruelty is funny to some people, but I nearly turned off the movie about midway; her scenes were grating. There is also a convicted sex offender who goes around giving everyone homemade cookies and telling them that he is required by law to tell them he is a sex offender, and no one seems to care about it; I wasn't sure what to make of his role in the film. He was kind of creepy, which was the point, I suppose.

I'm glad I stayed to finish the movie, because the last 25 minutes are devoted to Monica (Erin James) who works at a telephone service for the deaf - she answers video calls from deaf people, conveying their conversations to the people they want to talk to - and Sam (T.J. Power), a deaf graphic artist with insomnia who wants to call a sex line.

Think about the premise for a moment and you'll realize how funny this can be, and then multiple that by several factors and add real warmth: this was one of the funniest (and cutest) scenes I have ever seen in any movie. Ever. Erin is phenomenal: she's cute, she's prudish but accommodating, she's perky, she's funny. She's every boy's dream of a fun girl to hang out with. T.J. is similar: cute, funny, warm, and winning. The two have amazing chemistry. The sex worker (I don't know who plays her) and some bit extras complete the scene perfectly. You must see the movie if for nothing else than this scene.

Wednesday, April 29, 2015

How to Fail (but Still Succeed) in Corporate Gamification: a Real World Experiment

In February, 2015, I ran a low-tech, pilot gamification process to encourage my company's employees to install an analytics application on their and their family members’ handsets. This report describes the initiation and development of the project, its results, feedback received, analysis of what went wrong and right, and takeaways for future gamification processes.

Gamification in Business

In a business environment, gamification is the application of game and/or play mechanics to a non-game process with the aim of achieving a better result than would be expected without these mechanics. The theory is to motivate people to achieve the process’ goal – not by a job well done or a salary – but by providing engaging elements to the process and imaginary awards designed to be collected in parallel with the process’ goals.

In other words: you add something fun DURING the process that hopefully causes people to do the process well, where previously they did not do the process well due to poor motivation. For example, you include thematic elements (like racing cars or animals in combat), iterative goals, real-time feedback and measurements – like a running score – and a social element that may range from encouragement to cooperation to competition to rivalry. And you might bestow a title upon one or more people who complete the process, or who complete it the best, where “complete the process” hopefully doesn’t mean the person who had the most fun or achieved the highest score, but instead means the person who best completed the non-game process for which we were hoping to get better results.

Businesses are filled with processes that could be done better: showing up on time, showing up altogether, fixing bugs, reducing time for handling customer service calls, handling them better, completing projects quicker, or coming up with kick-ass ideas. For some of these processes, introducing gamification to the process leads to (or can lead to) disaster. If you gamify reducing customer service call time, you encourage faster turnover but worse service. If you gamify creativity, you tend to get less creativity (there are many sources for this).

Gamification works best when it is used to improve simple non-thinking or lightly creative repetitive tasks, like attendance, turnover, and fixing bad records in the computer. Even then, different kinds of tasks are better improved by different types of gamification. It takes some experience, knowledge, and skill to marry the right kind of gamification elements, benchmarks, and goals to the right processes. And because people get bored of the same games over time, applying gamification effectively is a continuous process.

The best way to gain experience in something is to do it. The best place to do a business gamification project is in the company in which you’re already working. Without a clear business case or experience that proves the process is going to save/make a lot of money, you need a pilot that is homegrown and small scale. If it succeeds, you find something larger and more costly to tackle.

The Process We Found to Improve

My company made software for mobile devices, typically installed at source by handset manufacturers or service providers. They were working on an Analytics client that could be installed on a device and which would report back various information about the devices, such as installed OS version, crash times, app usage, and so on.

This was not the first time they were working on this client. They had made two earlier versions. To test it, they wanted in installed on as many devices as possible. On each of the previous occasions, they had tried to get fellow employees to install the client; they got 7 to 15 device installations.

My boss wondered if a gamification project would help. (I had introduced the company, and my boss, to gamification a few months earlier.) Maybe we could get to 50 devices? Or even 100? He approached me. I considered for about ten seconds and said, with confidence, that a company of our size (250 people) could get 1,000 devices using gamification: each employee could install it on his or her own device(s) and three family members of close friends for the two month trial period. If the process was designed and handled properly.

My boss was initially taken aback – 1,000 devices? – but he told me to go for it. The company will get the client ready and the kinks worked out as much as possible, and I will design the game.

The Game as it was First Proposed

This was the email I sent as my proposal for the game:
We have 250 employees (approx) and I think that each one can install it on his or her own device and get 3 to 4 close friends or family to do the same. They only have to keep it on their phone for a month or two. The game is not for the general public, since the client is not yet ready for the public.

The game is as follows: Employees will be divided into six teams, each named for a color and an animal (e.g. brown bears, blue dolphins, etc). Teams include Israeli employees paired with employees in a foreign office. The launch will be at a specific date and end at a specific date. Each team will have use of a dedicated internal email list, and a web page will contain the instructions and each day's and the total scores.

Each employee will get some kind of token, like a pin, to wear in their color during the game.

Employees report daily to me their "captures" (I'm calling the game Handset Hunt), and I update the website with the scores (manually, which is a bit of a pain; we don't have the time to develop something better.) Naturally the server registers all clients, so we know how many devices actually sign up.

If the entire company gets to 1,000 devices, we all get breakfast. The best scoring team also gets dessert (even if we don't get to 1,000 devices).

The Thinking

This game involved nearly no resources; this is a small initiative by a low level employee with no budget, or almost no budget. It is not hard for me to tabulate a dozen or fifty emails in a day, and I wasn’t expecting more than that. The daily feedback would give people a metric to see with constant changes.

I thought two weeks was a good time: a longer period would not only drag out the time unnecessarily, since people would sign up at the beginning and end, but not in the middle, but that is would actually hurt participation, because people would just delay installing the client until they forgot. And that we couldn’t sustain the energy past two weeks.

The task would be simple to accomplish for one’s own devices, and not too difficult to persuade family members for a favor for a few months.

Six teams meant teams of 40 or so players each, pairing somewhat contiguous groups with offices around the world. We tried to keep some kind of coherence, and I was hoping that the tokens and the mailing lists would serve as a catalyst for team identity. I thought a tangible token would be a daily reminder to people that there is a game in progress as well as a possible source of team-identification.

The game included cooperation with teams, to instill a sense of identity, and a competition to foster competitiveness. There was no individual leader board, since I wanted everyone to do something, not something to be done in general by whomever could do it best (which is often what happens with a leader board).

The reward was to provide some additional incentive. Generally speaking, a gamified process solely rewards badges, points, bragging rights, etc. But I figured Israelis, all of whom are post-army, needed something real to incentivize them. Israelis are keen to avoid being a “friar”, that is someone who does something that he doesn’t have to do. They are dedicated when they have to do something that they think is important; many are also dedicated to both cooperation and competition.

The Trigger

I wanted the CEO in Israel, and the leaders in each region, to physically gather everyone together to launch the game and its stress its importance, hand out the tokens, and give some encouragement to participate. Either I didn’t make this clear enough or I was overruled by my boss, I can’t recall which; this trigger, or anything like it, never materialized. Instead, the game was launched by emails sent out with the game information.

Here was one of the emails:

Handset Hunt, a Gamified [Our Company} Game

[Our company] would like to test its Analytics client in the field. To do that, we need to have the client installed on as many devices as possible.

We are inviting you to play our game, which we call Handset Hunt. We are aiming for 1,000 client installations in order to perform a complete test. If we succeed, [our company] will take the entire company out for breakfast.

[Our company] employees are on the prowl to capture and tag mobile devices in order to test their Analytics client. Six packs of hunters will compete to tag the most devices.

Game Goals

[Our company] needs to test the reliability and viability of the Analytics client. The test will be performed by collecting information from many devices over the course of an eight week period.

Team goal: Get the Analytics client installed on the most devices by the end of the game.

Company goal: Get the Analytics client installed on at least 1,000 devices by the end of the game.

Teams

Employees have been assigned to one of six teams. Each team has 39 players.

All employees in each office outside of Israel are on a single team together with as many Israeli employees are required to complete the team size.

You are assign to [Color Animal] team.

Game Period

The game starts on February 4 and runs to February 25 at 23:59 IST (three weeks). This is the “game period”.

Rules

1. Install the Analytics client on as many Android devices as you can during the game period.

2. Ask your family and close friends to install the client on their devices.

3. Inform friends and family to keep the client on their device until at least March 15.

4. IMPORTANT: DO NOT POST A GENERAL REQUEST to your friends on social media or publicize this game or the trial in any public forum. The client is not ready for public use and contains proprietary source code that [our company] does not want exposed at this time.

5. Registration: Each day, email to [someone else in the company] the number of new devices onto which you or your friends or family have successfully installed the client. A daily update will be available on the internal Wiki. The URL is [URL].

6. All teams have an email list to be used as desired (encouragement, discussion, etc). You are receiving this email using this list.

7. If you experience any installation problems, mail [someone else].

Privacy

All information collected is aggregated and anonymous: [our company] cannot map collected information to any individual, and the system ID of the device is not mapped to a phone number.

You can find list of collected information in the game portal: [Portal URL]

Rewards

If the company meets its goal of 1,000 devices, all [our company] employees are awarded breakfast (specifics to be determined). All members of the winning team are awarded dessert (specifics to be determined).

Installation

[installation instructions for Android devices went here]

Teams [1]

  • Blue Dolphins
  • Orange Tigers
  • Red Bulls
  • Green Dragons
  • Brown Bears
  • Yellow Lions

Good luck, happy hunting, and have fun!

The Wiki had these instructions, together with a table at the top of the page listing the names of each person on each team, and the current day’s and total scores.

The Problems

Amateur

The immediate question is “Why not bring in a gamification company?” The HQ of one of the world’s leading gamification companies, Gameffective, was a mere 20 minutes from our office and I am friends with its CEO, Gal Rimon. The immediate answer is that there is no business case for gamification at the company; we were trying to build a business case. Spending tens or hundreds of thousands of NIS was not on the table.

So there was no framework, no individual point scores, no badges, avatars, fancy sounds or graphics, player props, levels, etc, etc.

Teams

The teams didn’t. See below.

Reward

No tangible reward is not a bad thing, and a substantial reward can be a good thing, but a small reward can be a disincentive - like leaving a very small tip. So this was probably a mistake. No one was motivated by the reward, though no one was really demotivated by it, either.

Token

The token was shot down during discussion with my boss and others as impractical; it was difficult to do when our employees were scattered around the world. I suggested that each regional manager could buy the tokens for their employees, but this was rejected. I suggested that, at least, each Israeli employee get a colored something, since I thought something tangible would be important. The result was this change:

The Israeli employees will get a colored paper to place on their desk to write down, which are the phone numbers of the people they got to install the client. Employees also report daily to me. At the end, the Israeli employees give me their papers "for corroboration".

In the end, we abandoned this too, since it was hard to find the right paper in the right colors and it didn’t make sense to give papers to the Israeli employees but not to the non-Israeli ones.

Task

An app that sends data about your phone to a company is not something that most people want on their phone, certainly not without very clear information about what the app does and how long it will stay on your phone. Company loyalty goes only so far. My boss agreed to give general ideas about what it did and a link to the portal with summary info. But he didn’t want to tell people how long to leave it on the phone. I wanted to tell people that they could remove it after two months, but he insisted we leave that out of the message.

So people didn’t have a clear idea of what they were installing, or for how long, or what kind of information was being collected. However, we told them that all data would be kept private to the company.

Also, the process was a fairly finite one. You could play once or twice, maybe a few more times than that, but then you were pretty much done.

Period

I wanted to run the trial for only two weeks. In truth, four days would have been right. My boss wanted four weeks, but agreed to cut it down to three weeks.

The trial was set to start sometime in October, but the client wasn’t ready, so it kept being pushed off. We almost started in December, but the foreign offices indicated that they did not want to run the trial over the end-of-year holidays. I found a new job and gave notice on Jan 19. Finally the trial started on Feb 6, scheduled to end after my time at the company was over on Feb 19.

Culture

I considered whether any of the offices would have a cultural issue with my theme selection of colors and animals. Would being on team dolphins offend the Japanese? Would being on the red team offend the Chinese? I didn’t know, but I didn’t follow through. I don’t think there were any problems.

Support

Any gamification project, unless it is a breakout hit with its audience, requires a champion to marshal enthusiasm among the troupes. In addition to the pitch at the kick-off meeting that didn’t happen, there should have been team leaders, daily events, and an enthusiastic guy (me) to go around spurring people to make the initial leap into the game. I had limited motivation: The game was supported by my company less than I had hoped and I was overruled on some design issues. I knew that I hadn’t made the best game, and the design was made poorer due to compromises that were required and some interference. I was leaving the company. On the plus side, I wanted to see the game succeed.

Reporting

Fielding reports was not difficult, and I dutifully put them up on the web site. However, many people forgot to tell me; we had more handsets connecting the server than were reported in the game.

What Happened

My boss and I made some attempts during the game to remind people about it, I posted once or twice on my team list to start a conversation, but to my knowledge, the lists were never used. Participation was about 10 to 30 handset signups a day during the first few days. By the end of the first week, we had around 120 handsets. A few days later we hit 140, and then nothing until I left the company. I called later for the final counts: 157 handsets.

So we “failed” to reach 1,000 handsets. But we succeeded in reaching over 10 times the number of handsets that had ever been reached in previous attempts. The data collected from the handsets, and the experience gained from the people installing them on various live devices, was invaluable to the client’s development. And it cost nothing.

Feedback

When I asked my boss about the experiment, he wrote: “We completed the development for the trail, we got the client installed on a nice number of devices, and we got insights from the trial. We did not promote it enough and did not get to all people.” In a future project, we should “Invest more in order to have the people on board, call the regions to sign up and call in order to share the insights and not trust mails.”

Here are answers to some questions I asked other people in the company about the game:

1. Did you sign up any handsets?

YES: 8

NO: 7

“I'm proud to be part of the team that signed up the most devices and also one of the two people who personally signed up the most devices.”

“Yes, about 4.”

“I had 5 or 6 handsets installed. All others in my family have iPhones.”

“Only my own.”

“Yes, me and my wife.”

“My family only has iPhones.”

“Yes, I installed the application on my device. I talked a bit with other office members, asking them why they did not installed the client. Half of them are using iOS… and for people who use Android, their device is old and with limited memory.”

“Did not sign up any headsets. Maybe I should have...”

“I signed 3 or 4 handsets not including my own, as the app did not work for me.” [for reasons]

2. Did the "game" motivate you at all to do so (or the general needs of the company)?

“The game definitely motivated me to sign up people.”

“No, I would have done this per personal request also, although it would have been nice to win a good breakfast on the company treat.”

“I think if it wasn’t for the game I would probably install it on my phone and maybe my son’s phone, but with the game I went out to find other people’s phones.”

“The game did not motivate me.”

“It is interesting for me to see the report and I am pretty willing to install the application on my device. I am interested in the game is because I am familiar with the product and I believe it is a valuable product.”

“The game slightly motivated me but not enough to make an actual effort.” “The general needs of the company.”

“The needs of the company motivated me much more than the game/teams/wins etc.”

3. What about the game worked for you and what didn't; what might make you more motivated in the future for similar projects?

It was cool to see the client working

“The fact that we could see the actual results and stats is great. I also see a lot of value in being able to use the server as a real demo and strongly believe that we should eat our own dog food, so to speak – so that worked. ”

“It was nice to receive the summary of the information that was gathered from the devices.”

Lack of triggers or didn’t understand the game

“I didn’t look at [the emails] at all.”

“The emails got lost in the general email clutter - maybe a more physical display of the progress such as the 'thermometers" that the old fund raisers used to use would have been a good idea.”

“One thing I need to complain about was the invitation plan. From the description email, I didn’t understand how to count the invited devices. I remember the email said once we have the application installed on a friends device, we need to write email to someone simply tell the number of the device as a score.. It looks very un-serious to me. Since we don’t need to send either IMEI or some solid proof of a device, while just sending the number of new devices… are you expecting me to be serious about the game?” [He went on to say how the lack of a rigid game methodology in counting devices, combined with the competition, made it seem like the game was based on “trust”, which he couldn’t wrap his head around.]

“This game basically sounded like a spam game to me...”

General problem with the activity

“It’s my personal issue with that kind of software.”

“I did not like the point that I need to install some useless app on my friend's phones... Specifically made for spying after usage statistics...”

“It did not work for me that the people who installed the app got no benefit from it – there could be a report showing some value.”

Lack of daily interaction/feedback

“The game didn't have enough presence or awareness in employees day to day... The reports on progress were not updated daily. There were no motivating follow ups during the game.”

“I did not see my device data in the final report. It is quite a pity to me.”

Problems with the teams

“I think that there was a lack in the sense of real competition, because the groups were not homogenous enough… in the sense that I don’t really know who was in my team, and even what is my team’s name. If my team was “product and marketing”, then I would more easily associate with them and encourage them to do more… but I was brown bears or orange tigers or something else, and the team included people from outside my immediate reference group…”

“Splitting for groups didn't really motivated me. Maybe if it was more individual and I could see online how many devices I registered against the others, it would turn the competition more personal and interesting. :)”

Registering should have been automated [something over which I had no control.]

“I believe the activation of the program should have done the report automatically instead of manual report.”

“Upon installation on device, the application should pop up a screen asking the user to choose which team he wants to register to. This is more intuitive.”

Lack of motivating prizes

“The prizes didn't matter much to me but I would have added some interim (real but small) effort recognition prizes, for example, best team of the week, top signer weekly, top signer, etc.”

“A more serious motivation might be some more real gift to the winners.”

“I would have participated more actively if there was a decent prize involved.”

“Some really cool reward or giveaway or activity for everyone on the winning team may cause more motivation. But the main motivation is not about a reward at all.”

Takeaways

If a lackluster attempt at gamification can achieve 50% participation and produce a 1000% increase in participation for an activity that few people really wanted to do, then there is something about corporate gamification that can work for business. A big portion of that, maybe the bulk of it, is simply promoting the idea that there is an activity outside of the normal work requirements that is important to the company, is not difficult to do, and can be done in a particular time frame, so “please do us a favor”.

It may be that 50% participation was achieved only because this was a “new” thing. Perhaps less people will be interested next time because it won’t be new. Perhaps more people will participate: the ones who did this time will do so again, and new ones will if they know more about it and the game is constructed and introduced properly.

Everyone is wildly different about what does or doesn’t motivate them. No one type of challenge suits all people. A game that provides a number of ways to play that hits multiple motivational points is more likely to succeed. Some people wanted clearer, more defined groups, others wanted more individual competition, while others didn’t care about the competition. The prizes mattered to people – not more than doing their civic duty – but this may have been skewed by the fact that we offered a small prize. If we had offered no prize at all (except bragging rights), maybe fewer people would have asked for a better prize. Or maybe not. However, a better prize would have increased participation.

This game was an example of “short burst” gamification. Different rules apply to long term gamification that is built into the daily routines of employees, Long term gamification has high exec buy-in, is taught to every employee, and becomes part of the daily routine. It must be changed regularly and kept fresh to maintain long term interest, but the rules of engagement are different.

In this process' case, a better game, with a dedicated team, a spiffier framework and graphics, a less frightening product, a more limited time frame, maybe a little less compromises on game design, a more serious buy-in from the execs, and daily enthusiastic communication would have been preferred. These would have gone a long way in achieving better results. I still think we could have hit 1,000.

Yehuda

[1] Pictures taken from various CC sources on Google

Saturday, March 21, 2015

Nimbicus: An original game to play on a children's bead abacus stacker

You can play a surprisingly good variant of a nim game on this bead abacus stacker that I found at a friend's house on Friday night. I call this game Nimbicus.

Here are the rules I devised on the spot [1]: The frame contains 5 pegs of different height, each of which takes, 1, 2, 3, 4, or 5 balls. There are 15 balls in five colors, with 1, 2, 3, 4, or 5 balls in each color. The game starts with all of the balls off of the frame.

On your turn you must do ONE of the following: 1) Take as many balls as you like that are all the same color and put them all onto a single peg, or 2) Take exactly two balls of different colors and place them onto two different pegs.

The peg(s) must have room to accommodate the balls you selected. The peg(s) on which you place the balls can have other balls on it from any colors; you don't have to match the ball colors already on those pegs. When choosing the first option, you can take any number of balls you want of the same color; for instance, if there are four yellow balls, you can take 1, 2, 3, or all 4, as long as there is space on a a single peg to place them.

As in other nim games, the last player to play loses.

Analysis

There are only 15 balls, which makes this a very limited game. What complicates this is the varying color choices and limitations imposed by the spaces on the pegs.

Let's refer to the available balls at the start as (5,4,3,2,1) and the available frame spaces as [5,4,3,2,1]. As options disappear, we can ignore ball colors and spaces that have no available choices. So, for example, if there are three balls remaining in 2 colors, you can select (1), (2), or (1,1), but only if the frame spaces allow for these selections. If the remaining frame space is [3], you can't select (1,1). If the remaining frame space is [1,1,1], you can't select (2).

First Moves

For your first move, you have 25 choices for selection: 1 ball from (1), 1 ball from (2), 2 balls from (2), 1 ball from (3), etc up to 5 balls from (5): that's 15. You have 10 more choices for (1,1) from the 5 available colors. That's the selection.

Now you have to place the balls. If you chose (1)  (5 different possibilities), you have 5 choices for placing. That's 25 possibilities.
(2) (4 choices) x 4 placement possibilities = 16
(3) (3 choices) x 3 placements = 9
(4) (2 choices) x 2 placements = 4
(5) (1 choice) x 1 placement = 1
(1,1) (10 choices) x 10 placements = 100

Add it all together and you get a total of 155 options for your first move.

End Games

Let's work backwards, instead.

1 ball

You lose if it is your turn and there is one ball.

2 balls

You win if it is your turn and there are two balls. Place one on the frame, and now your opponent has 1 ball.

3 balls

There are nine options for 3 balls. In some configurations you can force a win, and in others you have lost.

StateBallsFrameWin/LossComments
3.1(3)[3]WinPlace (2), leaving your opponent with one ball.
3.2(3)[2,1]WinPlace (2), leaving your opponent with one ball.
3.3(3)[1,1,1]LossYou must place (1), leaving your opponent with two balls.
3.4(2,1)[3]WinPlace (2), leaving your opponent with one ball.
3.5(2,1)[2,1]WinPlace (2) or (1,1), leaving your opponent with one ball.
3.6(2,1)[1,1,1]WinPlace (1,1), leaving your opponent with one ball.
3.7(1,1,1)[3]LossYou must place (1), leaving your opponent with two balls.
3.8(1,1,1)[2,1]WinPlace (1,1), leaving your opponent with one ball.
3.9(1,1,1)[1,1,1]WinPlace (1,1), leaving your opponent with one ball.

4 balls

There are twenty five options for 4 balls. In some configurations you can force a win, and in others you have lost.


StateBallsFrameWin/LossComments
4.1(4)[4]WinPlace (3), leaving your opponent with one ball.
4.2(4)[3,1]WinPlace (3), leaving your opponent with one ball.
4.3(4)[2,2]LossIf you place (2), you leave your opponent with two balls. If you place (1), your opponent is left in state 3.5.
4.4(4)[2,1,1]WinPlace (1) in the [2], leaving your opponent in state 3.3.
4.5(4)[1,1,1,1]WinPlace (1), leaving your opponent in state 3.3.
4.6(3,1)[4]WinPlace (3), leaving your opponent with one ball.
4.7(3,1)[3,1]WinPlace (3), leaving your opponent with one ball.
4.8(3,1)[2,2]LossIf you place (2) or (1,1), you leave your opponent with two balls. If you place (1), your opponent is left either in state 3.2 or 3.5.
4.9(3,1)[2,1,1]WinPlace the single ball in [2], leaving your opponent in state 3.7.
4.10(3,1)[1,1,1,1]WinPlace the single ball, leaving your opponent in state 3.7.
4.11(2,2)[4]LossIf you place (1) or (2), your opponent places (2) or (1) respectively.
4.12(2,2)[3,1]LossIf you place (1), your opponent places (2). If you place (2) or (1,1), your opponent is left with two balls.
4.13(2,2)[2,2]LossIf you place (1), your opponent places (2). If you place (2) or (1,1), your opponent is left with two balls.
4.14(2,2)[2,1,1]LossIf you place (1), your opponent places (1,1) or (2). If you place (2) or (1,1), your opponent is left with 2 balls.
4.15(2,2)[1,1,1,1]LossIf you place (1), your opponent places (1,1). If you place (1,1), your opponent is left with 2 balls.
4.16(2,1,1)[4]WinPlace (1) from the (2), leaving your opponent in state 3.7.
4.17(2,1,1)[3,1]WinPlace (1) from the (2) in the [1], leaving your opponent in state 3.7.
4.18(2,1,1)[2,2]LossIf you place (2) or (1,1), you leave your opponent with two balls. If you place (1), your opponent is left in state 3.5 or 3.8.
4.19(2,1,1)[2,1,1]LossIf you place (1), your opponent places (1,1). If you place (2) or (1,1), you leave your opponent with two balls.
4.20(2,1,1)[1,1,1,1]LossIf you place (1), your opponent places (1,1). If you place (1,1), you leave your opponent with two balls.
4.21(1,1,1,1)[4]WinPlace (1), leaving your opponent in state 3.7.
4.22(1,1,1,1)[3,1]WinPlace (1) in the single spot, leaving your opponent in state 3.7.
4.23(1,1,1,1)[2,2]LossIf you place (1), your opponent places (1,1). If you place (2) or (1,1), you leave your opponent with two balls.
4.24(1,1,1,1)[2,1,1]LossIf you place (1), your opponent places (1,1). If you place (2) or (1,1), you leave your opponent with two balls.
4.25(1,1,1,1)[1,1,1,1]LossIf you place (1) or (1,1), your opponent places (1,1) or (1) respectively.

Note that you always lose if the frame configuration is [2,2] on your turn, and you always lose if you're left with (2,2) on your turn.

5 balls and more

There are 49 options for 5 balls. Things continue to grow, but slower, for more balls, since limitations on spaces and ball colors begin to apply. The whole thing is not terribly hard to work out with a computer, but it doesn't appear to be easy to figure out for humans, unless someone hands you the winning strategy.

Variants

I created the game after showing my daughter the Towers of Hanoi puzzle on this. It's not hard to add a number of twists to the game to change the challenge. For example, you could say that certain colors are not allowed to be placed next to or on top of (like Towers of Hanoi) other colors.

Yehuda


[1] I vaguely recall rules similar to these in other games I have played, so the idea isn't original, although I think the game is.

Tuesday, March 17, 2015

20 API Design Tips to Stop Annoying Developers

Here is my presentation at DevConTLV March 2015, slide by slide, with my accompanying talk and some notes. I don't write down what I say on the slides, not do I have a script, so the text is an approximation.

This talk was supposed to be 20 tips to stop annoying developers, but I stopped counting at 20. You're welcome to count along with the presentation and tell me how many there are at the end.

Every example in this presentation represents an actual example I've seen while documenting APIs.

Just to clarify, the title of this presentation means tips to "stop doing things that annoy developers", not "stop developers who are annoying". Which brings me to my first tip ...


Don't name your APIs with names that have ambiguous meanings. English can be tricky; if you're not a native English speaker, get one to help you review your function and parameters names.

What's confusing here? "Barks" can mean "This animal can bark" or "This animal just barked". If a developer sees this, he or she can't tell which one you mean just by looking at it. Try one of the following.

Now the action can't be misunderstood. However, ambiguity is just the start.

Take a look at the first one, "can_bark". This turned out to be a problem for me when I was documenting an API.

Typically, there are two types of APIs. In the first type, all of the business logic is in the API. In this case, the application acts as a funnel, sending information to the API and passing requests from the API back out. The application is notified about things that happened on the server, or by the user, or on the device, or in another application, or even another part of the application, and sends the information to the API. In turn, the API sends things back to the application and the application sends it back back out to the world. For this type of API, the application isn't supposed to think.

My documentation was supposed to say when to call each API function, and what to do with the information sent back from the API. The developers included a sample application that had this API "can_bark" in it. I asked the developers "When does the application call this?" They said "When the API is waiting for it". But when is that? Just look in the sample application. That's not the point, I said. The application isn't supposed to have business logic in it. The application can't know when to call anything; it just responds to external requests. If it has to decide on its own, I need to write a whole new document on how to design the application's business logic.

Essentially, the developers had drifted part of the business logic to the application, instead of keeping it in the API where it belonged. As a result, you had an API that could not be called, let alone documented, because it didn't have access to information that was inside the API.

This API would have been fine if it responded to an event or call of some kind from the API itself. In other words, it didn't have to think for itself if it just responded to a request from an external source (the API) as usual, sending the requested information back to the external source.

(Another situation arose when new information arrived about an animal ("this dog can bark") to be sent to the API. The information could be sent using an API that already existed "animalUpdate", which meant that the new API wasn't required.)

The moral of the story is: don't split your business logic. If you use the kind of API that has all the business logic, keep the business logic in the API.

Another kind of API has none of the business logic and simply responds to requests from the application. For example, a device driver writes what the application tells it to write and reads what the application tells it to read. If you drift application business logic into this API, your next customer is going to want something different from it and you're going to have to redesign the API.  So don't split your business logic.

This is me. I worked for 14 years as a system administrator and a web programmer, until I switched to technical writing over ten years ago. Between my roles as technical writer, teacher of game rules, and now a designer of APIs, one of my major skills is to turn complicated ideas or topics into very simple ones. I teach complicated games so that they can be understood in only a few minutes, take 200 page documents and turn them into 120 page documents, and take 60 page documents and turn them into 2 page tech sheets.

I have documented dozens of APIs. When I get an API to document that is overly complicated, or would require a lot of documentation (and therefore a lot of work for the integrator to understand) because it doesn't match the rest of the APIs, I go back to the developers and say, hey, rather than write complicated documentation, let's rewrite the API. That gets me into trouble with some developers, but the product managers are generally happy. The result, in some of the places that I worked, was that API functions, names, parameters, and so on went through me before they were implemented. I sat in the design process.

Which makes sense. It's not enough for a web site to work. Nowadays you hire a UX designer to ensure that your web interfaces are clean and neat and don't drive away potential users. The same should be true for your APIs. It's not enough to say "they work!" If they are complicated, ugly, or difficult to integrate, you may drive away potential integrators.

In this talk I'm first going to talk about what makes a good API in general. Then I'll give some general tips for APIs, then some specific tips for specific instances, like actions and parameters. I'll end with general tips about documentation and delivery.

What is the object of an API?

It's the same object as your UI or your product: help your customers to be awesome.  (Note that I stole this idea from a fantastic lady and speaker, Kathy Sierra.) The ultimate object is not to have an awesome product. Your product should be awesome, of course, and you can sell that in your marketing documentation. But no one wants to use your API, or read your document, or even use your product (unless it's a status symbol). They use it because they have to in order to be awesome, to do what they really want to do.

People buy a cool bicycle because it has a tungsten carbide frame, cool anti-rust paint, blah blah. But then they have to use the bike - interface with it - and they don't want to spend time trying figure out your fancy features, If the interface isn't "get on the bike and push the pedals", it means that they have to read the manual.

"Have to" is not a Good Thing. People "have to" use your APIs or "have to" read your documentation. No one "wants to" do these things (unless you're a hacker who loves systems, like me), so it's a negative experience. They do them because they have to. If they can do it easier using someone else's product, they will. If they have to use yours because you have a monopoly on some kind of feature, they will; you have them over a barrel. But you're not going to make any friends by forcing someone to do something that they "have to" do.

The object of any API is the same as the object of a technical document: to have the user/reader use it as little as possible. Ideally, not at all. If they have to use it, You've already lost something. Make it as simple, quick, and painless as possible for the user to get in and get out.

Your job in writing an API is not to sell your technology. You should not write an API that goes "start the super cool dog grooming feature". The API should be "groom the dog". Keep focus on what the user wants to do, not on what a great feature you're providing. Otherwise, your API will be bloated and loaded with all kinds of things that you think are cool but are forcing users to learn your language, showing off features that are not helping them get in and out as fast as possible. Obviously, if a user has to use a feature, you have to provide a way for him or her to use it. But keep the focus on the user, not the technology.

(Here's another slide totally stolen from Kathy Sierra.) On the left is what you promise your customer. She's going to take a cool picture while climbing a mountain. It's going to be awesome. On the right is what you deliver to the customer: technological documentation and interfaces in love with themselves, all of which she has to wade through to get to the cool picture on the left. Again, some of this is inevitable; you have to describe how the camera really works. But keep the gap as small as possible. Focus on getting the user in and out of your API as fast as possible so they can get to being cool.

 So what makes a good API?

A good API (or document) is invisible. The customer doesn't feel it or see it any more than they have to. It is so natural that it doesn't feel like they are learning or using it.

A good API (or document) is unsurprising. If there's a left, there's a right. If there's an up there's a down. If it works one way here it works the same way there. It works the way every other API works. The user doesn't have to know something different to use every functions. It works exactly as expected, so that it needs no (or almost no) documentation.

An API that presents a few good features well, unsurprising, and easy to implement is better than one with lots of complicated features that have to be learned one at a time. Complicated, hard to understand and hard to implement. It may be inevitable that you have to provide something bad or complicated for a feature that the user MUST use, but minimize this as much as possible.

In the end, an API is good when the user feels that the money he or she spent on the product was worth it.

Have someone constantly looking it over to ensure that it's all consistent and logical, even if you are working in agile. Agile development adds features here and there as they come up without worrying about how they fit together as a whole. Ronit on Inbal's team added this feature, and Itzik on Moshe's team added that feature, and they all work, so done, right? No. Ronit used one kind of parameter set and Itzik used a different kind, and now the integrator has to learn two different methodologies to integrate them, which is annoying.

Keep a master plan for your actions, objects, parameters, and values, and keep it up to date with each new addition and each release.

Because it's very hard to change an API after it's released. If your code has mistakes and discrepancies that are hidden from the user inside the code, I don't care. You can release new code and fix it. When an API is released and customers are using it, it's painful and annoying to have to rewire an applications to incorporate the new API. It's worthwhile getting the API right the first time.

How do you write a good API? Think like a customer. A customer thinks: what do I want to do? Give the customer use-cases that show what your API does, and give him APIs that do things, with useful verbs.

An R&D team has access to all kinds of dummy information at all times. They forget that, in the real world, the integrator starts with nothing. If your API takes the list of dog breeds as input, where does the customer get that list of breeds? From this other API, that requires the list of dogs. Where do they get the list of dogs? From this other API that requires the list of kennels ... It's ok to cascade API requests, just make sure the developer can easily find the input for every API.


Then make sure they can use the results you send back to them as the input for the next API. Don't send back dog names in one API and ask them for dog IDs in the next. Unless the returned information is heading straight to a UI screen or a log file, your user is not a person, it's an application; it needs to feed the results of one request into the next.

How do you end up with this, where one function is camel case and one has underscores? Well, Ronit on Inbal's team added one feature, and Itzik on Moshe's team added the other feature. "It works!" But it's annoying. Don't do it.

Same thing for the parameter order and what gets passed. The first function takes a pointer, the second takes the variable followed by a Boolean, and the third takes the Boolean followed by a literal. How did this happen? Ronit on Inbal's team added the first one and ...

Here dogs are defined by a flat set of fields with feet and so on. But cows has a two-level structure of fields with limbs, followed by feet and hands. Be consistent in how you construct your data structures.

If a name or a term appears somewhere it should mean the same thing everywhere, and the terms you use for one thing should be the same for everything. Your pet store started with only dogs, and the names used "name". They added cats, and now they use "catName". Please. Also, "bark" means one thing, for dogs yes or no, but "bark" is the same word but has a different meaning, an enumeration, when used for trees. Be consistent.

Shorter is nearly always better. Shorter words are clearer and more logical. I know you want to be helpful by adding "is" and phrases and so on like this, but it's more to read for the user and not any more clear. In this case, the test "is this an animal" is always going to appear in an "if" clause, and it reads cleaner by just using the noun "animal", which means yes or no.

But there is a limit to being short. Don't abbreviate English words. Aside from being hard to read, you might run into abbreviations that can mean more than one word. I keep running into abbreviations or acronyms used by non-native English speakers that have unintentional vulgar or ridiculous meanings.

Here the type is "dog" but the user still has to define all of these other things, like the number of "legs" and the sound a dog makes, when these should be defaults. Use defaults.

Your company decided to rebrand. From now on dogs will be "BarkBuddies". That's fine, and the new APIs use BarkBuddies, but all the old ones still use dog. Don't do that. Yes, it's a pain to have your customers move to a brand new version of the API, but that's still better than an API that uses several types of terminology for the same thing. It starts with just a few functions but it always ends up as a mess.

Get someone to review your function names, parameter names, and so on BEFORE you implement them, not a week before delivery when your R&D team is too busy to revamp all of the code to fix problems. Because they won't. They'll say they'll fix it in the next release, but by then it will be too hard and too late, and they'll be working on new features.

In my jobs, new functions went through technical writing, but it could just as easily go through QA or support, as long as it goes through someone who writes English well and will push back and ask for changes.

And of course, make sure it really does work. An API with functions that don't actually work is annoying, too.

 Here are some more specific tips.

Use a consistent naming structure for your actions. For instance, if you add a new animal, always use "add". Or "create" or "set", whatever you choose, just always make it the same. One popular method is "CRUD" which stands for create, read, update, delete. I like to use "set" and "get" because it's short and sweet. But it doesn't matter, as long as the same thing always uses the same word.

If you're using a REST API, make sure your REST commands match your actions. Don't use POST for edit or delete, or PUT for read.

Here you create an animal using a single command, but you edit each animal using multiple commands. Why? Because Itzik from Eyal's team programmed ... Here you update each item in a dog using a different command, but  edit the same things in a cat using one command for everything. Don't do that.

Verbs set, nouns get. ParagraphCapital does not make the first letter of a paragraph capital, it checks if the paragraph is capitalized. Use a verb to set the paragraph. More simply, you set a state using setState, you get the state using state or getState.

Please avoid using Booleans, because they will always, always, (almost) always change to non-Booleans in the next version. You started the pet store with dogs. Then you added cats, so some developer added isDog to some commands. But other APIs defaulted to dog, so she used isNotDog. And then elsewhere she used isCat, just to mix it up a little.

Then you start selling elephants, snakes, giraffes, turtles, and fish. How many Booleans do you need to add now? Just avoid the problem. Anytime you want to add a Boolean, assume you're going to have to make it into an enumerated list up front.

Also, avoiding Booleans prevents your integrators from having to learn many new terms, especially if they're going to localize. It's one thing to learn a list of 50 or 60 words in your API, like "type" and "breed". Don't force them to learn all the English values, too. If your integrator is Spanish, he might not use "cat", he'll use "gato". So why should he have to learn that gato "isCat"? Minimize the number of tokens and avoid putting values in your action names.

 And I don't even know what this means. If you can tell me ...

For the same reason you shouldn't embed values in actions, don't embed units. Document the units. Also, the units may change, and you don't want to have to change the action names.

Here we have the animal type. The animal name. Number of legs. Number of heads, I think, or maybe number of tails. This must be the hair color and the breed. Then height? Length?

Anyway, don't do this. There is no need to add the number of legs once you know the animal type. If beagles are generally brown, there is no need for the hair color by default.

Here we wrap the parameters in a hash, so the meaning of each field is clear and we can leave out the defaults.

Try not to use a global state. For one thing, it avoids race conditions. For another, the application now has to use business logic to figure out what state it's in, how long to wait, how often to poll for the answer, and so on. Send the result back with an event, or a socket, or an email, or what have you. Let the application be dumb.

When considering resources, you may have dozens of ID fields for your database, your UI, some other system. Don't expose them all to the integrator; only give him what he needs. Also, don't return one kind of ID from one command and then require a different ID for a different command. We want to let him cascade the output of one command into the next one. He shouldn't have to look around for the information he needs.

Like actions, don't use Boolean parameters and don't embed the values in the parameter names.

I've seen this kind of documentation. It's not helpful. Remember, your result is being sent to an application, not a person. The application has to take the result and figure out what to do next, and for that it needs the exact list to parse. If something returns an enumeration, link to the enumeration or provide all the possible values.

Enums are good. Pass the enum code, not the value. This way the integrator can localize the results. So don't pass literals. In the second example, the developer tried to be clever by avoiding literals but concatenating strings together, but that's not useful if the result is going to a different kind of UI or if the language reads right to left. Pass the code and the values and let a utility do the substitution.

Don't use literals even if you don't plan on passing them on to the user. You might enjoy parsing a literal return value, but it's dangerous. If your API returns error code 22, the next person working on the API isn't going to change the return code to 23 just because it's his birthday. So you can expect it to remain the same. On the other hand, if your application parses the return value "no dogs found", it's going to break when the API changes all references to "dog" to "BarkBuddies".

The last example was also a problem, because you may have several results to pass back, and now you have to worry about parameter order. Pass the values back in a structure and let the utility figure out how to handle it.

What do we need documented for values? The range or possible values for the value. The units. Whether there is a certain subset of range or options that is recommended, like 4 legs. The default value or option, of there is one. Any dependencies between the values, like if that is above 4 then this has to be below 3. And where the implementer can get the value; which API returns the list of options for this value, so they know how to string the APIs together.

Speaking of documentation. A big problem with a lot of documentation is the writer assumes you know everything about the product before you start. Lots of documents start with "Welcome to our system. To log in ...." That's not helpful. Take a paragraph to orient your reader by explaining what your system is, and what the user can expect to do with it. Like a mini-table of contents so they know what to look for and if it's worth reading.

Don't waste their time documenting basic concepts like classes and programming ideas. But don't assume they know what your terms or products are or do. Don't just say it's a system for managing BarkBuddies. Tell them that a BarkBuddy is a dog.

Hyperlink so that they can get more information, so you they don't have to read the same information more than once. A content generation system like doxygen, JavaDoc, Swagger, etc does this for you.

Provide examples. Some people can learn the system straight from the examples, and in fact you may be able to get what you need just by cut and pasting the examples. And include a complete list of error codes that might be sent back.

Here's a very common source of annoyance. I hate documenting delivery packages, because I should never have to. They should be self-explanatory. Also, unless the API is a web page, no R&D team ever knows how the API is delivered. Is it a zip file? A DVD? How does the user get it? R&D teams don't even know this the day before, or of, or after the delivery.

But the delivery is the very first thing that the user interacts with. Please make it nice and clean. Make all the file names and directory names self-evident. Don't include parse.h and also parseNew.h or parse2.h . Clean it up! Remove everything that is not needed: files, directories, methods, and so on. Don't make the integrator wade through all these things he doesn't need, because he WILL call support and try to figure out what to do with them. Include the localization files and anything he can customize, like enums and configuration files.

Last tips. Consider a quick start guide to get the user up and running. Consider a cookbook that the user can cut and paste. And, if it makes sense for your API, consider a wizard that will generate the code with everything already in place without errors. Just make sure the wizard is up to date with the latest code changes.

Thank you.