Monday, March 7, 2011

Creating an iPhone Ad Hoc Distribution

There's always some step here that I forget, so here's my checklist of things to do in order to get a working distribution build for your iOS project:
  1. Make sure you have Default.png and Icon.png added to project
  2. go to developer.apple.com, create App ID (this is the "bundle ID")
  3. go to developer.apple.com, create distribution provisioning profile
  4. download distribution profile
  5. drag profile from Finder into XCode Organizer's "Profiles" window. This is critical.
  6. optional: add profile to the project. Sometimes this helps.
  7. optional: quit xcode & restart. Sometimes this helps.
  8. app target info, properties tab: edit Identifier to match App ID
  9. target info, build tab, configurations popup: choose "Edit Configurations..."
  10. duplicate Release config, rename "MyApp adhoc"
  11. build settings for adhoc, Code Signing: choose the adhoc profile
  12. build settings, "Packaging" section: edit "Product Name" to be what you want
  13. choose Adhoc / Device as your build target
  14. build
And you're done!

To distribute this app, you'll have to mail both the app (MyApp/build/MyApp adhoc-iphoneos/MyApp.app) and the provisioning profile to your users. If they have macs, they can use the iPhone Configuration Utility to install onto their device. Windows people need special zips (.IPA?) which you can find detailed elsewhere.

Tuesday, July 27, 2010

libAdMob.a missing from iPhone project

Did you check out someone's iPhone project (or sample code) from SVN and get a "library not found, -lAdMob" error?

That's because some SVN clients are set up to ignore .a files, which is how the AdMob library is distributed. What you'll need to do is to contact the person who checked in the project and get them to add the .a file (it's about 2MB) to the SVN repository. Or, you can download it yourself.

To download libAdMob.a, go to admob.com, sign up, create a new App for them, and THEN it will let you download the SDK code. No, you can't just download the SDK, the AdMob developers are a bunch of stupid cunts that don't want to let you have an easy day; they'd rather force you to sign up and create an app you'll never actually ship, instead. They *want* the clutter. They *want* to hassle you, one of their developers. That's because (and I hate to repeat myself) they are a bunch of stupid cunts.

Saturday, July 24, 2010

Sharing to Facebook from an iPhone App

First, let me say that the sample code provided by Facebook and others is teh suck. Some of the top hits when you search for stuff are broken samples. Be careful out there!

Second, the documentation itself is crap.

So I'm here to go over the flow that I used to share to facebook. If you're developing an iPhone app and want a "Share on facebook!" sort of thing, then start by perusing the readme: http://wiki.developers.facebook.com/index.php/Facebook_iPhone_SDK That's nice and all, but it's not shippable.

Background #1: Facebook updates. The 'stories' that appear on your wall, and are shared to your friends' home pages, are all little text doodads with links to content stored elsewhere. Adding a story to a user's wall is the simplest thing, and it's what most of those Facebook games do. There are status updates and then there are other stories; a status update is what happens when you don't include an actionable item (a 'call to action' type link). Mostly you just pull some key/value pairs together (see Facebook's list of attachments) then make a request.

Background #2: You can't upload images to a wall, only to your photo album, for example. Developers making utilities, games, and entertainment want to add a story that contains a custom image. You might note that most facebook games don't do that; they use a generic image instead, like a picture of a cow or sheep or barn as FarmVille does. Uploading a custom image is tricky. If you want a wall story with a custom picture, you have to either (a) first upload the image to the user's photo album (the default one has a limit of 500 photos, one dedicated to your app will have a 1000-photo limit), which means that two stories will appear back-to-back on the user's wall, or (b) store the image somewhere else instead and link to that.

What you wanna do:
0) First, allow the Facebook Developer application. Go to http://www.facebook.com/developers and 'Allow' it.
1) Create an application (see the image on the right). Yes, you might need to make your application page pretty.
2) Go to XCode. Create your own facebook helper class. I called mine FacebookHelper, cuz I'm creative like that. The point of creating this class is to not mix facebook delegates and dialog handlers and all that crap into your other classes. Posting isn't just one function call (there can be three or more callbacks involved), so partitioning it all into a separate class will help.
3) Add an entry point to this class. I haven't yet refactored this out; right now, I copy-n-paste the class into a new project and edit the implementation. So my entry point isn't
- (void) Share:(NSString*)shareText;
blah blah blah, but just
- (void) Share;
4) That entry point will look roughly like this:
{
if (self.session==nil || !self.session.isConnected)
 [self ShowLogin];
else if (!havePermission)
 [self AskPermission];
else
 [self PostToWall];
}
5) Write the FB login code and delegates. This means creating an FBLoginDialog and show'ing it.
6) If you need extended permissions of any type, create & show an FBPermissionDialog. Note that your FBDialog delegate callbacks will need to differentiate the type of dialog shown. I did this by sticking an enum in the dialog's "tag" field, and switching on it in the dialog:didFailWithError, dialogDidSucceed:, and dialogDidCancel: callbacks.
7) Finally, post to the wall. Do this by creating an FBStreamDialog, add an attachment string with all your parameters, like so:
 "name":"My App Name","message":"User enters this text, this is placeholder","caption":"etc"
