Refactoring tools are one of the single most important tools developpers have. Also, using a distributed version control system, especially Git, makes it trivial to try out experimental features and not worry about screwing up royally and ruining your codebase.
They're basically a set of tools built into the IDE which allow you to clean up code easily. Things like renaming variables and adjusting their references globally for an entire project, extracting sections of code into methods, encapsulating fields into get/set methods, etc...
I found a few free trials already, but I'm wondering: are there any tools that make suggestions for improvements rather than "click me to rename a variable" tools? I don't mind the work needed to shift code around (my projects are small), but I'm open for suggestion for what to improve.
(I use Cppcheck as a static code analysis, but it doesn't seem to find that much, so I guess it only searches for actual problems, not possible improvements. (Might just be my awesome coding skills though!)
@Gaminic,
i've noticed that with cppcheck as well. Maybe it's a good thing... Try Clang's static analyser; I seem to remember it being more thorough.
Also, Valgrind is probably my favourite debugging tool. It's mainly for fixing memory leaks but it detects lots of other errors which makes it incredibly useful.
My advice for you is to start with the game design, think about the genre, the features, the gameplay, the story (make the story your main focus if you want to create a single player game) and after you've planned that create a poll and ask people what do they think, and expect feedback from gamers from casual to hardcore. After you get a thumbs up from people start worrying about code.
Having a really good design document will make the coding much much easier. The thing about making video games is that the programming is a very minute fraction of the overal process. It is the means, rather than the end. Think of *what* you want to do, then design your game in an abstract way (with diagrams, paragraphs, etc... and very little code). Then once you have a good idea of what you want to do, and how you want it to fit together start writing code to make your ideas concrete.
It might be helpful also to use something like Python/Pygame at first, instead of delving into low-level C++ because you can make your prototypes much quicker and it is much easier to change the code. Once you have a solid prototype you can port it to C++ if you need to (you may realize that your game doesn't need a high-performance language and Python is sufficient).
Looks like Clang's static analyzer requires more than just "install and run". I've never done anything with external libraries/building from source stuff. I guess I'll stick to Cppcheck for now. [At this point, I don't think there's much that CAN go wrong, so that might be the reason Cppcheck isn't finding much.]
I disagree with palfil and darkestfright. A design document really only makes sense if you really know what you're doing, which clearly isn't the case for a beginner. And C/C++ doesn't automatically make anything low level.
@Gaminic,
I don't remember how I installed it but I would have thought it was via my Linux distribution's package manager. I'm sure cppcheck is fine though.
C/C++ doesn't automatically make anything low level
programs translated to C/C++ are almost always several times
Hanst99 makes a valid point. Just because C++ can be low level doesn't warrant the stereotype that C++ is out to reinvent the wheel with miles of low level code. I've actually saved space / complexity on a lot of code ports by using constructs of C++. Granted, I've used libraries to do so, and the code that I was porting wasn't designed as well as it could have been, but still.
IMO a programmer should be at least a whisker past the beginner stage before attempting to make a non-trivial game.
I actually don't think it's the job of C++ to provide facilities for you. I don't know why people are against that or can't make the distinction between C++ and facilities that are made in C++.
Anyways, given my fair share of programming games, I've found that your first game shouldn't be designed because you don't know what or how to design it because you don't have the experience to do so. You end up spending more time than its worth on designing which will end up heavily flawed anyways.
I suggest getting a library or two to accomplish your goal and trying to rush the game. Don't intentionally make it sloppy but do take note on things you could have done better. When you finish the game (if you do), restart the creation of the game in a cleaner manner using better and more refined techniques and design, the design being things you know you can improve from the beginning of the creation of the game.
After so long of doing this with various things, it will eventually come naturally.
Also, this can be applied to just about anything as long as you're open to failure. It's a relatively fast way to learn.
EDIT: Also, C++ is not a beginner language. I assume that you understand the quirks of relatively low-level programming and C++.
EDIT2: While "recreation" works in the beginning, it becomes inefficient after the second, and eventually from the get-go. Recreating a program is only efficient if the entire program is crap as far as design and technique goes which I assume is how your first game/large-scale program will be.
What are some of the higher level constructs of python anyways? I know a little bit of python, but other than those abilities that more or less directly result from it being an interpreted language, I don't see what makes python so terribly much higher level than C++.
What are some of the higher level constructs of python anyways?
This:
I assume that you understand the quirks of relatively low-level programming and C++
You need to know lots of low-level things in C++, before you actually start coding anything bigger than hello-world. You need to know manual memory management. You need to distinguish between pass by reference, by value, by pointer. You need to know how compilation / linking is done and all the crazy stuff about header files. You need to learn about undefined behaviour very early. Otherwise you'd immediately find yourself creating new posts on C++ forums with titles like: "why does my program corrupt heap; what is heap corruption anyway? what does this mysterious compiler error mean (and 50 lines long error folllows)?".
In Python / Ruby / Scala: none of the above. You just write simple code and it works. No need to deal with memory, it is handled for you. No need to ever worry where to allocate objects - just create them. No need to worry about argument passing semantics. No need to worry about undefined initialization order. No need to worry about 32bit / 64bit compatibility, etc.
Additionally these languages allow for lexical closures, which C++ doesn't have, and which is a very high level and powerful concept, especially for library creators. Full lexical closures are not possible without GC.
Imagine you have a short-ish project (~month of work). You can either do it quickly first, then do it properly based on the experience you got from the first; or, you can try to do it properly at first go, but it will be slower, because you have to think and plan more carefully. Which do you pick?
Personally, I always get annoyed halfway through a project because of the "mess" I made by introducing small changes, thinking "I should just restart and do it properly". When I do restart, I often end up changing my mind on something and ultimately end up with a mess again, thinking "next time I'll do it such and such". With my latest project, I've been trying to work out everything before actually implementing everything. At one point, I was convinced that I had the structure I needed and begun programming, only to find out I forgotten to take something into account, thus forcing me to redesign (large) parts of the project.
Is there a way to do it properly? I'd use design documents, but it's usually some low level stuff that gets me stuck ("Wait, this function belongs to that class, but it doesn't have access to a variable it needs."). I think it's due to my old addiction to global variables, getting me to "assume" certain variables are accessible everywhere.
So, should I spend more time on details in the design phase, or should I just go in head-first until I'm more experienced in making larger projects?
I personally prefer to always start small and then *refactor* as I go. I don't rewrite code. Sometimes I throw away one class or two, but never do a complete rewrite. I don't need detailed design before starting coding, only very high level design overview (just kept in head).
("Wait, this function belongs to that class, but it doesn't have access to a variable it needs."
Fixing things like that is usually a few minutes on a properly designed codebase, even if the modification itself touches tens of files. Pretty standard feature in C++ Java IDEs (change method signature, change constructor)
In Python / Ruby / Scala: none of the above. You just write simple code and it works. No need to deal with memory, it is handled for you. No need to ever worry where to allocate objects - just create them. No need to worry about argument passing semantics. No need to worry about undefined initialization order. No need to worry about 32bit / 64bit compatibility, etc.
That's not extremely compelling.
Manual memory management is only a minor inconvenience if you do it properly.
The difference between "just creating" an object and what you would do in C isn't that obvious to me either:
No need to worry about argument passing semantics.
Now that's just plain wrong, in Python at least. You DO need to know that arguments are passed by reference, and what the difference between
1 2 3 4
def my_func(x):
x = MyObj()
def my_other_func(x):
x.copy(MyObj())
is. Also, Python code can never be truly self documenting because type informations are lacking - you need to write down somewhere (or remember) what kind of argument types a function expects and what kind of output it generates - heck, the same function might be generating an integer in the morning and a string in the evening. This might be less of a problem with code you're writing yourself, but that did bother me a few times in the past already when trying to decipher poorly (if at all) documented (ruby, not python) code.
I guess my main complaint is that those languages aren't really much more expressive than, for instance, C++.