You Should Be Drawing

Original Author: Mike Jungbluth

Artists know this phrase all to well. They hear it from peers. From mentors and idols. From themselves. I am thinking it over and over now as I type this. It is a mantra that is always haunting me. Guilting me.

You should be drawing

Why does that phrase hold so much power? Does it do more harm than good? What is so important about drawing anyway?

The best answer I’ve ever heard1 in regards to that question is “Everyone draws when they are a kid, and then most people grow out of it. I just never grew out of it.” For me, that perfectly sums up why I should be drawing. It is creativity and fun in its purest form.

Drawing is a tool for play and communication. And an incredibly powerful tool at that. It can be academic or it can be entirely free form. It can be permanent or fleeting. It can be beautiful or it can be crass. It can be honest or it can be deceiving. And best of all, it can be done by anyone, at anytime, anywhere.

This is inevitably the part where someone says, “Sure, but all I can draw is stick figures.” So what, that hasn’t stopped Even your meeting doodles are incredibly valuable.

What is important is that drawing affords an outlet that requires only the most basic of tools and technology, which can then scale infinitely to the artist’s wishes. Drawing allows you to cut through any technology or large production constraints and get right to the heart of execution. All you need to do is approach art like you would game design.

You should be playing

Drawing, at its core, is play. You are given an open world with a set of tools and only one core objective. Make your mark. Which probably explains why kids love drawing and adults are terrified by it. The only structure that exists is what you bring to it, and adults bring so much ridiculous structure when they are given the chance to draw that they just freeze up. So, the first step towards enjoying drawing again is to let go of those preconceived notions of what is good and what is bad and just play.

So to let go, approach drawing like you would design a game, which are the tools at hand and any rules you want to add to them.

Start with some tools that encourage energetic mark making. Finger paints, vine charcoal, chalk. Tools that get you messy and have an inherent level of imprecision are the rocket launchers of art. They are inherently bright, loud and able to make anyone hit their target at least in a small way. Then, as your precision with the rocket launcher gets better, you can move towards a machine gun, like water colors. Pencils, Charcoal, Conte, etc are the sniper rifles of art. Starting with those can quickly lead to frustration as they inherently force a steady hand. It isn’t until you’ve used them a lot that you feel comfortable no-scoping them.

Oil paints are a genre able to be scaled amongst themselves based again on the tools. You have access to the entire dev panel with oil paints. Painting only with a palette knife vs a fine sable brush is like God mode with confetti headshots vs one hit kills.

This leads naturally into wanting to create some rules to play with. Draw some random shapes on a page, and then like staring a clouds, turn them into whatever you think they look like. Try drawing the image upside down. Or with your alternate hand. Or with your feet. Or with your eyes closed2. Find rules that allow for you to stop thinking about the physical act of drawing and transport your mind into pure creation. You want rules that foster a sense of fun without the concern that you will be judged. Because once being judged is added into the equation, it requires dedication and becomes work.

You should be growing

Judgement is adding difficulty settings to your game of drawing. It is adding weight to the win/lose conditions of the rules decided upon when you begin to play. Inherently, judgement itself isn’t a bad thing, you just need to set it to a level where your work to success rate isn’t frustrating. Essentially, you need to balance your drawings.

Just like balancing your game, you need to be aware of the intended players and their skill level. If you set the difficulty too high, you are going to rage quit. If it is too low, you are going to get bored and lose focus. Just like with anything, honestly examine what you want out of the experience and then turn the dial up one more notch to push yourself without breaking yourself. Do you want to learn how to design more appealing characters? Do you want to learn color theory? Do you want to learn how to paint environments? Choose a specific goal or objective, like you would in a game, and work towards that. Simply saying, “I want to draw better” is the equivalent of starting a game with the only objective being “Save the world.” Without a specific task or direction, most people, like most players, are just going to wander around aimlessly. Unless you have your difficulty setting high, this probably isn’t an approach that will work well for you.

When you start to feel good about what you have, play test your work. There are countless online forums and communities that gladly give honest critiques and tips to aspiring artists of any skill level. Local colleges or schools often have life drawing classes available to those interested. The artists in your studio might even have draw nights at a local pub or coffee shop. These are your lifelines towards leveling up and having gone through the same process, will gladly lend their eye and focus to give you the honest feedback you need, appropriate to the difficulty level you have established for yourself. Find groups that approach their artistic community like a game of co-op, there to get everyone’s back. And then once you are ready, and are capable of the occasional rocket jump, search out a team deathmatch art group to really have your skills put to the test.

If your difficulty level is set appropriately, you are going to fail sometimes. But that is fine. You have endless continues. Just click restart by picking that pencil back up and making a note of what knocked you into that pit last time. So when you come up against it again, you can jump on its head and knock it out. Because as much fun as just playing a free form game with no difficulty can be, there is nothing quite as rewarding as overcoming that tricky obstacle that kept knocking you down.

You should be doing

This obviously doesn’t have to just be about drawing. It could be about weight lifting. It could be about cooking. It could be about gardening. Ultimately, what it comes down to is opening your eye towards observing the world around you and then honing those observations into something you can communicate successfully. It is about taking your ideas and crafting them as only you can. It is about play. Sometimes with a purpose.

So what are you waiting for?

You should be drawing

_________

Joshua Middleton, but it was told to me second hand many years ago, so I could be wrong. But regardless of who said it, the answer is still brilliant.

I came across the Ty Dunitz. I love how energetic and loose the lines are as each step moves forward. Makes me realize how much I need to relax my main hand during the initial sketch. Fun fact, it seems our most capable drawing foot coincides with our most capable drawing hand. The more you know.



What You Can Learn About User Experience From An Eccentric Billionaire

Original Author: Rob Braun

Like so many other people out there, I was recently at GDC 2012 and for the flight there and back I flew Virgin America. For the uninitiated, Virgin is owned by British billionaire Richard Branson. Branson has gained a reputation over the years for being a bit of an eccentric, but his eccentricities work in his favor. He constantly challenges the status quo and pushes the limits of what technology can do. I picked up on a few key themes while flying, and the first thing that hit me was…

First Impressions Are Key

Flying out to San Francisco was my first experience with flying. Sitting in the terminal, waiting to board the flight, I was expecting the stereotypical flying experience always depicted on TV and the movies: a completely full flight, sitting in obscenely tiny seats and sharing my row with two people even bigger than myself and the snacks cart destroying my elbow every time it passed by. I was pleasantly surprised as soon as I got on the plane. While the flight was full, the seats were surprisingly roomy, with a large area cut out under the seats for either feet or carry-on/personal items. As an added bonus, on the back of each seat was a touch screen that allowed the passengers to select whatever they wanted to watch for the duration of the flight, which leads to my next point…

Novelty Goes A Long Way

This being my first experience flying, it wasn’t all that surprising that I was gaping like an idiot at my surroundings. I was surprised by the two people I shared my half of the row with. Both had flown before, but both were just as amazed with everything the flight offered to all their passengers. In addition to touch screens, the plane had free wifi access once cruising altitude was reached and power outlets under all the seats. Through the touch screens we had access to about a dozen movies, satellite TV, a wide range of music, and the ability to order food and drinks from the stewards/stewardesses. Also, there were purple lights lining the ceiling of the craft the entire length of the cabin. By the end of the flight, my seat-mates and I concluded that Virgin was going to be our airline of choice in all our future travels. This leads to my final point…

Your End User Is The Only Person That Really Matters

I’d be willing to bet that when Branson outlined what he wanted Virgin Airlines to be, he had more than a few people tell him that he was insane. I’d be willing to bet that the initial overhead would be ungodly and that getting everything together would be far more difficult than a standard plane, but Branson knew that there would be a market for that type of flying experience and that he could easily build up a loyal customer base. Admittedly the airline has been struggling to get its feet off the ground (no pun intended), but things are starting to turn around for the airline.

So you might be asking by now, “Rob, what does this have to do with game design?” The points listed above apply just as much to games as anything else. If you think of some of the most successful games of the last ten years, I’d be willing to bet every one of them can fall under one or more of those categories. By keeping those points in mind, you’re helping to ensure that you’re creating an enjoyable user experience.

NOTE: In the article I am referring to Virgin America, which is a separate airline from say Virgin Atlantic, and it has been struggling financially.


Interview Techniques

Original Author: Darren-Vine

It has been a little while since I last posted.  I wanted to post about some memory related bits and pieces but our latest version of Elephant is still in testing.  So, I decided to write about something a bit different.

You have landed an interview at the company of your dreams.  For some it may have been a long hard road to get there but now you are sat waiting to be called into the meeting room.  Others may have had several interviews and been unfortunate enough to not get any further. This post, I hope, will get you that job.

I have also deliberately kept this short for one very, very good reason. You will never remember it all in an interview.  You have so many other things to think about that every little tip you are given will vanish the moment you step through the door.

I am going to pass on 3 simple rules.  These rules were passed on to me (I forget by whom or I would credit them) after my first ever set of interviews went poorly.  They are short and to the point and because of this you will remember them.  They are:

1. Don’t fold your arms.

2. Maintain eye contact.