These key-value pairs will include a link to your app and a link to the image to use in the post.
7b) If you're uploading an image to one of the user's albums, you use an FBRequest instead of showing an FBStreamDialog.
{
 NSMutableDictionary* args = [[[NSMutableDictionary alloc]init]autorelease];
 [args setObject:@"my caption" forKey:@"caption"];
 FBRequest* request = [FBRequest requestWithDelegate:self];
 [request call:@"photos.upload" params:args dataParam:image];
}

Later on I'll upload the entirety of the class so that you can see it all in process. Plus I'll probably clean this post up, too... meanwhile, I've got to run.

Saturday, July 10, 2010

some notes on learning

The best teacher will show you theory, give you both good & bad examples, explain why the bad examples don't work, then watch you try it and give you feedback. The lower the time lapse between trying something and getting feedback, the faster you'll learn.

If you don't have the spare $50k laying about to hire a personal instructor for your desired task, you're stuck searching and finding this stuff on your own.

Programmers

What if you're a programmer? The best place to go for theory is textbooks. Usually they're thick with theory but light on practice, and some of their theory will only work in the toy examples that academics are used to. But that's fine; you're here for the theory.

Good & bad examples are somewhat easy to google for. "Best practices" and "horror stories" are good keywords. Look for people that suggest bad experiences and ask them to expand on it.

Newbs tend to have bad habits, but finding out what those are and why they're bad is difficult. Books and didactic websites are again your best bets here.

The hard part is feedback. For that you need a coding buddy; someone (and I would suggest someone you don't work with) to serve as a sounding board, and will develop their own library of best practices, bad habits, and good feedback. You can give yourself feedback by (as I mentioned early) refactoring your own code shortly after you write it. Go back and rewrite the last app/utility/website you built! Might seem like "a waste," but it's amazing what you'll learn in the process.

Gamers

Game theory is woefully light. Good luck with that.

Good examples are easy to find; there's tons of videos of good players and really bad players. The hard part is figuring out why the good players succeed. Sorry. Good luck with that.

The easiest way to get better, actually, is to study mistakes. Look at people that get crushed and try to figure out what they did wrong. Fraps your own play and study it. A lot of people just hate doing that. Suck it up, cowboy. You'll learn fastest that way.

Three Steps to Being a Better Programmer

How to Be an Awesome Programmer in three easy steps:
1) Practice
2) Study the experts
3) Learn from your mistakes

