Wednesday, May 29, 2013

Green Algae: Bridges

Alright, so a little movement on the 'Green Algae' project. I was able to add the ability to create
bridges that you can walk across. This allows you to connect islands together.

I gave it a go and it took me a long time (hour and a half) to create a bridge connecting the island I was spawned on to the island to the north. Perhaps the world is a tad large or the island just aren't big enough. Another thing is just a small chunk of the trees at the top of that island were cut out in order to make the bridge. Which currently you do by dragging trees one bridge section at a time. So there was a lot of lugging and chopping going on to get that bridge built.

It was a little annoying having to drag around the trees, and chopping down that many with no hope of doing it a little faster each time was not very fun. So that definitely needs to be tweaked and improve chopping speed over time so you feel like you're progressing and getting rewarded. Some visual effects of the tree falling, or effects when you grow stronger might also help.

No saving maps yet which will be necessary soon. for play testing long term progression and replayability things that don't matter right now because there aren't any full game mechanics yet. The map generation seems to make islands that are all slanting from left to right which is odd but it must be something with the random generation I need to work out.

I also have a perlin noise generator that I can integrate and use as a way of generating a map it might we a lot faster as well. I need to tweak the rotation of the bridge sections so that they flow in the right direction pretty easy to do as you can imagine.

For chopping down trees I use a state machine. Here is the line in my update function.

chopState = chopState.handleEvent(input, world, dt, collisionResults);

Where input is an input manager that has the state of the keyboard and mouse etc... dt is a fixed time step value per frame. World contains a reference to the map and a list of drawable objects and various other things. The collisionResults holds the objects that the player is colliding with this frame separated by object class type, I use a partioning scheme right now the strategy is to have bins based on the grid of tiles in the map, lookup time is really quick probably uses more memory than it needs, though.