3. Don’t answer with yes or no.

As I said, three simple rules.  After being told these I landed my first job.  Coincidence?  Probably, but they have worked for every single interview I have ever had since so I feel they work well.

I have also lied a little bit about the rules. They are not quite as simple as I have made out but it’s all common sense so don’t panic.

Don’t fold your arms

Really, don’t do this.  Don’t wave them around like a loony either.  If your hands are prone to sweating try not to keep rubbing them on your lap.  Keeping them by your side makes your slouch so that’s one position to avoid as well.  Leaving them on your lap prevents this though.  Use hand gestures to reinforce what you are saying but try to avoid pointing.  Be animated with them, words alone do not always convey what you need.  Also leaning forward a bit when asked a question or answering shows you are attentive to whats being asked.

Maintain eye contact

Maintaining eye contact is critical.  I don’t mean concentrate harder on the floor or HR lady’s chest. I mean look them in the eyes.  If more than one person is interviewing you, focus most of your time on the person who asked the question.  Flick from one to the other occasionally but spend 75-85% of the time focused on the person that asked the question.  If you find this hard, and people do, look at the top of the nose between the eyes.  No one can tell the difference from across the table.

Don’t answer yes or no to questions…

But don’t ramble on either.  I have seen many people botch an interview by talking to much.  Get to the point or their mind will wander.  Answering yes or no makes you seem disinterested in being there.  Something that you do not want.  3 or 4 sentences is perfect.  It is enough to get a fairly detailed answer across but not enough to bore the interviewers.  It also helps lead the conversation down paths that you can be confident talking about as well.  This plays on your strengths.

Final Advice

The only other bits of advice I can recommend are fairly obvious and can be prepared before or after the interview.

The first is wash.  If you are prone to sweating put deodorant on.  Most importantly do this on a clean body.  Lynx (or Axe depending on the part of the world you are from) on top of a day (or for some, days) stale body oder really doesn’t smell as nice as you think.  First impressions count.  Nobody wants to be gagging on a mixture of the two as you walk into the meeting room.

The same goes for what you wear.  I normally go for slightly smarter than I would expect to wear on a normal day working there.  For a job in the games industry that would be a shirt, smart jeans and shoes.  If it was office work then it would be a suit.  If you are unsure a suit never hurts.  Though if everyone else is in jeans then it can feel uncomfortable but it’s better than coming across as lazy.

Mind your P’s and Q’s.  Saying please and thank you goes a long way.  This shouldnt be a problem because you are always polite, right?

Nerves affect everyone, some worse than others.  No one will hold it against you, interviews can be stressful.  If something goes awry, take a deep breath, wait a few seconds and restart.  Try not to panic and just slow down.  Things normally start to go wrong because you are trying to think of things to fast.

Don’t forget to take your portfolio with you and a CV.  It’s best not to have it covered in coffee stains.

There may be some tests.  I tend to do badly at riddle style questions but often it’s how you arrive at your answer that counts.

After the interview

After the interview, whether it went good or bad think back on what you saw and the impression they gave you.  Interviews are a two-way street.  They also provide you with the opportunity to decide if the company is right for you or not.

Some company’s are notoriously bad at getting back to you.  Even with an email that says thanks but no thanks.  I think that this is huge professional faux pas and something the games industry is terrible at.  Any managers reading this should take note, it reflects badly on your company!  Be prepared for this, chalk it down to experience and move on.  If you feel you must have an answer drop them a mail a couple of weeks after the interview.  Chances are if you didn’t receive a reply before you probably wont now either.  If you went through an agency chase them up.  Some people dislike agencies but they are very good at this aspect or they wouldn’t make any money.

…And finally

These are the rules I stick to.  I look forward to seeing more suggestions in the comments below but these three have worked countless times for me.  They are small, simple and easy to remember at all times.  Some people can rattle off pages of hints and tips but you will never remember them once you are actually in the room.


Be an Architect

Original Author: Andrew Meade

So I haven’t posted in a while – my sincerest apologies. With GDC, schoolwork, moving, work, and my own projects, I’ve been a bit swamped for time. But here I am, fresh and ready to talk about level design.

Now, I’m not sure whom I’m directing this to. It may be for a more entry-level perspective, but maybe I will be throwing some new concepts out there for everyone to benefit from. If anything hopefully I am tossing some old thoughts around in a fresh way.

They tell me that Level Design is an entry point into the industry for fresh-faced designers. I wouldn’t know much about that, as my first (and current) job has been centered on a more rounded design platform, as opposed to one specific discipline. I suppose if I had to hammer down what I focus on most, it’s probably a combination between usability and fun – then again, shouldn’t that be every designer’s main pursuit? Shouldn’t those two things be infused in everything we do? I should probably move on, before I get too philosophical.

Anyways, let’s gain some relevance in regards to the title of this post. Last week, I had the benefit of spending a lot of one-on-one time with quite a few of my teachers at GDC – none more than my current teacher, Tom Long. Chilling at Golden Gate Park, we were chatting about the “Why” of what we do in a level. In comparison to “How” and “What”,  “Why” seems like quite the sticky wicket. Why should the player follow a certain path? Why are the weather conditions the way they are? It may all seem like aesthetics, but it’s a carefully calculated choice. But it’s also aesthetics. I hope that isn’t confusing. Aesthetics have the ability to put the player into a specific mood, which will alter their playstyle or emotional state in the level. This in turn alters the mechanics of the actual level. We mustn’t forget that we can’t just put things in a level because they look cool or seem clever – this is where our restraint needs to come into play. An exercise I have been taught, and frequently practice, is create a pen and paper level, then “zoom in” to the nuts and bolts of it – the actual playable space. If it doesn’t benefit the level in some way, shape, or form, then it doesn’t need to be there.

I think a great example of a level designed with constraint, yet with a seemingly large scope, are the “All Ghillied Up” and “One Shot, One Kill” levels from Call of Duty: Modern Warfare. The actual landscape that the player traverses is vast and imposing, yet play happens on a very small scale. Even the frantic chase scene at the end through an entire city seems large, yet encounters are set in very specific pockets, giving the player a feeling of chaos when in fact the pacing is very controlled and deliberate. No space is wasted in that level, and what we are left with is an example of Level Design that is still referenced glowingly today.

Finding the “Why” and answering it may be a bit difficult at first – hell, I’m still wrangling with it myself, but through practice, study, and constraint, we can tackle that question head on.

So let’s go back to the park, where we were discussing the “Why” of Level Design. Once that bit of conversation was over with, we started discussing “Swipes”, or “Swipe Files”. If you aren’t aware of this yet, then you’re really going to love it. A swipe is a collection of items meant to enhance our designer’s toolkit – mostly it’s in the form of pictures, but it can also be samplings of schematics, sketches, audio files, scents, and actual materials like rocks, fabrics, soils, etc. You can use your swipe to be a better designer.

When we think of a level, we paint it with broad strokes. Like we’re going over something with a paint roller. The gist of the concept is there, but it’s missing all the details and trim work that make a level real. Players aren’t stupid – even if they don’t know anything about anything, they will know if something isn’t right with their virtual world, because it’s based off a reality they live in. This is even true with levels outside our known reality, because everything is based off of our own implicit human knowledge.

Once you have painted the broad strokes of your level, you can use your swipe to get down to the details. For instance, I was working on a pillar last night and thought it felt a little lackluster. Looking through my swipe, I found a cathedral that used three pillars together to form one giant über-pillar. It looked awesome, so now that’s in the level. Since I started my swipe, I’ve felt much more inspired than I have in months. As soon as I learned about it I started a San Francisco Swipe – literally the moment I heard I pulled out my phone and started to work – and it has benefited me greatly. I have set pieces that are as huge as an entire city overlook, shots as intimate as a bistro in Little Italy, and details as minute as the grain and pattern of a concrete slab to use as a material in the editors I work in.

Going through my things, I also put together swipes from places I’ve been before – a Lisbon Swipe, a Northern Ohio Swipe, a Central U.S. Nature Swipe, and more. I think these things are great, because instead of looking at pictures online and formulating my work from those, messing with my swipes brings me to the moment in time when I took them, and I suddenly remember the smell in the air, the direction of the wind, the sounds of the area – all of it. It’s more real because I’ve been there, and I took the picture. All it does is help me fill in some blanks – plus it makes every trip I take into a business expense!

Looks like I’ve diverged from the initial point of this post, but I think everything I’ve said is relevant in a way. Looking through my SF Swipe, I was kind of thunderstruck by how Level Designers really aren’t Level Designers, or Builders, or whatever industry term one wants to use. Level Designers are Architects! I never really knew what a flying buttress was before I started Level Design, but I sure do now – granted what I thought they were beforehand was far funnier and immature, but that’s beside the point. I didn’t know what cresting or an oriel was, but now I do – and if you don’t, you really should look it up.

The more of an architect a Level Designer is, the more realistic the level will be. More realism equals more ambiance, more immersion, and more credibility. Don’t forget that when I say “realistic”, I don’t mean that every game needs to be realistic in that Battlefield 3 kind of way, but realistic in “there is an internal logic to the workings of this world that is congruent with our opinions and knowledge of how things work”. I hope I’m clear on that; kind of a “learn the rules to break them” sort of thing.

