Much has been said, so I will write a little about the specifics of this project.
I am currently working on a platformer game (or rather a tech demo), created without using any library to build games (just for fun). For this purpose, I use the
TForm class and various utils from the standard library. No hardware acceleration. More about I described
in this old post. The code of the game is practically ready, now only need is to create levels and I can publish the project. That's why I'd like to remove what is unused from the code.
Currently, the main project consists of 35 units (with
.lpr unit), slightly over 12,000 LoC. Each unit has a separate logic wrapped in a class or several classes, using inheritance or not (depending on the needs). If only one instance of a given class is used throughout the entire game, it is simply contained in a global variable, declared in the same unit as the class declaration. It is convenient (although no one likes global variables, but they do not bother me).
For example, the unit
Platformer.Levels.pp contains a global variable named
Level and it is used by other classes from other units (because always only one instance of the
TLevel class is used at the moment). It looks the same as with global variables with form instances in a classic application. Each global variable is used to store an instance of a class. Instances of classes for global variables are created and released in the main game class (ie in one place, not using the
initialization and
finalization sections—these are not used at all).
I decided to play with the code and in addition to global variables, also use other less common techniques. For example, multi-level nesting of class declarations, custom helpers for various types, class variables, some syntactic sugar and so on.
For now, I'm still using the
Debug mode generated with the
Build modes tool in the project options window. All message settings are enabled (default for this mode). The compilation is clean—no hints or warnings. The only exception is the
Symbol "ScanLine" is not portable warnings, but that's not a problem.
In
Release mode (generated, also with default options), I have 30 warnings, only about
ScanLine and uninitialized local variables and
Result in methods (all by using
case of statement, but this is also not a problem, because the control flow is always correct). Example:
function THeroRenderer.GetArea(AHero: THero): TRect;
var
CropSize: Integer;
begin
Result := AHero.Location.Area;
if AHero.Dozing or AHero.Walking then
begin
if AHero.Dozing then
CropSize := AHero.DozePhase
else
case AHero.WalkPhase of
0: Exit;
1: CropSize := 1;
2: CropSize := 2;
3: CropSize := 1;
end;
case AHero.Orientation of
voNormal: Result.Inflate(0, -CropSize, 0, 0);
voUpsideDown: Result.Inflate(0, 0, 0, -CropSize);
end;
end
else
if AHero.Falling and not AHero.Rising then
Result.Inflate(0, Abs(AHero.VerticalSpeed));
end;
Variable
CropSize is uninitialized for the compiler, but it will never be used without initialization. If I turn off the optimizations (or set the
-O1 or
-O2), the compilation is clean. So the warnings about uninitialized variables is shown only if I use more aggressive optimizations.
Well, I wrote unnecessarily. Since there is no way to get a list of such elements (also for the debug mode), then I will have to check each one separately... Thanks for the answers.