Making a Static Free Engine

I just escaped static hell after way too many hours of frustration. I write this as a map to help you escape static hell much easier than I did. As I am far from being a java guru, if you see a better way or have an issue with my methods, by all means pile in.

Because your Java program starts execution with a block something like, ‘public static main(String args) { }’ , Java sets you on the road to static hell. The experts will give you philosophical reasons why static variables and methods are wrong. I am not an expert by any means, so my reasons are plain and simple. The first reason why static is evil is static creep.

Static creep happens when you get an error that wants to to change a variable or method to static in order to resolve an error. Static is an addictive state in Java. The first two ‘public static int whatevers’ were free, but then you had to have a getter or a setter and suddenly you are on the road to static hell. Every change or addition wants to be static and when you finally try to make a constructor, you find that the word ‘new’ and the word ‘static’ don’t play well together. So you try to reduce the static and you discover the real catch, static cling!

Static cling happens when you try to fix your static filled code from the bottom up. You fix stuff until the code saves without error and then it blows up with a null from nowhere when you run it. If you are not real careful, you can easily thrash your code into meaningless gibber while chasing down and trying to comprehend where you went wrong. If every other line in your code resembles ‘system.out.println("it got past this part and x is now " + stupidValue)’ you know exactly what I mean. Once you figure out where you need to inject a proper linkage to avoid the null, unless your initial source for the linkage is clean, static creep sets right back in.

Here is a game engine example of how to escape static. This game engine consists of 6 objects; Game, GameEngine, Play, Canvas, GameLoop and GameContext. They key to escaping static is the GameContext object.

GameContext.java is how we escape from static hell. GameContext.java contains all or most of the variables and methods that would have been static. It also has all the appropriate getters and setters. The GameContext method can initialize objects and set this.whateverObject = whateverObject so that the initialized object can be referenced later. Your game might be better organized with GameContext divided out into a few similar objects but the function remains the same and the core context object can initialize and provide links to the other context objects.

Game.java is the central object passed to methods in order to link the various processes. Game has the main block in it. Game calls GameEngine.Java and passes itself and a new Play to it.
‘GameEngine.start(new Play());.’
By creating and passing Play in this manner, we have now excaped the static realm and everything else can be free of static.

GameEngine.java sets up the canvas and starts the game loop passing itself and Canvas.java to GameLoop.java.

Play.java extends Game.java and is where the engine becomes personalized to the game. If you keep the modifications and expansions of your engine as generic as possible, you can reuse it for other games you write. Ideally Play and GameContext are the two parts of the engine that bridge between the basic engine functions and your game. As you extend your game, alway keep in mind that generic additions might be more useful if added to the engine, and specific additions should remain outside the engine. Since Play.java extends GameEngine.java, generic functions can be maintained in GameEngine.java and Play.java can have the same function personalized with a ‘@Override’ in front of them. Play.java has the generalized methods for render and update that should probably point to render and update objects. Updated properly, Play is where drastic changes to the game can be made and reversed with relative ease.