So I’ve decided, when I wear my Level Design hat, to call myself an Architect. In fact, I told that to an old lady at the bus the other day. She asked what I did in games, and I said that I do this and that, but lately I’ve been focusing on Level Design. I puffed my chest up a bit, and then said “Actually, I prefer to think of myself as more of an Architect”. Unfortunately I busted out laughing through the word architect, because let’s face it – it’s kind of pretentious and douchie, but that’s ok. Maybe we need a bit of pretention to make us feel good.

All the nuances of static_cast (and others)

Original Author: Jaewon Jung

Recently I noticed my knowledge about C++ cast operators had been far from complete. For instance, I had thought static_cast is only for static upcasts(or downcasts also?) in an inheritance hierarchy. And for some legitimate casts between primitive types(like between int and float or between int and unsigned int), I used the C-style cast, still. I was not sure about how new cast operators are precisely mapped to the old C-style, either. So here is my shot at finally clarifying all these.

Categories

Errors possible
  • Es : compile error
  • Er: run-time check failure
    • an exception when casting a reference
    • returing nullptr when casting a pointer
  • Ec : run-time crash when using the converted
Conversions supported
  • Cprim: between primitive types : int <-> float, int <-> unsigned int
    • built-in conversion rules apply
  • pointer(reference) types
    • Cbase: pointer to a linearly related type(upcast/downcast) : CDerived* <-> CBased*
      • a proper pointer arithmetic applies if a multiple inheritance used
    • Cvoid : void pointer : void* <-> int*
    • Cconst : removing const/volatile type qualifiers : const int* <-> int*
    • Cetc : Any other cases : int* <-> float*

Casts

static_cast<>
  • Cprim, Cbase, Cvoid
  • Es if Cconst, Cetc tried
  • A possible Ec if an invalid downcast tried e.g. CBase* pB = new CBase(); CDerived* pD = static_cast<CDerived*>(pB);
reinterpret_cast<>
  • Cbase, Cvoid, Cetc
  • Es if Cprim, Cconst tried
  • A possible Ec if Cbase tried(because a proper point arithmetic isn’t applied)
dynamic_cast<>
  • Cbase, dynamic_cast<void*>
    • The latter returns a pointer to the complete(i.e. most-dervied) object.
  • Es if Cprim, Cvoid, Cconst, Cetc
  • A possible Er if a downcast of Cbase tried and its run-time check fails
const_cast<>
  • Cconst
  • Es if Cprim, Cbase, Cvoid, Cetc
C-style cast
  • A C-style cast is defined as the first of the following which succeeds:
    • const_cast
    • static_cast
    • static_cast, then const_cast
    • reinterpret_cast
    • reinterpret_cast, then const_cast

Conclusion

  • Never use the C-style cast any more. You can use one among (or an combo of) const_cast, static_cast, reinterpret_cast depending on your exact need at that time.
  • dynamic_cast is a complete new thing in C++ and use it sparingly since it has a run-time cost and a need for it might be a symptom of some bad underlying design(though this aspect of it has not been discussed in this article).
  • C++ is too deep (for a mere mortal to figure all its nooks and crannies).

References

(This article has also been posted to my personal blog.)

Update – dynamic_cast<void*> and the fourth reference added


Getting started with Google App Engine (for .NET developers)

Original Author: Jason-Swearingen

Here at Novaleaf, we make consumer apps in addition to games. Our first web app is a Thai specific computer hardware eCommerce web app built on Google App Engine (GAE), using Java.

I’m historically (and well, currently) a .NET developer, but find the idea of a GAE based game server platform intriguing. But hey, I’m pretty much a 1 trick pony: “C# or nuthin.” (I can write C++ but hate it), so how do I get into the world of “weird” java buzzwords like servlets and WAR, in addition to the platform specific knowledge that makes up GAE?

One way would be to force one of Novaleaf’s webdevs to sit down and teach me. I might just do that, but… after I give it a try myself.   Here’s the steps I took to learn GAE’s basics, and get a “hello world” app running. I hope it’s useful for other .NET developers looking to expand their skills in a relatively painless way.

First: Get a high-level picture.

I skimmed Google’s online resources about GAE and it’s various features. and learned from a high-level what GAE can and can not do, and what it will be able to do in the near future.  I prefer to do this high-level overview first to frame the capabilities of the platform, so later when doing in-depth tutorials I can frame the knowledge in context to how it’d fit into my project’s needs.

I was a bit surprised about how well described it is, at least relative to Sun’s Java/Javadoc references. I am sure that for Java developers, the documentation is perfectly fine… but for people starting out, it’s a bit painful to figure out the difference between J2SE, J2EE, that Java “2″ is actually v1.2, etc etc…  Anyway, no need to go into that here, right 😉

Second:  will GAE do what I need?

Once I understand the general capabilities of GAE, I ask myself if it will do what I need?   Well, I have a ton of ideas floating in my head, but to put this in perspective for a “simple game server” here’s some key points:

  1. GAE scales very well with multiple users (each request is on a separate thread)
  2. Storing intra-gamestate will be too expensive (GAE stores all state in database, so high-frequency read/writes will be monetarily expensive)
  3. Storing macro-level metagame information (low-frequency user information and matchmaking data) seems to be a good match for GAE’s feature set
  4. Per-user server polling is the only viable option for GAE right now  (a socket api is in development but not yet ready)
  5. Threading is not supported right now (in development) so no multithreaded fancyness is available.
  6. Supports XMPP based chat protocol
  7. To summarize, GAE seems suitable for synchronizing with users every few minutes, so for savegame, matchmaking, topscores, achievements, etc.    but not for high-frequency use .
So this is all fine by me.   Current GAE features seems to restrict my game-use to matchmaking services only, though if I want to get creative with the XMPP functionality, it may be possible to introduce a high-latency gamestate server, though the adding of sockets to GAE in the future also looks promising.

Third: Find a good book.

I searched amazon for the highest rated books on the matter, and settled with “Programming Google App Engine“.

I am currently on chapter 2 of this book, following the tutorials to put together a “hello world”.  Seems good, however their explanations detail using Eclipse,  which is nice and all (and free) but not realy that user friendly to .NET developers comfortable with Visual Studio.

Fourth: Setting up the right tools

I did some research as to the most visual-studio-like java IDE, and came up with Google Web Toolkit integration, so seems great to me.     I’ll quickly summarize the steps I take to get the tools setup:

  1. Install Java6 JDK from Sun’s website (J2SE x64 is what I used) 

Run IntelliJ and create a new project with the following options:

  1. Setup a new project (Java Module)
  2. Under technologies, choose “Google App Engine”, choose the right SDK dir that you extracted the GAE SDK to.
  3. If not set, point JDK dir to the program filesjavajdk1.6.x dir  (File–>Project Structure–>Project)
  4. Add J2EE servlet references:  File–>ProjectStructure–>Libraries–>AppEngine API–>Classes->Attach Directory:   “%PATH_TO_APP_ENGINE_API%libshared”  also add liborm and libuser and lib
  5. Add GAE Javadocs for inline documentation:   File–>ProjectStructure–>Libraries–>AppEngine API–>Specify Documentation URL–>“google’s own tutorials.

    Summary:  Pretty easy!

    In total, I spent about 3 days figuring out these details and finish up my first “hello world” app and getting it published on GAE.   If this information proves useful (or not), please leave a comment.  I’d love to hear.


Float Precision–From Zero to 100+ Digits

Original Author: Bruce-Dawson

How much precision does a float have? It depends on the float, and it depends on what you mean by precision. Typical reasonable answers range from 6-9 decimal digits, but it turns out that you can make a case for anything from zero to over one hundred digits.

In all cases in this article when I talk about precision, or about how many digits it takes to represent a float, I am talking about mantissa digits. When printing floating-point numbers you often also need a couple of +/- characters, an ‘e’, and a few digits for the exponent, but I’m just going to focus on the mantissa.

Previously on this channel…

If you’re just joining us then you may find it helpful to read some of the earlier posts in this series. The first one is the most important since it gives an overview of the layout and interpretation of floats, which is helpful to understand this post.

What precision means

For most of our purposes when we say that a format has n-digit precision we mean that over some range, typically [10^k, 10^(k+1)), where k is an integer, all n-digit numbers can be uniquely identified. For instance, from 1.000000e6 to 9.999999e6 if your number format can represent all numbers with seven digits of mantissa precision then you can say that your number format has seven digit precision over that range, where ‘k’ is 6.

Similarly, from 1.000e-1 to 9.999e-1 if your number format can represent all the numbers with four digits of precision then you can say that your number format has four digit precision over that range, where ‘k’ is -1.

Your number format may not always be able to represent each number in such a range precisely (0.1 being a tired example of a number that cannot be exactly represented as a float) but to have n-digit precision we must have a number that is closer to each number than to either of its n-digit neighbors.

This definition of precision is similar to the concept of significant figures in science. The number 1.03e4 and 9.87e9 are both presumed to have three significant figures, or three digits of precision.