For the chop states I have a start, end, and a no chop (or idle state). I also use that mechanism for dragging. This keeps the number of if checks or switch statements (which I don't have any of) down to only what is needed. For instance, instead of a bunch of else if statements to check various states each state object has hopefully one if check in it which should very quick. It's about the same performance wise I would think but it helps make the code flexible for new states. The handleEvent method is called every update frame so if no conditions have changed for that state it just returns the same state.perhaps not the best to keep setting the variable if it hasn't changed but that's a minimal amount of time compared to other operations that are done.

So that's all for now, until next time I get a chance to move the code forward.

Friday, March 29, 2013

Java Image Acceleration

This is something that took me a long time to figure out. But that might help you if your seeing java performance issues when rendering sprites or other images.

Speeding up image rendering

While working on a game that was using sprite sheets with a background color instead of transparent PNGs. I found that my rendering code was slowing down significantly especially in fullscreen mode. I did some research and found out that Java images have to be hardware accelerated and won't be if the raster is modified directly. Something I had assumed would happen automagically. The problem arises from modifying an Images raster on the CPU and not automatically reallocating it on the GPU.

Check Image Capabilities

There is a check to see if a given image is hardware accelerated. It's in ImageCapabilities which you can get for any java.awt.Image for a given GraphicsConfiguration which is different per GraphicsDevice. There is also setAccelerationPriority method but I don't believe you would want to rely on it for games as much. You should definitely give it a test especially if you don't want to convert all images over to using VolatileImage's which can loose their handle to video memory in certain circumstances akin to DirectX's hardware reset that usually happens in windows when Alt+Tabbing between a fullscreen exclusive application and another windowed application.

Creating Accelerated VoltaileImage's

I've relied on the GraphicsConfiguration function for creating these VolatileImage's. createCompatibleVolatileImage or on the java.awt.Toolkit function with the same name. There are a couple of overloaded methods that you can use to successfully create accelerated images. Combine this and the check in the ImageCapabilities to make sure you've created an image that is going to be accelerated.


This is yet another tricky spot, I always make sure to set the following -D or system property flags for explicitly turning on either opengl or directx rendering. The flags I use are

// either

System.setProperty("sun.java2d.opengl", "True");
// or
System.setProperty("sun.java2d.d3d", "True");
System.setProperty("sun.java2d.ddforcevram", "True");
// and

System.setProperty("sun.java2d.transaccel", "True");

The capital T in True actually tells java2d to output to the console whether the accelerated rendering system was enabled this sometimes can be installation and system configuration dependant. I've had issues on some systems with both OpenGL and DirectX where they should be working but for some yet unknown reason they don't. I've also had issues with a WindowsXP hardware acceleration setting on the desktop causing sometimes reverse effects to java applications, when I figure this out I'll let you know. You'll get a message like this "OpenGL pipeline enabled for default config on screen 0" in your console or "Direct3D pipeline enabled on screen 0"

You can also optionally add logging to java2d to debug long rendering operations using:

System.setProperty("sun.java2d.trace", "timestamp,log,count");

*Warning* opengl driver support is kind of iffy on some NVIDIA cards on Windows, not sure what exactly the issue is but I have had reports of slow rendering with SLI cards. You'll have to experiment and offer a way of switching the flags that are turned on in order to get better performance. Additionally on a laptop I've had issues initializing DirectX I need to investigate more on that.

Test Code

Monday, March 25, 2013

Green Algae: Updates

Thought I'd do an update on the latest changes I've been making to my Green Algae project. It's one of those side projects that sometimes can be more enticing than the more serious projects. I feel it's good to have something on the side that is not under the gun or a time crunch it gives you freedom to work on it when your moved. Of course it's always easier to work on a project that is making progress. Spend too much time trying to move the code to the next step and you'll end up stagnating it. It's a funk you don't want to find yourself in, so either move on to something a little bit less challenging or that you've done before or risk spending way to much time on a road block.

Anyways just a little rambling thoughts to get your brain going. So without further adieu I'll lay out my current changes.

  • Changed tree image perspective to side view.
  • Modified map generation ever so slightly
    • Created worker threads during map generation
    • Was working on using a perlin noise generated map texture but stalled that for a little while to focus on gameplay
    • Reduced generation time from a couple minutes to around 10-15 seconds using the LMAX Disruptor Library, I was going to go with a ConcurrentLinkedQueue but I found the Disruptor a while back and had been meaning to attempt to pulverise things with it.
      • The slow down was due to drawing to a bufferedimage to create the minimap during map generation causing  major blocking to occur during generation
      • I had to tune the disruptor to a 4 core machine with an integrated graphics chip and no DirectX pipeline in the swing rendering.
      • I'm using only two EventHandler instances with a ring buffer of size 1024 
      • Haven't counted the number of draw calls which I further reduced by not drawing things that had already been drawn which actually increased the correctness of the minimap with respect to foliage now noticably showing.
  • Attempting to add bridge building, almost there just need to properly place bridge sections
  • Fixed issues with dragging logs from chopped down trees.
    • Turns out my grid partitioning scheme was to blame because the logs were not moving partitions when being dragged so drag one outside of it's partition and you wouldn't be able to drag it again, this works almost perfectly now, still some issues with duplicates being created when placing in piles.
  • Fixed collision volumes for trees and player to allow the correct overlapping. 
    • Changed from using radial colliders to box/rectangular colliders, the box/rectangular volume for the tree is now only at the base of the tree allowing the player to walk behind the tree
    • The players box/rectangular volume is now at the feet allowing for  the player to walk in front of  trees and other objects. Additional collision volumes will be necessary at some point to handle combat and other types of hit detections so a CompositeVolume using the composite design pattern will be necessary at some point.
  • Fixed render order with foliage (which are just trees right now).
    • They are now properly sorted, however the character does not display in front of them when it's supposed. I actually started using a TreeSet for the render sorting with a custom comparator, my Drawable interface which extends Comparator only sorts using layers and id values which id values are in order of instantiation which was not always coinciding with the correct order.

There are definitely more improvements to be made with regard to map generation and render order as in making sure moving objects are removed and added to the sorted Drawable collection, that should be pretty easy after changing the abstract Drawables compareTo method to use coordinates rather than simply layer and id.

I'll eventually get around to detailing a little bit more of the way the collision detection and space partitioning works, it's functional currently not feature complete but the abstraction is there for new strategies to be added.

I welcome questions for those interested in how any of the features work up to this point. Enjoy the screenies!

Friday, January 25, 2013

Challenge the Player

There are a couple of things you most certainly need when making a game and challenge is the first and foremost. If it isn't challenging it becomes just a set of interactive graphical 'stuff'. Like a lot of those watered down tycoon games available all over the mobile app markets. It takes me about five or six minutes of play time in those games to get utterly bored out of my mind. They look cool and fun but they play like money drops. Arcade games were designed to be money drops too although I would consider the arcade games to be works of art where as the new Story style games are works of monotony and dullness no clear goals to achieve no end game but the biggest thing about those is that they don't have challenge.

Arcade versus Story games

So what makes them different well Arcade games there were good ones and there were bad ones. You could spend more than a few dollars just playing the first level/stage of an arcade game. But they had goals that were hard to achieve. The Story games I've played always had a fast track to all the unique items, buildings, etc which is pay some money. Arcades didn't guarantee that the closest I've seen to that with Arcades is Insert Coin to Continue. That is a very different concept because your reward is different. Instead of being rewarded with a hammer head shark building to place in your city so you and your friends can see your wonderful new statue you paid money for and really does nothing. I think the difference there is the incentive. Arcade incentive - insert coin to not loose all the things you've worked up to to this point the further you are in the game the more likely you will be to put in another coin and the more coins you've put in so far the more you want to keep going and finish a play session. So the games had to be difficult but not too difficult. No story game I've played yet has presented me with any challenges. There are no downsides to actions there aren't any real upsides either. Placement of buildings well most of them allow you to move the buildings at anytime anywhere instantaneously so you can go wrong where ever you place them. Need I go on I feel like I could keep going about the bad design choices of these games and the lack of challenge, but that would just be cynical.

How to achieve a challenge?

One of the problems when designing games that I've had is that yes I didn't think about how to challenge the player and most of my prototypes or earlier development builds turn into the Story game where it's just a bunch of mechanics and so I look at it and say to myself, "I'm done it works move on". And I am bored of my own idea and move on. So I have decided to breath a breadth of life into my games. I hereby declare I will make my games impossible, I will find ways to only make a prototype you cannot win. Then once I know I could play for hours and still not win, and I'm not talking about not having an end game like many of these games today. There must be an end game or else what the hell is the player playing for. So Impossible game, with an End Game that you might be able to achieve but it's just humanly impossible. Then come up with mechanics or tools if you will for the player to have a better chance at solving the impossible. Beating the impossible boss. I think that type of thinking exercise should help create games that will have interesting choices present a goal a true game goal, "do the impossible".

Tip: Do the impossible! If the player doesn't feel like it's an impossible task i.e. trying and failing then in the players mind it isn't impossible but one thing that is expected of a game at the end of the day is that it is beatable. This mindset can create new solutions you never thought of before, which is very exciting.

Tip: Make a game out of it, say to yourself when thinking about your next game, "What monster can I create that is the most bad arse biggest badiest creature to ever set foot on the interwebs, what bfg will he have that kills you even if your blocking" Then the followup "what weapon item or tactical manuever can I give the player so he can defeat said bad arse creature."