Practice is by far the easiest thing to do. As I've mentioned before, I think the great lesson of Gladwell's Outliers: The Story of Success is that one gets better at something by practicing. In anything competitive, by practicing against better players (that's #2). But time on the field isn't enough; you actually have to learn something.

I've been thinking about playing Warcraft again, and in preparation I've watched a few Arena videos to get me motivated. That lead to watching some Quake videos, and that reminded me of my old days playing Quake. Obviously, the top players (at any online game) have played a lot. But time on the battlefield isn't enough; being smart by itself isn't enough.

I also read a number of "how to get better at Arena/Quake/Whatever" articles, and that led me back to Gladwell, a bunch of other articles and books, and eventually to the pickup community. A lot of people go to coaches for learning. This mostly gives the student a chance to find out who the masters are, so that he can study what they do. It's difficult to get better when you're around people that are as good as you; you're forced to learn everything yourself. Coaches will tell you what to practice, and they'll show you better players, too.

But learning that way is still pretty much learning by yourself. You just have better examples to teach you.

The better way to learn is to have a teacher. The teacher will look at your performance and suggest what to do different. They'll point out your mistakes.

That's the hardest part of getting better

Most people don't like to go back and revisit old work, but it's potentially the most instructive. And watching the pros at work isn't enough; a good teacher will point out what they're doing.

The the pickup community, "instructors" either "teach by example" (which is really doing what they do and then hoping that you figure it out on your own) or stick to mechanical skills (like body language).

In online games, there are no coaches; everyone learns by themselves. In this sort of community, the best thing to do is to play with the best.

In programming, the cost of practice is extreme; there's a plethora of experts; and they all say different things. About the easiest way to improve your programming is to refactor.

The best way to be a better programmer

The easiest way to improve is to try different tools, languages, and platforms. Until you try a decent interface builder, you'll probably think the one you're using is good enough. Until you try a functional language, you'll think your OO skills are all you need. Until you use a modern compiler, you might think the crap you have to do to satisfy your current compiler are acceptable.

Theory is nice. Where's the practice?

One of the things I learned while working on my other blog is just saying "try a new platform" is vague. Are there any that I could name that would be good?

Why, yes. Yes there are.

1) F#. Try building little Windows utility apps using it. Dive into the community to find better ways of doing it. Read a book or two and pick up the common wisdom.
2) iPhone dev. This is a great place to learn from other's mistakes, because the platform and tools are such utter shite. Seriously. The rest of the world is using modern compilers and tools that work. (OK, honestly, this entry is a bit of a joke, but you will learn message-passing.)
3) Find an open-source project using Perl or Python. Diving into one of these languages is the best way to learn them.
4) Website dev using C# and ASP.NET. Modern compilers & tools are an amazing thing.

I'm sure there's better examples out there; use these suggestions as a start.

Wednesday, July 7, 2010

Four Things Good Programmers Do

After a five-month ski vacation I'm back in civilization job-hunting. The interview process is interesting from the interviewee side, to see what many companies think that they want. To me, a good programmer isn't someone that's spent seven years with Technology X; in that much time one learns a lot of tricks, but good programmers don't just know tricks - they're supposed to be writing code.


#1 Ship

Good programmers finish what they're working on. I think being left in a cubicle by yourself makes it easy to succumb to creeping featuritis. To get caught up in 'perfecting' a system which might have a minor role in the finished product. Good programmers ship. They get things in shape to release, and they release. The more things you release, the more you learn about what customers want. And you also learn how to release better software faster.

To me the lesson of Outliers is that everyone learns by doing. The more you do something, the better you get at it. The people that are really good at stuff - from major-league sports players, to Bill Gates, to writers and artists - are good because they have had a lot of practice.

Spinning your wheels polishing bad code is practice polishing, not practice shipping. If you want to hire a good coder, you want someone that's had practice turning a working prototype into a professional, shippable product.

#2 Working

It a similar vein, good programmers write working code. I've worked with too many coders that write buggy code that barely works - or doesn't work at all. You'd think they wouldn't still have jobs programming, but the interview process is pretty damn flawed. It's like a first date. The interview I had today was mostly feel-good; a guy on the team liked talking about Agile and I could talk the talk. Walking wasn't really part of the discussion.

I'm surprised when I see someone check stuff in that doesn't actually work. It suggests that the programmer has bad habits and doesn't test what they write. To them, programming is something you do in the editor. As soon as their code compiles, they check it in and move on. Yes, I've actually worked with coders like that. They think they're gods; they think they don't make mistakes.

The good programmers on your team, the ones you want to keep and promote, are those that actually get stuff working. When a web page is supposed to do something, when a class is supposed to commit a transaction or pull data, it should do so. Some guys get 90% of the way there, and other coders step in and turn a code checkin into a working feature.

Mr. 90% won't be able to ship software. He might write a lot of code, but the stuff he checks in doesn't actually work. Ask your coders; they'll be able to tell you who on the team is Mr 90%. Fire Mr 90%.

#3 Robust

There's a lot of work that goes into the "foundation" of a feature. Some of it is gruntwork; creating the class, getting headers & dependencies set up; building the UI using a design tool. This is mostly monkey-work, and that's why bad programmers can get to 90%. Getting stuff working is the last 10% of the code that's written, but it's an essentially important 10%.