Wasted digits and wobble

The “significant figures” definition of precision is sometimes necessary, but it’s not great for numerical analysis where we are more concerned about relative error. The relative error in, let’s say a three digit decimal number, varies widely. If you add one to a three digit number then, depending on whether the number is 100 or 998, it may increase by 1%, or by barely 0.1%.

If you take an arbitrary real number from 99.500… to 999.500… and assign it to a three digit decimal number then you will be forced to round the number up or down by up to half a unit in the last place, or 0.5 decimal the wobble.

Wobble also affects binary numbers, but to a lesser degree. The relative precision available from a fixed number of binary digits varies depending on whether the leading digits are 10000 or 11111. Unlike base ten where the relative precision can be almost ten times lower for numbers that start with 10000, the relative precision for base two only varies by a factor of two (again, the base).

In more concrete terms, the wobble in the float format means that the relative precision of a float is usually between 1/8388608 and 1/16777216.

The minimized wobble of binary floating-point numbers and the more consistent accuracy this leads to is one of the significant advantages of binary floating-point numbers over larger bases.

This variation in relative precision is important later on and can mean that we ‘waste’ almost an entire digit, binary or decimal, when converting numbers from the other base.

Subnormal precision: 0-5 digits

Float numbers normally have fairly consistent precision, but in some cases their precision is significantly lower – as little as zero digits. This happens with denormalized, or ‘subnormal’, numbers. Most float numbers have an implied leading one that gives them 24 bits of mantissa. However, as discussed in my first post, floats with the exponent set to zero necessarily have no implied leading one. This means that their mantissa has just 23 bits, they are not normalized, and hence they are called subnormals. If enough of the leading bits are zero then we have as little as one bit of precision.

As an example consider the smallest positive non-zero float. This number’s integer representation is 0×00000001 and its value is 2^-149, or approximately 1.401e-45f. This value comes from its exponent (-126) and the fact that its one non-zero bit in its mantissa is 23 bits to the right of the mantissa’s binary point. All subnormal numbers have the same exponent (-126) so they are all multiples of this number.

The binary exponent in a float varies from -126 to 127

Since the floats in the range with decimal exponent -45 (subnormals all of them) are all multiples of this number their mantissas are (roughly) 1.4, 2.8, 4.2, 5.6, 7.0, 8.4, and 9.8. If we print them to one-digit of precision then we get (ignoring the exponent, which is -45) 1, 3, 4, 6, 7, 8, and 10. Since 2, 5, and 9 are missing that means that we don’t even have one digit of precision!

Since all subnormal numbers are multiples of 1.401e-45f, subsequent ranges each have one additional digit of precision. Therefore the ranges with decimal exponents -45, -44, -43, -42, -41, and -40 have 0, 1, 2, 3, 4, and 5 digits of precision.

Normal precision

Normal floats have a 24-bit mantissa and greater precision than subnormals. We can easily calculate how many decimal digits the 24-bit mantissa of a float is equivalent to: 24*LOG(2)/LOG(10) which is equal to about 7.225. But what does 7.225 digits actually mean? It depends whether you are concerned about how many digits you can rely on, or how many digits you need.

Representing decimals: 6-7 digits

Our definition of n-digit precision is being able to represent all n-digit numbers over a range [10^k, 10^(k+1)). There are about 28 million floats in any such (normalized) range, which is more than enough for seven digits of precision, but they are not evenly distributed, with the density being much higher at the bottom of the range. Sometimes there are not enough of them near the top of the range to uniquely identify all seven digit numbers.

In some ranges the exponent lines up such that we may (due to the wobble issues mentioned at the top) waste almost a full bit of precision, which is equivalent to ~0.301 decimal digits (log(2)/log(10)), and therefore we have only ~6.924 digits. In these cases we don’t quite have seven digits of precision.

I wrote some quick-and dirty code that scans through various ranges with ‘k’ varying from -37 to 37 to look for these cases.

FLT_MIN (the smallest normalized float) is about 1.175e-38F, FLT_MAX is about 3.402e+38F

My test code calculates the desired 7-digit number using double precision math, assigns it to a float, and then prints the float and the double to 7 digits of precision. The printing is assumed to use correct rounding, and if the results from the float and the double don’t match then we know we have a number that cannot be uniquely identified/represented as a float.

Across all two billion or so positive floats tested I measured 784,757 seven-digit numbers that could not be uniquely identified, or about 0.04% of the total. For instance, from 1.000000e9 to 8.589972e9 was fine, but from there to 9.999999e9 there were 33,048 7-digit numbers that could not be represented. It’s a bit subtle, but we can see what is happening if we type some adjacent 7-digit numbers into the watch window, cast them to floats, and then cast them to double so that the debugger will print their values more precisely:

image:

One thing to notice (in the Value column) is that none of the numbers can be exactly represented as a float. We would like the last three digits before the decimal point to all be zeroes, but that isn’t possible because at this range all floats are a multiple of 1,024. So, the compiler/debugger/IEEE-float does the best it can. In order to get seven digits of precision at this range we need a new float every 1,000 or better, but the floats are actually spaced out every 1,024. Therefore we end up missing 24 floats for each set of 1,024. In the ‘Value’ column we can see that the third and fourth numbers actually map to the same float, shown circled below:

 image

One was rounded down, and the other was rounded up, but they were both rounded to the closest float available.

At 8.589930e9 a float’s relative precision is 1/16777216 but at 8.589974e9 it is just 1/8388608

This issue doesn’t happen earlier in this range because below 8,589,934,592 (2^33) the float exponent is smaller and therefore the precision is greater – immediately below 2^33 the representable floats are spaced just 512 units apart. The loss of decimal precision always happens late in the range because of this.

My test code showed me that this same sort of thing happens any time that the effective exponent of the last bit of the float (which is the exponent of the float minus 23) is -136, -126, -93, -83, -73, -63, -53, -43, -33, 10, 20, 30, 40, 50, 60, 70, or 103. Calculate two to those powers if you really want to see the pattern. This corresponds to just six digit precision in the ranges with decimal exponents -35, -32, -22, -19, -16, -13, -10, -7, -4, 9, 12, 15, 18, 21, 24, 27, and 37.

Therefore, over most ranges a float has (just barely) seven decimal digits of precision, but over 17 of the 75 ranges tested a float only has six.

Representing floats: 8-9 digits

The flip side of this question is figuring out how many decimal digits it takes to uniquely identify a float. Again, we aren’t concerned here with converting the exact value of the float to a decimal (we’ll get to that), but merely having enough digits to uniquely identify a particular float.

In this case it is the fuzziness of the decimal representation that can bite us. For some exponent ranges we may waste almost a full decimal digit. That means that instead of requiring ~7.225 digits to represent all floats we would expect that sometimes we would actually need ~8.225. Since we can’t use fractional digits we actually need nine in these cases. As explained in a previous post this happens about 30% of the time, which seems totally reasonable given our calculations. The rest of the time we need eight digits to uniquely identify a particular float. Use 9 to play it safe.

printf(“%1.8e”, f); ensures that a float will round-trip to decimal and back

Precisely printing float: 10-112 digits

There is one final possible meaning of precision that we can apply. It turns out that while not all decimal numbers can be exactly represented in binary (0.1 is an infinitely repeating binary number) we can exactly represent all binary numbers in decimal. That’s because 1/2 can be represented easily as 5/10, but 1/10 cannot be represented in binary.

It’s interesting to see what happens to the decimal representation of binary numbers as powers of two get smaller:

Binary_exponent Decimal_value
-1 0.5
-2 0.25
-3 0.125
-4 0.0625
-5 0.03125
-6 0.015625
-7 0.0078125
-8 0.00390625
-9 0.001953125

Each time we decrease the exponent by one we have to add a digit one place farther along. We gradually acquire some leading zeroes, so the explosion in digits isn’t quite one-for-one, but it’s close. The number of mantissa digits needed to exactly print the value of a negative power of two is about N-floor(N*log(2)/log(10)), or ceil(N*(1-log(2)/log(10))) where N is an integer representing how negative our exponent is. That’s about 0.699 digits each time we decrement the binary exponent. The smallest power-of-two we can represent with a float is 2^-149. That comes from having just the bottom bit set in a subnormal. The exponent of subnormals floats is -126 and the position of the bit means it is 23 additional spots to the right and 126-23 = 149. We should therefore expect it to take about 105 digits to print that smallest possible float. Let’s see:

1.401,298,464,324,817,070,923,729,583,289,916,131,280,261,941,876,515,771,757,068,283,889,

791,082,685,860,601,486,638,188,362,121,582,031,25e-45

For those of you counting at home that is exactly 105 digits. It’s a triumph of theory over practice.

That’s not quite the longest number I could find. A subnormal with a mantissa filled up with ones will have seven fewer leading zeroes leading to a whopping 112 digit decimal mantissa:

1.175,494,210,692,441,075,487,029,444,849,287,348,827,052,428,745,893,333,857,174,530,571,

588,870,475,618,904,265,502,351,336,181,163,787,841,796,875e-38