Canvas.java is the graphic object and starts with ‘public class GameCanvas extends JComponent implements ComponentListener {.’ Canvas has all the listeners so Canvas is not only the object to refer to for display, it is the object to go to for interaction with the display.

GameLoop.java calls all of the background processes that make the game run. GameLoop calls a routine in Play.java to redraw everything and a routine in Play.java to update game status over and over again. A good primer on game loops can be found here, http://www.java-gaming.org/index.php?topic=24220.0

Now to string it all together all the classes that need it have a 'Game game; defined and set by either a setter or by having it passed as a parameter and set with the line ‘this.game = game;.’ The Game class has the line ‘Context context = new Context();.’

Since Play extends Game, when play runs the line ‘context.setPlay(this);.’ game.context.getWhatever()’ and ‘game.context.setWhatever()’ can pass to any objects that have the parameter game and ‘this.game = game;’ as part of the construct.

If the object you are working on is going to be large the line ‘GameContext gc = game.context;’ can make it pretty easy to access the pool of variables. Writing something like gc.getDataYouWant() to call up a value is pretty easy and an entire range of potential static errors can be evaded. All this and the Guru’s will tell you that you have avoided the slew of security, testing and philosophical issues that static variable present.

I really cant see whats wrong with static methods classes (if used right).

How are you creating constants?
if you dont make these static, you assign extra values for each class, or classes inheriting this class for each constant (seems like a waste).

Classes like loggers are also really handy as static.
I really dont get singletons, they would be the evil offspawn between static classes and normal OO, so i would argree to run from these.

An instance of a logger makes sense as a static member. The logger itself should not consist of static methods, unless you’re fine with Baby’s First Logger. Really though, there is no “static hell”: it should not present some kind of engineering challenge to avoid writing everything as static methods. It’s very much OOP 101, something you should be getting the hang of by the time you’ve done a tutorial or two.

Why would I make my logger OOP when it saves me a line or two having it static? As far as I can tell it would work exactly the same even if I didn’t have it static.

package core;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Core_ErrorLogger 
{
	private static void setup(String s)
	{
		File f = new File(s);
		
		if(!f.exists())
		{
			try 
			{
				f.createNewFile();
			}
			catch (IOException er) 
			{
				System.exit(0);
			}
		}
	}
	
	public static void logError(Exception exception, String className, String methodName)
	{
		final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
		final Calendar cal = Calendar.getInstance();
		final String s = "Error Log @ " + dateFormat.format(cal.getTime()).toString() + ".txt";
		
		try(BufferedWriter bw = new BufferedWriter(new FileWriter(s)))
		{
			setup(s);
			bw.write(className +" - "+ methodName);
			bw.newLine();
			bw.write(exception.toString());
		}
		catch(Exception er)
		{
			System.exit(0);
		}
	}
}

How about multiple loggers? Look at any logging system like log4j and you’ll see ways of turning loggers on and off by level or by the class they’re contained in and pointing them at different files, system loggers, etc. But if a hardwired implementation with no support for levels, facilities, or appenders is fine for you, then yeah I guess you could implement it with one or two statics.

Um… I think people arguing about static classes being all bad are well, misinformed. Let’s start with an article shall we…

Are static classes code smell?

Programming style is very important, and static methods actually is part of the reason why Java remains very flexible.

The biggest bane to static programming that I’ve seen is its harmful to unit tests. If you rely heavily on unit tests, static classes will make it pretty difficult to set up into test suite. They can cause threading problems as well, and data has to be controlled with much finer detail when dealing with static variables and functions.

It isn’t all bad…

Static classes allow you to transfer functionality of one class to many classes that might need the same thing (like error logs). As long as you keep track of how you are using static classes, they allow you to essentially “script” some OOP functions. In some cases, you’ll be able to solve a lot of problems faster with static calls because it’ll drastically reduce singletons when used correctly.

Like all facets of programming, you have to research and look at the benefits and the downsides of everything before you use it. Not only will you learn more about it, but it will also improve your programming knowledge as well.

As for me, I like static because it helps me reduce the amount of code I have to write. It isn’t for all aspects of coding, mind you. I like using static to keep some items separate from the main engine. Sometimes it is very beneficial to only have to initialize an object once and use that object for different parts of the program (like Loggers).

funny story

every programmer starts out using static all the time. When others are telling them that static is bad and they shouldn’t use it, they don’t listen because they have so many “good” arguments why static is the perfect tool.
A few years later they aren’t using static anymore and trying to convince the new ones…

p.s. when you already use static everywhere pls try not to have any static/global state. This means don’t have any static variables(only with final)

If I have a player class, and it needs to access ONE function in some irrelevant class for some purpose, am I really goin to go and add a field for that class, add an argument to my constructor, and then do the same for every class that references that constructor?!

No.

Static is good, when used appropriately.
Personally, in my ‘main’ game class, which stores the player and the entity/world/whatever managers, I have a static reference to that class (so it’s pretty much a singleton) so I can access that one function in the otherwise irrelevant class.

And what about math functions? Should I create a whole new object every time I want to find the magnitude of two coordinates (in a situation where I don’t need to create a new vector)?
Random functions? Do I need to create new objects for that? Or should I add yet another object to my now bloated constructor.

Worst of all: Constants. How do I do these without static? [icode]new Constants().CONSTANTNAME[/icode]?

Now, don’t read this wrong. Static has to be used wisely. But saying to never use static is (more) stupid compared to always using it.

Using static to make the compiler happy is a sign of n00b-programming. (If you did this before and realised your mistake, this is not meant to be offensive)

If you keep trying to avoid static, you’re going to end up in non-static hell. :o

Er, for random number generation you probably do want distinct instances.

Not random number generation, just random numbers. (Where you don’t need to use the random instance again, so it may as well be static)

[quote] am I really goin to go and add a field for that class, add an argument to my constructor, and then do the same for every class that references that constructor?!
[/quote]
That’s precisely the situation NOT to use static; if code in instance class A needs to access something in instance class B yet has no reference to it, then your class dependency coupling is wrong. Introducing a static in this situation will bite you in the ass sooner or later, because you’re masking a more serious design flaw.

I actually implement the Log manager as a singleton with methods to allow for those functionalities, but just wrap the methods into a static external method so I don’t need to worry about calling the Instance getter:

Its mostly a convenience thing for me, and since the Logger shouldn’t be running in production, I don’t care much for method call overhead or the like.

Also, @OP: Any part of a programming language specification, even goto, can be useful if used correctly, and any part can be an utter mess if abused. Trying to instill dogmatism in a community by stigmatizing something (“static hell”, classy) is hardly productive, specially when your post sounds like you expect to be preaching to the choir and as such be received with confirmation of your position.

Naughty you. ::slight_smile:

I personally use static methods and classes for standard operations that I expect to be useful. For example, I have a nice static trigonometry class with all sorts of math operations relating to angles, vectors, points, distances, etc… Classes that need to use said operations internally end up referencing the static function, so if I need to tweak an specific algorithm (say, a vector-vector intersection calculation) I don’t need to go around tracking all classes that implement it.

We use static everywhere! And when it turns out to be a pain, the Magic Refactoring Fairy waves her wand in Eclipse, and the pain is gone!

Cas :slight_smile:

I tend to avoid statics if I can but if a class is stateless or singleton then I see no reason why it couldn’t be all statics, in the context of game development anyway.

Careful: a boon is a blessing/benefit, not the opposite :wink: Unless you deliberately want to undermine the ability to create automated tests of course!

Don’t use static if you don’t know why. Eclipse error saying “can’t use in non-static context” is not a good reason.

^haha… I’ll fix it up there. I meant to say “bane”, silly phone :P.

I am really going to see just how far I can get without static. I am usually pretty good at debugging things, but the tangled mess I recently created has left me trembling in fear.

Random numbers are no biggie. SimpleRNG produces a fairly sweet set of random numbers. I rather like pseudo-random generators anyway. With the same seed you get the same result. This allows me to examine a random game setup and replicate the ones I really like by using the same seeds. It is quite possible to save a world map by saving two doubles. Most RNG’s show their flaws in a multi-thread system. Either they are not thread safe or they end up producing enough of a pattern for you to start guessing what comes next with reasonable odds. once you figure out how to keep cranking numbers between zero and 1, you can make a slightly different generator for each thread. Done well, this can make pseudo random numbers seem pretty random.
Pseudo-random generators can be useful in testing as well. Best hidden program change detector I ever saw was based on a random number check. If you want real random numbers record the interval between a players key press events while starting the game and adjust a seed with that result. You can keep measuring user timing to adjust your seeds. This does create a potential testing flaw. Live use is more random than test events.

Guice looks like a a good anti-static laundry sheet for Java. I have no experience with it, but it look pretty sweet. JUnit I love, I just need to use it more. It makes me twice the programmer I would otherwise be.

As far as constants go I rather like using enum so I guess I am avoiding the word static and not all static instances. Enum can be used to give code clarity so I rather like it. Enums don’t work well with the word new, but the implicit error checking that goes along with the word enum seems to prevent my doing really stupid things with them that won’t show up till much later.

While I am going to make a serious try at being static free, I got over my dependence on philosophical coding limitations years ago. At one time there were two new languages that were neck to neck in competition, C and Forth. I picked Forth. Part of the Forth philosophy was no floating point. It made sense at the time. By keeping important values as a ration of two potentially very large integers you could avoid the rounding errors caused by division until it was time to output a final number. You simply multiplied divisors with the divisor to effect division without having to do it. This was all well and good, but it was a pain when you just wanted quick and dirty and didn’t really care that you might be off by a ten thousandth. This was a particularly sad thing since no language before or since has been as good at doing quick and dirty. Forth coders implemented floating point stacks, but floating point was never part of the approved standard.

I have been using static as a way to provide simple access to data that I did not mind being global. Now I only use static if it absolutely has to be global. So far the only thing that has had to be global is the main method.

All this talk about how “Java gurus” will tell you not to use static is garbage. >:(
Static is a helpful tool that saves so much time.

Static is there for a reason.
It’s extremely stupid and a waste of time, if not impossible, to avoid it at all costs.

If you don’t know what the reason for something is, find out! Don’t go into all the trouble to create some hacky time-wasting workaround. Why would you do that?

Going out of your way to avoid static is stupidity (unless you’re doing so as some kind of weird challenge).
Telling others, especially beginners, to join you is evil.
If you don’t know what something is for, and use it wrong, don’t go and tell everyone else not to use it.

To summarise my argument:

  • Static makes coding more efficient.
  • Static needs to be used sensibly or else you will fail.
  • If you make a mistake, it’s probably your fault, not the tools’.
  • If you don’t know and properly understand what you’re talking about, don’t be talking about it as someone who does.

If you really want to completely avoid static, by all means go ahead.
Just don’t drag down other people into your mess with you.

To avoid starting a flame war, I will now apologise for any feelings that may have been hurt by this post. It was not meant to cause (too much) offense. (but if it has, that is a bonus!) Anyway, I hope you learnt something from this. Insults have no real value, and should not be taken seriously unless you completely ignore this post and deny your mistakes. Thank you. ;D

Avoiding static because someone told you so is basic ignorance.

I use do do indirect contract jobs for a big gamedev company. Code is quite rigid. I even have to follow their comment style.

When I sent them preliminary source, it contained singletons ( for a depth-buffer autoincrementer since you can’t disable depth buffer testing on the console ). Code was sent back saying to ditch singletons in favor of namespaced statics. Same note also told me to use “intrusive” ptrs in lieu of “shared” ptrs.

Code is supposed to make sense.

Code also needs to be easy to maintain. A strict coding style is invaluable for a company where different developers can get their hands on the code.

Speaking from experience here. Nothing ruins your day as finding out a critical section of code is not only built in a completely different style as the rest of the (massive) program, but even the comments are in a language you can’t even read!