But once a feature works doesn't mean the work is done. Debugging typically doesn't add lines of code. Refactoring to get stuff working is likely to reduce lines of code. Good coders don't just run their code to see if it works; they test it, too. And they know how to write software that passes tests, and how to write tests that go after edge cases and corner cases.

Going after those edge cases is a mindset. Some programmers have, in the back of their mind, a demon that thinks of malicious calling code. What's the worst that can happen? What if they give me bad data? What sort of bad data is there? Are there possible race conditions that could screw up this process? Good coders have that demon.

"Agile" has turned into a buzzword that many software managers think they need to have. They think writing tests will remove all bugs. But if your tests don't test the right stuff, then your product will still have bugs - it will just take live testing by a QA group to find them. There's good practices in agile testing, but TDD won't get rid of bad programmers or make them irrelevant. The guys you want on your team write robust code the first time. That doesn't mean no bugs but it does mean they, as a habit, look for edge cases.

#4 Features

 I think somehow it has become verboten to discuss intelligence. Yet software is one of the few areas where intelligence has a very strong effect on productivity. Smart programmers get more done. They are good at solving problems, and they can keep track of several things at a time. If they need to keep that "what if" demon running in the back of their mind, the smarter guy will have an easier time at it.

Good programmers get features done faster. Per week, they get more features done.

It's grossly difficult to schedule software development. Agile development, in part, is a response to that. Instead of making up a list of features and then committing to a length of time to get that done, Agile commits to shipping something at a point in time. Some features are easier than others. It's hard to actually measure programmer productivity - but still true that good programmers are more productive.

Shipping Feature-Rich, Robust Software

Software development is about shipping. Guys in academia and research departments can fart around for decades and you can call it good work, but out here in the real world we need to ship software. The more features you have, the better your market position. The more robust your software, the happier your customers will be.

Good programmers make that happen. They write the code, it works when they check it in, and they know how to go after bugs. And they do it all quickly.

Hire those guys; they'll make you rich. :)

Friday, June 11, 2010

The Thousand-Hour Sim, Part 1

One of the ideas I mentioned yesterday was that there's only a few genres where a large number of players (10,000 or more) will be willing to spend multiple hundreds of hours playing the game. There's a lot of games were a good chunk of the audience will spend around 100 hours. Many single-player RPGs have that much content, and a lot of multiplayer games will keep players busy for 100 hours.

But take a game like WoW - there are millions of people that put in hundreds of hours every year, and probably millions that have put in over a thousand hours over the six years since the game has come out. Some of the friends that I worked with averaged six hours a day - usually spending a dozen hours on the weekends and a few during the week. That works out over 2000 hours a year. Even if they burned out in six months, that's a thousand hours right there.

Competitive games, like Starcraft and Counter-Strike, are another genre where thousands of people might spend thousands of hours.

What would you have to do to make a sim that could keep at least tens of thousands of players occupied for a thousand hours?

Summary of the FMMORPG Argument

There were eight factors I mentioned when I described Fantasy MMORPGs as the ultimate genre. They are:
  1. environment variety
  2. tangible, human-scale environment
  3. non-trivial gameplay
  4. opponent complexity
  5. opponent personality
  6. solo and group gameplay
  7. inspiration
  8. open end-game