Pow! Bam!

While working on this I found a bug in the VC++ CRT. pow(2.0, -149) fits perfectly in a float – albeit just barely – it is the smallest float possible. However if I pass 2.0f instead of 2.0 I find that pow(2.0f, -149) gives an answer of zero. So does pow(2.0f, -128). If you go (float)pow(2.0, -149), invoking the double precision version of the function and then casting to float, then it works. So does pow(0.5, 149).

Perversely enough powf(2.0f, -149) works. That’s because it expands out to (float)pow(double(2.0f), double(-149)).

Conveniently enough the version of pow that takes a float and an int is in the math.h header file so it’s easy enough to find the bug. The function calculates pow(float, -N) as 1/powf(float, N). The denominator overflows when N is greater than 127, giving an infinite result whose reciprocal is zero. It’s easy enough to work around, and will be noticed by few, but is still unfortunate. pow() is one of the messier functions to make both fast and accurate.

How do you print that?

The VC++ CRT, regrettably, refuses to print floats or doubles with more than sin(pi) trick explained last time.. So, we’ll need to roll our own.

Printing binary floating-point numbers efficiently and accurately is hard. In fact, when the IEEE spec was first ratified it was not yet a solved problem. But for expository purposes we don’t care about efficiency, so the problem is greatly simplified.

It turns out that any float can be represented as a fixed-point number with 128 bits in the integer part and 149 bits in the fractional part, which we can summarize as 128.149 format. We can determine this by noting that a float’s mantissa is a 1.23 fixed-point number. The maximum float exponent is 127, which is equivalent to shifting the mantissa left 127 positions. The minimum float exponent is -126, which is equivalent to shifting the mantissa right 126 positions.

shift up to 127 positions this way <— 1.000 000 000 000 000 000 000 00 —> shift up to 126 positions this way

Those shift amounts of our 1.23 mantissa mean that all floats can fit into a 128.149 fixed-point number, for a total of 277 bits.

All we need to do is create this number, by pasting the mantissa (with or without the implied leading one) into the correct location, and then convert the large fixed-point number to decimal.

Converting to decimal is done by two main steps. The integer portion is converted by repeatedly dividing it by ten and accumulating the remainders as digits (which must be reversed before using). The fractional part is converted by repeatedly multiply by ten and accumulating the overflow as digits. Simple. All you need is a simple high-precision math library and we’re sorted. There’s also some special-case checks for infinity, NaNs (print them however you want), negatives, and denormals, but it’s mostly quite straightforward. Here’s the conversion code:

/* See
 
  Tricks With the Floating-Point Format
 
  for the potential portability problems with the union and bit-fields below.
 
  */
 
  union Float_t
 
  {
 
      Float_t(float num = 0.0f) : f(num) {}
 
      // Portable extraction of components.
 
      bool Negative() const { return (i >> 31) != 0; }
 
      int32_t RawMantissa() const { return i & ((1 << 23) - 1); }
 
      int32_t RawExponent() const { return (i >> 23) & 0xFF; }
 
   
 
      int32_t i;
 
      float f;
 
  #ifdef _DEBUG
 
      struct
 
      {   // Bitfields for exploration. Do not use in production code.
 
          uint32_t mantissa : 23;
 
          uint32_t exponent : 8;
 
          uint32_t sign : 1;
 
      } parts;
 
  #endif
 
  };
 
   
 
  // Simple code to print a float. Any float can be represented as a fixed point
 
  // number with 128 bits in the integer part and 149 bits in the fractional part.
 
  // We can convert these two parts to decimal with repeated division/multiplication
 
  // by 10.
 
  std::string PrintFloat(float f)
 
  {
 
      // Put the float in our magic union so we can grab the components.
 
      union Float_t num(f);
 
   
 
      // Get the character that represents the sign.
 
      const std::string sign = num.Negative() ? "-" : "+";
 
   
 
      // Check for NaNs or infinity.
 
      if (num.RawExponent() == 255)
 
      {
 
          // Check for infinity
 
          if (num.RawMantissa() == 0)
 
              return sign + "infinity";
 
   
 
          // Otherwise it's a NaN.
 
          // Print the mantissa field of the NaN.
 
          char buffer[30];
 
          sprintf_s(buffer, "NaN%06X", num.RawMantissa());
 
          return sign + buffer;
 
      }
 
   
 
      // Adjust for the exponent bias.
 
      int exponentValue = num.RawExponent() - 127;
 
      // Add the implied one to the mantissa.
 
      int mantissaValue = (1 << 23) + num.RawMantissa();
 
      // Special-case for denormals - no special exponent value and
 
      // no implied one.
 
      if (num.RawExponent() == 0)
 
      {
 
          exponentValue = -126;
 
          mantissaValue = num.RawMantissa();
 
      }
 
   
 
      // The first bit of the mantissa has an implied value of one and this can
 
      // be shifted 127 positions to the left, so that is 128 bits to the left
 
      // of the binary point, or four 32-bit words for the integer part.
 
      HighPrec<4> intPart;
 
      // When our exponentValue is zero (a number in the 1.0 to 2.0 range)
 
      // we have a 24-bit mantissa and the implied value of the highest bit
 
      // is 1. We need to shift 9 bits in from the bottom to get that 24th bit
 
      // into the ones spot in the integral portion, plus the shift from the exponent.
 
      intPart.InsertLowBits(mantissaValue, 9 + exponentValue);
 
   
 
      std::string result;
 
      // Always iterate at least once, to get a leading zero.
 
      do
 
      {
 
          int remainder = intPart.DivReturnRemainder(10);
 
          result += '0' + remainder;
 
      } while (!intPart.IsZero());
 
   
 
      // Put the digits in the correct order.
 
      std::reverse(result.begin(), result.end());
 
   
 
      // Add on the sign and the decimal point.
 
      result = sign + result + '.';
 
   
 
      // We have a 23-bit mantissa to the right of the binary point and this
 
      // can be shifted 126 positions to the right so that's 149 bits, or
 
      // five 32-bit words.
 
      HighPrec<5> frac;
 
      // When exponentValue is zero we want to shift 23 bits of mantissa into
 
      // the fractional part.
 
      frac.InsertTopBits(mantissaValue, 23 - exponentValue);
 
      while (!frac.IsZero())
 
      {
 
          int overflow = frac.MulReturnOverflow(10);
 
          result += '0' + overflow;
 
      }
 
   
 
      return result;
 
  }

Converting to scientific notation and adding digit grouping is left as an exercise for the reader. A Visual C++ project that includes the missing HighPrec class and code for printing doubles can be obtained at:

ftp://ftp.cygnus-software.com/pub/PrintFullFloats.zip

Practical Implications

The reduced precision of subnormals is just another reason to avoid doing significant calculations with numbers in that range. Subnormals exist to allow gradual underflow and should only occur rarely.

Printing the full 100+ digit value of a number is rarely needed. It’s interesting to understand how it works, but that’s about it.

It is important to know how many mantissa digits it takes to uniquely identify a float. If you want to round-trip from float to decimal and back to float (saving a float to an XML file for instance) then it is important to understand that nine mantissa digits are required. I recommend printf(“%1.8e”, f). This is also important in debugging tools, and I’m told that VS 11 will fix this bug.

It can also be important to know what decimal numbers can be uniquely represented with a float. If all of your numbers are between 1e-3 and 8.58e9 then you can represent all seven digit numbers, but beyond that there are some ranges where six is all that you can get. If you want to round-trip from decimal to float and then back then you need to keep this limitation in mind.

Until next time

Next time I might cover effective use of Not A Numbers and floating-point exceptions, or general floating-point weirdness, or why float math is faster in 64-bit processes than in 32-bit /arch:SSE2 projects. Let me know what you want. I’m having fun, it’s a big topic, and I see no reason to stop now.

C / C++ Low Level Curriculum Part 6: Conditionals

Original Author: Alex Darby

Hello interwebs! As the title suggests this is the 6th part of the C / C++ Low Level Curriculum series I’ve been doing. In this installment we’ll be starting to look at conditional statements, and what the code that you’re asking the compiler to generate when you use them looks like (at least before the optimiser gets to it…).

Just in case anyone is unclear about what they are, conditionals are the language features that allow us control over which parts of our code get executed. At face value, the subject of conditionals might seem a simple one, but it is precisely because it seems simple – and because so much else builds on top of it – that it is the first topic that I’ve chosen to look at in detail after function calls.

Though we won’t get around to all of them in this post, our look at conditionals will take us on a tour through a representative sample of x86 disassembly generated by if statements, the conditional operator (or “ternary operator”, or “question mark”), and switch statements; and whilst we look at all of these we’ll also be looking at disassembly generated by the (built in!) relational and logical operators that are used with them (i.e. ==, !=, <=, >=, >, <, !, &&, and ||).

Prologue

Firstly, I’d like to apologise to anyone who reads these posts regularly for the fact that my rate of posting has slowed down – I will hopefully speed up again to the regular 2 week posting cycle in the near future.

