It's always a matter of heuristics, for sure. When you need to modify code in a way that's less than readable/obvious, then you start dropping in comments to compensate. Your first pass should be understandable and obvious and readable, with comments typically restricted to documenting functions and interfaces.