The first factor means having a wide range of environments. The second suggests using an environment that can be rich. Gameplay needs to be complex, and getting to a really rich complexity means not just having a complex puzzle but introducing AI units into the game that introduce complexity, keeping the game fresh. The fifth factor, opponent personality, is like the second: it puts a face to the game world that players can relate to; an environment that produces stories. The sixth factor is about allowing players to play whenever they want, while also giving them team goals, where they can work towards goals larger than one player. Inspiration (and something I didn't mention, commitment) are ways of giving players long-term goals to keep them coming back. The final factor says that the game can't end after a hundred hours; allowing players to stay in the same game world for the entire duration of their play-time can keep them there.

The factors can be broken down into a few threads. I'll probably redo this list at some point. Obviously, this list isn't definitive; I'm building a model for game design and there are surely many other models just as suitable. Anyway, the points I'll cover today will be:
  • Gameplay needs to be rich
  • The game world needs to be rich
  • The game has to enable stories and emotional moments
  • It should allow the player to play, and make progress, whenever they want
  • The game should provide large goals, requiring time and/or teamwork
  • The game should have an anchor that commits players to the game
Some of these feel essential to me, others feel like caveats.

Positive Attributes

I think some of the attributes should influence the core game design. The game should be built around these principles. These are the things you should be trying to do when you design the game. The negative attributes, which I mention later, are a list of things you link at and think, is there something in this design that will drive away players? I think the negative attributes can be tweaked - that once the core game mechanics are nailed down, the next step is to go through a list of "gotchas" and make sure there's nothing there that would piss off players.

First I'll tackle the attributes core to game design.

Gameplay needs to be rich. This is the single most important attribute. Without rich gameplay, the game becomes rote quickly, and play-time becomes boring. I've talked about the essence of fun before, and my theses on boredom is that it happens when the player doesn't have to think about gameplay; if the time the player spends thinking about decisions is too small. As complex as the game might be, if the player has mastered the game rules then there's nothing more for him to learn.

Take a game like Halo. They introduce new mechanics throughout the game and, by the end, you've explored all of those mechanics. Once you've beaten a level, there's no reason to go back and play it again, except maybe to find a few hidden secrets or complete it faster. New sequels really just introduce a larger game world; they don't add new gameplay elements. Players spend 20-40 hours playing through the game, and then wait two years for the sequel, then spend another 20-40 hours.

Compare this to Grand Theft Auto. The worlds are about as large, but there's a richer variety of things to do. As a result, players can spend 100 hours in the world. There's only about 100 hours of "quests" in the game, though. If they added more quests, would you keep playing? Probably not, because without more mechanics, execution of those quests becomes easier and easier. As you play through the game, you pick up new weapons and learn new game skills - but you exhaust those skills by the time the game's done. That's what I mean by new mechanics: there'd have to not just be a new place to play (ie a larger world, such as in the expansion packs) but new ways to play.

The game world needs to be rich. I touched on this above. The world shouldn't just be large, but provide new environments. There are over sixty different zones in the world, and each one has many different sub-areas. Plus well over 100 different dungeons. The starter zones can be plowed through in under an hour, but by level 50, there's at least five hours of quests in each zone. The dungeons provide a couple hours of gameplay but can be replayed, too. Each of those zones and dungeons has its own creatures; usually dozens in each zone, and each creature type (like, say, furbolg) has several variants (such as warrior and shaman).

That means a lot of art assets, of course, but that's what "rich world" means! Players can easily spend ten hours in Stranglethorn Vale. Although the whole zone is jungle, the land ranges from the beach, to the river, to hills, to villages, to caves. Creatures include pirates, goblins, trolls, panthers, tigers, raptors, basilisks, and ... much more. Each little area has its own story (told through the quests) and there's a few greater storylines that take players through the zone.

Worlds are rich because of the variety of their assets and they stories they tell. Speaking of which...

The game has to enable strong emotional moments. Stories are a player retelling of emotional moments. The strongest emotions are fear, anger, and love. WoW doesn't really want to anger its playerbase, but anger does have a greater place competition-driven games (and therefore in the PvP aspect of WoW). Fear is the most common, but it's not often remembered as such. The most memorable moments for me in WoW were when I was running in fear from high-level enemy players, or in instances when our tank died and I was panicking trying to keep the group alive (I played a healer!), or close calls when I got attacked by several creatures and was running for my life. When these encounters ended well, that fear turned to extreme relief. I wanted to tell everyone I knew about what just happened, and the story got retold the next day at work, too.

Strong emotional moments make the game into a larger part of the players' lives. When we take those stories to work the next day, to the pub, into our dreams, its more than just a way to pass the time. Am I going to tell stories about that one time in FarmVille when I planted some corn? Ugh. We hate the boring coworkers that tell that kind of dumb story. NO. Yeah, sometimes those WoW stories are the same - but not always.

Players can feel love, or something similar, in these games, too. Probably a bit more common is respect, and dedication. Players in guilds might feel commitment to their guildmates, and want to show up on raid night not just because the raid will be fun but because they want to help their guild out. It's really cool to have a good tank in the group, or to have a great healer behind you, or an awesome DPS guy that is super-great about handling adds. I really respect those players and their skill with the game, and that generates stories that I want to tell, too. (But god I hope that raid is fun, too. See section one: gameplay should be rich.)

Curiosity can also be a strong motivator. Curiosity drives suspense novels and thriller flicks. It's usually not something that the designer would want to drag out for dozens of hours, but there are a lot of cases where a bit of curiosity keeps me playing for an hour, or to keep coming back to a quest line for an hour of play every so often. Some quest text can introduce a mystery, and either dole out new bits of story in each quest or give the player a chance to go exploring and find out the solution for themselves. This is a kind of meta-game; the game proper is combat, but if you've got a player hooked on a mystery they'll play through the combat to find out who done it! Yet another way of making gameplay richer, and in this case it works because of the emotions that the game makes players feel.

The final "core principal" is: The game should provide large goals. One of the things I've bitched about with browser games is that they don't feel like there's a larger goal. Travian actually has one, and it's a very appealing goal to me, but they did a crappy job of advertising that long goal. I played Lord of Ultima for about a week but quit mostly because I felt like I had no goals. Sure I can sit there building my city up, but who cares? Compare that to Nile Online, which I'm still playing: the goal is to get to a high enough level that you can "retire". When you do, you get a pyramid built and named after you! At that point, the game is "over" and one can leave the game, but at least it's a motivation to keep playing.

MMOs provide many large goals. To get to max level, to get into a raiding guild, to get to the hardest raid instance, to get awesome gear. Even just to complete the easiest end-game raid instances is a large goal, taking weeks of play to prepare and attempt. Single boss fights used to last a half hour or more though these days they tend to be 10-15 minutes. Each fight might take a few attempts to master, and there's around ten bosses in each raid. Throw in trash encounters (which can be tricky to master as well) and "raid night" is several hours of gameplay each week.

Accomplishing large goals tends to drive other gameplay. Preparing for raid night might mean running dailies to get cash to buy a new piece of armor, or to get enough faction to be allowed to buy a new piece of armor. Hopefully those dailies are fun and don't get too repetitive, one of the few places where I think WoW falls down. But consider this like curiosity: players will engage in hours of gameplay (hopefully fun by itself!) in order to achieve a meta-goal. They're not in combat to kill the creature, they're not killing the creature to gain rep, they're not gaining rep to buy new armor -- they're buying armor to make more progress on raid night. And they're doing that for bragging rights and to support their friends.

Non-Essential (Negative) Attributes

One can probably come up with a huge list of  rules saying "don't fuck up your game by doing X". I happened to extract two from my previous post; there's dozens more that I've thought of since (another post?) but I'll cover these two in some detail to explain what I mean.

Players should be allowed to play whenever they want. If your basic game mechanic is combat, then what would keep them from playing when they want? I heard EQ basically couldn't be played solo - which meant, if you wanted to play, you've got to wait around to find a group to join. One of the things that I think made WoW wildly successful is that it doesn't have this restriction. If you log in and want to play, there's always, always some solo task you could do. You can hop into a PvP battleground, go on a solo quest, do a daily, farm some crafting resources, or find a PUG instance to run.

This principle is better expressed in the negative: don't add anything to your game that would prevent players from playing when they want to. Not being able to play is frustrating, and one of the things in browser games that piss me off. I'd enjoy them a lot more if I could play at my own leisure. Having the game say "sorry, go away, we don't want you" makes me feel bad things towards the game and that's a great way to lose players before they hit the 1000 hour mark. And it kind of means that they can't hit 1000 hours. It's basically admitting that you don't even have 1000 hours of stuff for them to do!

I'm probably going to play Nile Online til I get into the top 100 (and then retire), but there's no way I'll put 1000 hours into it - it just won't let me. It would take me years of play to get that far, and I'm far more likely to find something else to do. If I can retire after six months, what's to keep me coming back again and again? Hence:

Players should feel committed to the game. One thing that kept many players subscribed to Ultima Online was their houses. They had a lot invested in their house, and they didn't want to give it up. This is a great example because a lot of those subscribed players didn't even play! They'd log in once or twice a week to prevent their house from falling apart, but they wouldn't actually play. Imagine how many more players they could have kept around if there was something else to do?


But really my point is that commitment itself is strong enough to keep players subscribed.


Summary


So I didn't even talk about sims at all in this post, and I've been hacking away at this post for hours. In part two, I'll explore how to apply these rules to the sim genre and see what I come up with.


Meanwhile, I'm gonna go pass out... zzzz