Secondly, here are the backlinks for anyone who wants to start from the beginning of the series (warning: it might take you a while, the first few are quite long):

  1. /2011/11/09/a-low-level-curriculum-for-c-and-c/
  2. /2011/11/24/c-c-low-level-curriculum-part-2-data-types/
  3. /2011/12/14/c-c-low-level-curriculum-part-3-the-stack/
  4. /2011/12/24/c-c-low-level-curriculum-part-4-more-stack/
  5. /2012/02/07/c-c-low-level-curriculum-part-5-even-more-stack/

Generally I will try to avoid too much assumed knowledge; but if something comes up that I’ve explained previously, or that I know another ADBAD author has covered already then I will just link to it; this implies that you, dear reader, should assume that I assume you will read anything I link to if you want to make complete sense of the article 🙂

Compiling and running code from this article

I assume that you are using Windows, are familiar with the VS2010 IDE, and comfortable writing, running, and debugging C++ programs.

As with the previous posts in this series, I’m using a win32 console application made by the “new project” wizard in VS2010 with the default options (VS2010 express edition is fine).

The only change I make from the default project setup is to turn off “Basic Runtime Checks” to make the generated assembler more legible (and significantly faster…) see this previous post for details on how to do this.

To run code from this article in a VS2010 project created this way, open the .cpp file that isn’t stdafx.cpp and replace everything in it with text copied and pasted from the code box.

The disassembly we look at is from the debug build configuration, which generates “vanilla” unoptimised win32 x86 code.

Instructions and Mnemonics: an aside

I’ve just realised that so far in this series I have typically been using the term instruction when referring to an assembler mnemonic.

I felt that I should point out that this isn’t 100% accurate, because whilst assembler mnemonics are normally thought of as having a 1:1 correspondence to binary CPU instructions, they are not actually instructions.

In fact, in x86 assembler, the menemonics often actually have a 1:x relationship with the corresponding opcodes, because multiple variants of each mnemonic exist that differ in the types and sizes of their operands.

This is not something you should worry yourself about too much, as it’s a fairly harmless Kenobiism, but I still felt I should point it out if I was going to carry on doing it 😉

Conditionals

The best place to start is, as someone or other famously once remarked, at the beginning; so let’s start with the most basic form of the if statement.

Before anyone mentions it, I know I could have omitted the curly braces around iLocal = 1; on line 9. If you’re the kind of person who’s so lazy that you like to leave out curly braces in these situations then that’s up to you; but I would just like to point out that there is probably a special place in one of the deeper and less pleasant circles of the Hell I don’t believe in that is reserved for your sort – just a couple of floors up from those who do the same thing with loops.

Also, I’ve left the #inlcude “stdafx.h” in the code box so that your line numbers match mine if you’re working through this yourself.

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  
#include "stdafx.h"
 
   
 
  int main(int argc, char* argv[])
 
  {
 
      int iLocal = 0;
 
   
 
      if( argc < 0 )
 
      {
 
          iLocal = 1;
 
      }
 
   
 
      return 0;
 
  }

Anyway, as usual if you’re looking at this in VS2010 then copy and paste the above code over whichever is your project’s main .cpp file, put a breakpoint on line 7, tell Visual Studio to compile and run, wait for the breakpoint to be hit, then right click in the source window and choose “Go To Disassembly”. You should now be seeing something like this:

Simple If Disassembly

n.b. right-click and check you have the same options checked as me…

As we already know the assembler above int iLocal = 0; is the function prologue (or preamble) and the assembler after the closing brace of main() is function epilogue.

The specific disassembler we’re interested in is between lines 7 and 13 of the source code that is shown inline with the disassembly, so here it is pasted into a code window (N.B. the addresses corresponding to the disassembly instructions will almost certainly differ on your screen if you’re running this yourself…)

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  
     7:     if( argc < 0 )
 
  010D20B0  cmp         dword ptr [argc],0
 
  010D20B4  jge         main+1Dh (10D20BDh)
 
       8:     {
 
       9:         iLocal = 1;
 
  010D20B6  mov         dword ptr [iLocal],1
 
      10:     }
 
      11:
 
      12:     return 0;
 
  010D20BD  xor         eax,eax
 
      13: }

Straight away, there are a couple of new assembler mnemonics we’ve not come across so far in this series of posts. We’ll cover these as we come to them.

line 2 is comparing argc against 0. The instruction cmp doesn’t have an instant effect on code execution, it compares  its first and second operand and stores the result of the comparison in an internal register of the CPU known as EFLAGS.

line 3 uses the mnemonic jge, which means jump greater equal. It will cause a jump to the address 0x010D20BD supplied as its operand if the outcome of the previous cmp instruction has set the content of the EFLAGS register to indicate that its first operand was greater than or equal to its second operand – i.e. if argc is greater than or equal to 0 then execution will jump past the instructions generated by the block of code controlled by the if.

Hold on a minute…

So, we’ve only covered the most basic form of an if statement and we’ve already encountered a major difference between what we might think we’re asking the compiler to do, and the code it’s generating.

The intuitive way to think about an if block in a high level language is that if the condition of the if is met, then execution will step into the curly braces delimted block of code it controls.

However, the assembler is clearly testing the logical opposite of what we’ve asked it to, and if that condition is met then it is skipping over the code block controlled by the if.

This is because, at the assembler level, instructions are executed in sequential order unless a jump instruction tells it to do otherwise – and so assembler has no equivalent to the high level concept of a curly brace delimited “code block”. The upshot of this is that the high level notion of “stepping into” a code block is implemented at the assembler level by “not skipping over” the code the block has generated.

Clearly these two behaviours are logically isomorphic (i.e. produce the same output given the same input), but the high level version is easier for the human mind to cope with intuitively, and the version generated by the compiler better suits the sequential-execution-unless-tampered-with behaviour of the underlying machine.

Just for the sake of clarity let’s re-write the C++ code in a form that matches what the assembler we just looked at does, using the C++ keyword goto:

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  
#include "stdafx.h"
 
   
 
  int main(int argc, char* argv[])
 
  {
 
      int iLocal = 0;
 
   
 
      // corresponding original code in comments to the right...
 
      if( argc >= 0 ) goto GreaterEqualZero;   //if( argc < 0 )
 
                                               //{
 
      iLocal = 1;                              //    iLocal = 1;
 
                                               //}
 
      GreaterEqualZero:
 
   
 
      return 0;
 
  }

NOTE: Ironically (though unsurprisingly) this C++ code generates different assembler to the original code. Please don’t worry about this.

if … else if … else

So let’s take a look at a more complicated if construct:

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  16
 
  17
 
  18
 
  19
 
  20
 
  21
 
  
#include "stdafx.h"
 
   
 
  int main(int argc, char* argv[])
 
  {
 
      int iLocal = 0;
 
   
 
      if( argc == 0 )
 
      {
 
          iLocal = 13;
 
      }
 
      else if( argc != 42 )
 
      {
 
          iLocal = (6 * 9);
 
      }
 
      else
 
      {
 
          iLocal = 1066;
 
      }
 
   
 
      return 0;
 
  }

This code generates the following assembler, which given what we saw in the previous example is more or less exactly what you’d expect:

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  16
 
  17
 
  18
 
  19
 
  20
 
  21
 
  22
 
  23
 
  24
 
  
     7:     if( argc == 0 )
 
  002020B0  cmp         dword ptr [argc],0
 
  002020B4  jne         main+1Fh (2020BFh)
 
       8:     {
 
       9:         iLocal = 13;
 
  002020B6  mov         dword ptr [iLocal],0Dh
 
  002020BD  jmp         main+35h (2020D5h)
 
      10:     }
 
      11:     else if( argc != 42 )
 
  002020BF  cmp         dword ptr [argc],2Ah
 
  002020C3  je          main+2Eh (2020CEh)
 
      12:     {
 
      13:         iLocal = (6 * 9);
 
  002020C5  mov         dword ptr [iLocal],36h
 
      14:     }
 
      15:     else
 
  002020CC  jmp         main+35h (2020D5h)
 
      16:     {
 
      17:         iLocal = 1066;
 
  002020CE  mov         dword ptr [iLocal],42Ah
 
      18:     }
 
      19:
 
      20:     return 0;
 
  002020D5  xor         eax,eax

The main things to note about this code are:

  1. Each if and else if condition is implemented as a cmp followed by a jxx – there are two new ones in here: je (jump equal) and jne (jump not equal)
  2. As in the first example, each if and else if condition is causing the compiler to generate the logically opposite test to the high level language, and skipping the assembler generated by the controlled block of code if it succeeds
  3. The test for the first if jumps to the condition of the else if when its condition is not met. If there were more chained else if statements then this pattern would continue through them.
  4. Each block of code has an unconditonal jmp at the end of it that takes the execution past the code block controlled by the else

That was all pretty straightforward for once. Joy.

Next, let’s take a look at the effects of the && and || operators:

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  16
 
  17
 
  
#include "stdafx.h"
 
   
 
  int main(int argc, char* argv[])
 
  {
 
      int iLocal = 0;
 
   
 
      if( ( argc >= 7 ) && ( argc <= 13 ) )
 
      {
 
          iLocal = 1024;
 
      }
 
      else if( argc || ( !argc ) || ( argc == 69 ) ) // deliberately nonsensical test
 
      {
 
          iLocal = 666;
 
      }
 
   
 
      return 0;
 
  }

