My Game Engine So Far

I’m really hoping this is appropriate for this section.

What I would really like, is if a few people would take a look over an engine I’m building so far, and maybe deliver some constructive criticism about it. I’ve never done any real game development before, so I’m sure I’m making quite a bit of mistakes.

My main concern is that the engine is setting up the game screen properly/efficiently and that the game loop is good enough to be used in games (I used an example I got from this site).

Here are the files for the engine:

Eclipse project: http://www.filedropper.com/erebos
Jar : http://www.filedropper.com/erebos_1

Things to look at:

The display package and the core package. This is where most of the work has been done.
The examplegame package. This “game” is just what I use to test features and whatnot. You can use it to see how a game by this engine behaves.

Any advice that might lead me in a good direction would be great.

Side note: If you run the examplegame, and you get a blank screen, try minimizing and maximizing. Also, be sure to note that you had that problem in this thread.

Thanks in advance!

Host your code on Github; if people want to contribute they can easily send you pull requests or open issues.

I don’t necessarily want people trying to contribute. My goal for this thread was to find some people who would take a look at my engine so far, and give me some pointers on where I could improve.

I’ve decided to go ahead and upload my engine for anyone to look at. I’ll be updating the OP.

If it runs games and has no bugs then it is great.

I know that right now my ehh…engine :-\ works for the most part and would love for someone to make sure everything is done right but the best way to check is to pump out some games.

A few findings:

  • a game engine should be as flexible to use as possible, so methods should never be declared as final, there is no benefit anyway
  • same reason as above against private classes
  • always log the cause of exceptions
  • deriving Swing components is rather unusual and there should be a very good reason to do so, otherwise do not inherit but just use them as component
  • synchronizing is partly insufficient
  • no creation of concrete ui components and screens in the game engine as well as no hardcoded fonts and colors, that could be extracted into an optional layer of standard screen
  • mouse handling is always creating tons of Point objects even if there is no later use of them
  • no public members please
  • why is keyboard and mouse input bound to each game object ?
  • is Player#update() called from several threads or what is the synchronization for ?
  • there is EGame#createGameCanvas but later on the canvas is modified in gameloop, createGameCanvas should do the full creation
  • EGame#gameLoop should not be private and final
  • EGame#isRunning needs to be synchronized or made volatile
  • what are the roles of EGame and EGameStarter, which one does actually start the game ? EGame is constructed with EGameStarter and EGameStarter starts with an EGame object

Agreed to what 64k said, except for the final and private comments. Some parts of an API can be private and/or final as they might change in the future. Final/private keeps people from messing with internals and then complaining if the API/implementation breaks.

Wow. Thanks for taking the time to check out the engine! Here are my responses to your responses. The ones that are numbered, I’d love to get some more detailed feedback on.

  • The only thing final does is disallow a user from overriding a method. Though, I see your point. The engine is open source anyway, so I might as well give them the freedom to use it how they want.

  • I suppose the same could be said about private classes. Though, I use that for methods that have no reason to be called from outside their own class.

  1. How should I be logging the source of exceptions??

  2. Can you explain what you mean by “deriving Swing components is rather unusual”?

  • Unless I’m mistaken, the only place I use synchronization is in the input classes, which I’ve made singletons. Once the objects are made, the program won’t encounter the synchronization call again. But, I agree. If you did see that call elsewhere, could you let me know?
  1. I don’t get what you mean by “no creation of concrete ui components and screens in the game engine”.
  • I agree that the Points are kind of wasteful, I’ll change that.

  • No public members. Got it.

  • This is a good point. If an object needs the input devices, they can request them.

  • Well, now that I’ve gotten to this point, I see where there is that synchronization. That can be taken out.

  1. The point of createGameCanvas, is for the user to be able to use the canvas they’ve created. The code that is done outside of that method is code that should run regardless of what kind of canvas they’ve used. I can’t quite think of a more efficient way to do that part.

  2. While on that point, is there any issues with allowing for multiple canvases (for things like pop up menus, different levels, etc), or should the same canvas be used for everything?

  3. Noted about the gameLoop. Besides that, does the actual loop seem to be okay?

  • isRunning will be synchronized.
  1. I tried to explain in the comments the best that I could. The EGameStarter is basically just a start button for EGame. Since EGameStarter is not used outside of the constructor, I found that it was more efficient to have EGame create it and display it. The reason it’s passed into EGame is in the event the user wants to create a custom start up dialog, rather than use the default that I’ve built. And EGameStarter needs the current instance of EGame to be able to call it’s run method to start the game.

Thanks again for doing this for me. If anyone else would like to check it out, that would be great!

Edit: Did the example game display properly for you? That’s kind of important.

Agreed to what 64k said, except about public members since I use it sometimes for trivial variables.

I appreciate the comments, but could you guys maybe add a bit more? I understand that 65K gave good advice, and I even addressed all the issues he noted. If could get some answers to those queries, that’d be great.

These are the requirements to have a good engine. (In order of importance)

  • It launches
  • It runs
  • It doesn’t crash
  • It works
  • It works well
  • It is usable
  • It is easy to use
  • It is flexible
  • The code is readable
  • The code is easy to read
  • The code looks pretty

The last few can be skipped if you are interested in making games, which is why MOST of us are here.

(EDIT: I hope by engine you mean the framework for your game, and that you’re not reinventing the wheel :point:)

Well, those are concepts that pertain to any type of programming.

I’m making an engine because I’m interested in making games. And yeah, it’s an engine. It’s all about experience. There is no reason to go and rewrite the Linux kernel, but so many programmers do that as a milestone in their career.

I’m likely the only person who will use the engine to actually build games. It’s much easier to start with a framework you built yourself, rather than a third party engine.

Agreed. (Although I’d go all the way and make a full operating system if I had the time ;D)

Some tips:
If your doing some Maths equations make a static methods in a Maths class for those more dIfficult equations even if you don’t use them, you could build up your own maths class over time.

If your going to try and keep this engine for future games you make try keeping any of this game outside of your engine code maybe even back the engine code up in a new folder so you can easily copy and paste the code into your new project if you don’t want to have to add a jar to your build path.

Use one existing logging framework and feed it with caught exceptions.

By inheriting you tightly couple your whole game stuff to concrete Swing components.
Then, you extend its responsibility with domain (game) specific stuff.
And force engine users to use your components.
Look up inheritance vs. composition.

When synchronized methods access members, all others methods doing that as well, must be synchronized too, otherwise that has no effect.

Again, that is highly usage dependent. Choice of UI classes, look, layout and their compositions should be left to the engine user.

Just let the user completely create the canvas. Splitting the creation code causes confusion and is inflexible.

Don’t start the game from the constructor. A constructor creates an object but should not start the game. Doing so, the dependency to EGameStarter would be obsolete.

Btw: the game shows up properly

Thanks for clearing that up for me! All of what you said makes sense, except

[quote]Just let the user completely create the canvas. Splitting the creation code causes confusion and is inflexible.
[/quote]
I don’t think you quite understand what is “split up” about the code:

The user creates a new EGameCanvas class. In there, they do all the rendering, graphics updating. When they create a new game, they override the method

public abstract EGameCanvas createGameCanvas()

To simply return an instance of the class they wrote.

The only thing that’s not done by the user is setting up double buffering, and add the key/mouse listeners.

Like I said, this is the best way I could think to do it. Though, maybe that will change once I figure out a better way to go about my engine with some looser coupling.