Well, I had hoped that the answer would be clear enough, but I will be more precise:
You only need to use "extern" if you are trying to share a variable across multiple translation units. In Handmade Hero, we have three total translation units: one for the platform layer, one for the game, and one for the few specific routines where we need to keep optimizations on all the time.
The only "real" translation unit here is the game, and that's where all the code lives. The platform layer and the optimized translation unit are "special", in that they have consequences - for example, we can not simply share a global variable across the DLL boundary, we have to think carefully about it and make sure we do it in a specific way. We cannot simply declare it "extern" and have it work.
So for our purposes, global variables are strictly those which are global to either the platform layer or the game, and those can (and should) be thus marked "static" since they never cross the translation unit boundary. Any variable which is _actually_ global to the _entire_ program must be treated specially, and we don't actually have any of these other than the debug services, which are handled specially.
- Casey