This generates the following assembler, which is much more interesting than the  first if … else if example:

1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  16
 
  17
 
  18
 
  19
 
  20
 
  21
 
  22
 
  23
 
  24
 
  25
 
  
     7:     if( ( argc >= 7 ) && ( argc <= 13 ) )
 
  00F120B0  cmp         dword ptr [argc],7
 
  00F120B4  jl          main+25h (0F120C5h)
 
  00F120B6  cmp         dword ptr [argc],0Dh
 
  00F120BA  jg          main+25h (0F120C5h)
 
       8:     {
 
       9:         iLocal = 1024;
 
  00F120BC  mov         dword ptr [iLocal],400h
 
  00F120C3  jmp         main+3Eh (0F120DEh)
 
      10:     }
 
      11:     else if( argc || ( !argc ) || ( argc == 69 ) )
 
  00F120C5  cmp         dword ptr [argc],0
 
  00F120C9  jne         main+37h (0F120D7h)
 
  00F120CB  cmp         dword ptr [argc],0
 
  00F120CF  je          main+37h (0F120D7h)
 
  00F120D1  cmp         dword ptr [argc],45h
 
  00F120D5  jne         main+3Eh (0F120DEh)
 
      12:     {
 
      13:         iLocal = 666;
 
  00F120D7  mov         dword ptr [iLocal],29Ah
 
      14:     }
 
      15:
 
      16:     return 0;
 
  00F120DE  xor         eax,eax
 
      17: }

Now, I don’t know about you but the first time I saw assembler generated by using && and || I was amazed by the sheer simplistic audacity of it – I think it’s because I’m not an assembler programmer, but I expected it to be a little more complicated and fiddly than this.

Looking in detail at the code generated for the if statement using && (lines 2 to 5), we can see that is using another two conditional jump instructions we’ve not yet seen: jl (jump less) and jg (jump greater) and as before is testing the logically opposite condition to that specified by the high level code.

More interestingly, in order to implement &&, the compiler simply concatenates the separate tests – if either of these tests fails they will cause execution to jump past the block of code controlled by the if statement. This means that the block of code controlled by the if will only be executed if both tests are passed, which clearly implements a logical AND.

If we now turn our attention to the code generated by the if statement using || (lines 12 to 17) we see a similar pattern of consecutive conditional tests, though clearly it must be different since it implements conditions joined by ||.

The first thing to notice is that the first two tests done by the assembler are logically the same as their high level equivalents. This bucks the trend we have seen so far, but why?

Well, the address passed as operands to the conditional jumps on lines 13 and 15 will move execution past the rest of the tests, to the start of the controlled code block. Unsurprisingly though, the last test of the || if statement (lines 16 & 17) follows the standard test-the-opposite-and-jump-past idiom we’ve come to expect from an if statement.

The jump-into-controlled-block behaviour of all but the last || conditional means that as soon as any one of the tests is passed the controlled code will be executed, which clearly implements a logical OR.

Aside: Lazy Evaluation

I’m sure that most – if not all – of you will have heard that C++ has “lazy evaluation” of && and ||. If you’ve never been 100% sure of what this means, you’ve just seen it in action in this block of assembler!

The && will fail if either of its operands fails; so if the first test fails it will never do the second (or third, or fourth …).

Similarly the || will succeed if either of its operands succeeds; so if the first test passes it will never do the second (or third, or forth …).

Since neither necessarily evaluates all of its operands this makes them technically “lazy”; which in this circumstance you can read as awesome, elegant, and efficient (for certain definitions of efficient).

Summary

The main points to take away from the assembler we’ve looked at in this post are that:

  1. The conditional test that you see in the disassembly is likely to be the logical opposite of the test the high level code is asking for…
  2. …and the conditional jump will typically be jumping over the assembler that is generated by the “code block” controlled by the conditional in the the high level code.
  3. This is because there is no concept of a “code block” at the level of assembler.

More or less all control code boils down to various combinations of conditionals and jumps at the assembly level; and being familiar with the assembler mnemonics that are used to implement these C / C++ features, and the various ways that they are used will almost certainly prove invaluable when you find yourself in the unenviable situation of a crash deep within some library code that you don’t have symbols for (or that your debugger can’t find symbols for).

Incidentally if you find yourself lost in code that you should have symbols for but your machine refuses to find them, you might try this post by Bruce Dawson to see if it helps 😉

Next time we’ll continue looking at conditionals with the conditional operator (also known as the “ternary operator” or more commonly the question mark), and the the switch statement.

Also, thanks to Fabian and Bruce for giving this a once-over and offering sage advice on content.

 

Disclaimers

I am pretty sure that the code in this article doesn’t demonstrate all the relational operators; so I’m leaving it to you, dear reader, to try out the ones I left out to see what they do 🙂

I also avoided writing any conditions for the if statements that contained function calls, clearly this will make the assembler generated by the test code significantly more complex and assuming that you have read the previous posts on the assembler generated when calling functions too you should be able to make sense of this by yourself. I have to admit that I also partly avoided doing this so I could steer clear of operator overloading. That’s for later. Probably.

Unit Testing in Unity

Original Author: Poya Manouchehri

When I started working on my new project recently, I was thinking a lot about how I can unit test the code. I knew that if I left it for later and built some momentum with the game code, I would probably never take the time to come back and write tests. The challenge of writing unit tests for me is twofold. First and foremost, a game is different to many other types of software in that a good portion of the code is handling input, and visuals/graphics/UI. These are two notoriously “un-unit-testable” parts of a system. How do you, for example, write a test that checks that your grenade explosion looks right? (Do note that there are other kinds of tests that can be appropriate for such scenarios and at least stop regression, but not unit tests). The second challenge, is creating unit tests within Unity. In this post I’ll share some of my experiments and thoughts about unit testing with the Unity engine. This is certainly not a definitive guide on the subject and I’m sure I’ve made mistakes. I simply want to open up the discussion on the subject. I also want to thank Richard Fine with his help and feedback on this!

A Unit Testing Framework

I started looking around for a framework that I could use in MonoDev and Unity. There are in fact a couple of free solutions around like here (note: I work with C#).

Unity Editor Extension

I really needed to give a shout-out here to the Unity team for making it so easy extend the UI! I was pleasantly surprised by how quickly I could bake the test UI right into the editor menus and windows with simply implementing two methods, and this is the free version of Unity (check out this article for a more thorough description. Thanks Richard!). I am already thinking of all the other tools that I could add, including a data editor. One issue I did run into is that you cannot run MonoBehaviour code on a worker thread, and the calls to Repaint do not seem to repaint the UI immediately. As such, at the moment the test results only refresh after all tests have been run.

So What Can I Actually Test?

The million dollar question. The bottom line is, it’s impossible to test everything. And as mentioned earlier, graphics and visuals related code are not really well suited for unit testing. Here are a few conclusions I have arrived at so far which might be helpful when going throught this.

Separating Logic from Visuals

More specifically, having pure classes that do not derive from MonoBehaviour and ideally do not deal with GameObjects and other scene specific constructs. Your data access class(es) are an example of this. Or your AI related classes. There are more subtle cases where you can critically look at a MonoBehaviour and decide to refactor some of the logic inside the methods such as Update into a helper class that is more easily testable. Note that this doesn’t mean you cannot use any Unity types in such classes, however if they have dependency on the scene, other objects, components and their state, then things get a little tricky.

Speaking of data access, if you have been thinking about a data store for your game and sqlite is a viable option, do remember that that it supports an in-memory mode which is ideal for testing. Simply switch out the connection string during the test run with “:memory:” and you can bypass all the issues of dealing with files and speed up your tests.

Testing MonoBehaviours

Of course there is always logic in MonoBehaviours that you simply cannot take out and test in isolation. Now if you try to simply instantiate a MonoBehaviour in your script you will see this error in the console:

You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all

A fair point. A MonoBehviour only really exists in the context of its parent object. If it’s not modifying anything about that object then it probably doesn’t need to be a MonoBehaviour. In order to get around this I put a simple utility class together, which looks something like this:

public class ScriptInstantiator
 
  {
 
      private List GameObjects { get; set; }
 
   
 
      public ScriptInstantiator()
 
      {
 
          GameObjects = new List();
 
      }
 
   
 
      public T InstantiateScript<T>() where T : MonoBehaviour
 
      {
 
          GameObject gameObject;
 
          object prefab = Resources.Load("Prefabs/" + typeof(T).Name);
 
   
 
          // If there is no prefab with the same name, just use an empty object
 
          //
 
          if (prefab == null)
 
          {
 
              gameObject = new GameObject();
 
          }
 
          else
 
          {
 
              gameObject = GameObject.Instantiate(Resources.Load("Prefabs/" + typeof(T).Name)) as GameObject;
 
          }
 
   
 
          gameObject.name = typeof(T).Name + " (Test)";
 
   
 
          // Prefabs should already have the component
 
          T inst = gameObject.GetComponent<T>();
 
          if (inst == null)
 
          {
 
              inst = gameObject.AddComponent<T>();
 
          }
 
   
 
          // Call the start method to initialize the object
 
          //
 
          MethodInfo startMethod = typeof(T).GetMethod("Start");
 
          if (startMethod != null)
 
          {
 
              startMethod.Invoke(inst, null);
 
          }
 
   
 
          GameObjects.Add(gameObject);
 
          return inst;
 
      }
 
   
 
      public void CleanUp()
 
      {
 
          foreach (GameObject gameObject in GameObjects)
 
          {
 
              // Destroy() does not work in edit mode
 
              GameObject.DestroyImmediate(gameObject);
 
          }
 
   
 
          GameObjects.Clear();
 
      }    
 
  }

The InstantiateScript() method creates an appropriate prefab object for the script, or if one is not available just creates an empty object and the associated script instance. The Start() method is then called where available. If you are using other methods like Awake() that also needs to be called. Awake/Start/Update methods need to be public in this case so you can call them from your tests. I have to admit these are shaky waters because initialization of a MonoBehaviour is probably more complex and there may be situations where the code above is incomplete. But for the basic scenarios, this is fine. Another thing to note here is that I am loading the prefabs from the resources folder, and their name always matches that of the script. In a more complex project where the same script is used as a component of different prefabs, you may want to explicitly pass in the name of the prefab. Additionally there may be situations where you want to create a simplified prefab only for the purposes of testing. In those cases you should keep the test prefab in a folder outside of resources (e.g. Assets/TestPrefabs) to make sure it is removed from the production build.

The CleanUp method is called in you TearDown method to make sure the objects don’t stay around.

Here is an example test:

[Test]
 
  public void MovingEntitiesUpdatesConnector()
 
  {
 
      var source = ScriptInstantiator.InstantiateScript<Entity>();
 
      var target = ScriptInstantiator.InstantiateScript<Entity>();
 
      var connector = ScriptInstantiator.InstantiateScript<Connector>();
 
   
 
      connector.SetSourceEntity(source);
 
      connector.SetTargetEntity(target, true);
 
   
 
      source.transform.position = new Vector3(-10.0f, 0.0f, 0.0f);
 
      target.transform.position = new Vector3(0.0f, 10.0f, 0.0f);
 
   
 
      connector.Update();
 
   
 
      Assert.IsTrue(Vector3.Distance(connector.transform.position, source.transform.position) < 0.01f);
 
      Assert.IsTrue(Vector3.Distance(connector.EndPoint, target.transform.position) < 0.01f);
 
  }

Not Every Test is a Good Test

One issue that Richard brought up during our discussion, was the trial-and-error nature of game development. Whilst most types of software are prone to design changes, I don’t think any of them involve the same level of going back and forth and tweaking features that games do. For that reason it is possible to write a bunch of tests that change very frequently and, in a way, become a burden. Of course there are any hard rules around this. Based on experience and just doing, we need to figure out what aspects of a piece of code can be tested and be expected not to change frequently, and what aspects are just too volatile. But we have to remember that all code can be subject to change and not be afraid of writing tests because we may need to change them.

It’s also good to remember that some unit tests are more useful later in the development cycle, at which point changes are less frequent. For example when a bug report comes in during the beta phase, you can write a test that exercises the bug and then write a fix. This way you are protecting your code against regression.

Again I have pointed to the source code on my blog here

The Value of Valgrind

Original Author: Max Burke

My team at work has been working on porting our core technology stack to a variety of platforms over the last long while. The total supported platform count for us currently is fifteen, with many more coming soon.

The biggest benefit to come of all of this, however, is an increase in the quality of our code. In addition to dealing with the pecularities of over fifteen compilers, especially around how some compilers deal with aliasing, comes an great exposure to extra tools. Supporting Xbox 360 gives you access to Microsoft’s static code analyzer, and Mac OS and Linux both provide access to clang’s static analyzer and valgrind.

Valgrind is a collection of tools based around a VM, not entirely unlike the JVM or the .NET CLR, but where the opcodes are the native instructions for your platform. The Valgrind runtime breaks down the instruction stream into its own SSA format which its plugins can then operate on. One plugin, memcheck, has been especially informative as it keeps track of memory that is initialized (both stack and heap), memory that isn’t, reads/writes beyond allocation boundaries, and ensures that calls to certain standard library functions (like strcat, strncat, strcpy, strncpy, memcpy) are conformant in regards to overlapping memory regions and necessary destination sizes.

Why is this handy? Consider this code:

 
  int AddThree(const int *a)
 
  {
 
      return *a + 3;
 
  }
 
  
 
  int Foo()
 
  {
 
      int a;
 
      return AddThree(&a);
 
  }
 
  

Most compilers will run right by this code without seeing any problems. Down the road when the result of Foo() is used, valgrind will point out that the memory was uninitialized.

 
  ==22064== Syscall param write(buf) points to uninitialised byte(s)
 
  ==22064==    at 0x2C11BA: write$NOCANCEL (in /usr/lib/system/libsystem_kernel.dylib)
 
  ==22064==    by 0x17B59D: __sflush (in /usr/lib/system/libsystem_c.dylib)
 
  ==22064==    by 0x1A6F6C: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
 
  ==22064==    by 0x175990: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
 
  ==22064==    by 0x17118D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
 
  ==22064==    by 0x17A2CF: printf (in /usr/lib/system/libsystem_c.dylib)
 
  ==22064==    by 0x100000E26: main (test.cpp:26)
 
  ==22064==  Uninitialised value was created by a stack allocation
 
  ==22064==    at 0x100000D70: Foo() (test.cpp:10)
 
  

Unfortunately it’s much more memory and CPU intensive, with memcheck your program will run 20-30x slower than normal, other plugins are even more demanding. It also doesn’t get the same info if you use replacement standard library functions, like the aforementioned strcpy, strncpy, strcat, strncat, and memcpy. Although valgrind provides macros for indicating to the runtime the state of memory blocks for your own custom allocators they don’t seem to work quite as well as the ones they provide for the system malloc/free functions.

In addition to memcheck, valgrind comes with a couple other plugins. Cachegrind profiles how your program interacts with the processor caches and tracks branch (mis)prediction. Here’s some sample output from a naive matrix transposition function, including all the stats on a translation unit and function level. The ‘I’ stats are for the instruction cache, the D stats for data cache. The ‘r’, ‘w’, ‘mr’, ‘mw’ are counts of read hits, write hits, read misses, and write misses. The data cache data is split between level 1 and last level which could be L2 or L3 depending on your processor’s architecture.

 
  --------------------------------------------------------------------------------
 
         Ir  I1mr  ILmr        Dr   D1mr   DLmr        Dw      D1mw      DLmw
 
  --------------------------------------------------------------------------------
 
  8,989,376 1,739 1,491 1,588,449 70,122 67,907 1,210,659 1,049,203 1,049,073  PROGRAM TOTALS
 
  
 
  --------------------------------------------------------------------------------
 
         Ir I1mr ILmr        Dr   D1mr   DLmr        Dw      D1mw      DLmw  file:function
 
  --------------------------------------------------------------------------------
 
  6,298,642    2    2 1,048,579 65,537 65,537 1,048,580 1,048,576 1,048,576  /Users/max/src/tmp//test.cpp:main
 
  
 
  --------------------------------------------------------------------------------
 
  -- Auto-annotated source: /Users/max/src/tmp//test.cpp
 
  --------------------------------------------------------------------------------
 
         Ir I1mr ILmr        Dr      D1mr      DLmr        Dw   D1mw   DLmw 
 
  
 
          .    .    .         .         .         .         .      .      .  void transpose(float * __restrict out, const float * __restrict in)
 
          .    .    .         .         .         .         .      .      .  {
 
      1,027    0    0         0         0         0         0      0      0      for (int y = 0; y < 1024; ++y)
 
          .    .    .         .         .         .         .      .      .      {
 
  1,054,721    0    0         0         0         0         0      0      0          for (int x = 0; x < 1024; ++x)
 
          .    .    .         .         .         .         .      .      .          {
 
  5,242,880    0    0 1,048,576 1,048,576 1,048,576 1,048,576 65,536 65,536              out[x * 1024 + y] = in[y * 1024 + x];
 
          .    .    .         .         .         .         .      .      .          }
 
          .    .    .         .         .         .         .      .      .      }
 
          .    .    .         .         .         .         .      .      .  }
 
  

As well there is callgrind which is similar to cachegrind but generates call graphs as well, helgrind and DRD which help detect errors in multithreaded code such as data races and incorrect use of threading primitives, massif and DHAT which profiles your heap (and stack) usage. There is an experimental tool called SGCheck which aims to detect global and stack array overruns.

Even though I’ve barely scratched the surface of what valgrind is capable of, I’ve found it to be immensely useful when tracking down memory related bugs. Because it’s free and really easy to use — no special libraries required, just run ‘valgrind foo’ — it’s easy to promote the use of to others on your team, and also easy to hook into your automated tests if you have any.

Besides, one can never have too many tools at their disposal!