Category: Programming


Caromble! Friday #398: Flowing from SVN to Git

Like every other software development team we use version control software to manage changes in our source code and other computer files. For years we have been using Subversion (SVN) as our version control system. In recent times we transitioned to working remotely; as was mentioned in our previous post. Because of this change in the way we work, we figured it’s better to switch to Git as our version control system.

Workflow

In real life we could sit next to each other for code reviews and working in parallel was easy because communication was easy. Using SVN worked fine. Today, we have to orchestrate this source control workflow a bit more and our experience with Git is that it’s better up for this task. The flow with “branching” (changes that happen in parallel along multiple branches) and “merging” (integrate these changes) feels more natural. See this example of a Git branching and merging workflow (a.k.a. Gitflow) where each node represents a set of changes:

A succesful Git branching model by Vincent Driessen

Source: A successful Git branching model by Vincent Driessen.

GitLab

We chose GitLab as our Git hosting service because it’s free and it offers a nice web interface, especially for remote code reviews (through the “merge request” feature) to easily manage our changes and keep up the quality of our work.

Migration

To migrate from SVN to Git we followed this nice tutorial from Atlassian: Migrate to Git from SVN. It took two days to migrate our Caromble! project, but we’re glad we did this! We’re back in a better flow.

Happy gaming!

We just got a nice question on twitter on how much time it takes for us to build an area. That made us realize that perhaps it would be nice to take this opportunity to explain a bit about how we make Caromble! and also why the game still isn’t finished.

Making a story level

Every story level has four parts set in the same setting. There are three normal areas (you could maybe call them a mini-level), and the action ends with a boss fight. Depending on the level, this can be in a different fourth area or you will encounter the boss within the last area before the fight. Each of these smaller areas will typically feature a specific part of the Caromble! gameplay. So you might have a bit of a puzzle area, then some destruction and maybe finish of with an area that will highlight the surroundings. These three areas usually have some physical connection, for instance they might be set inside each other (a bit like a Russian matryoshka doll).

But how long does it take to make such a level??

Well… It takes quite some time actually.

The process is pretty much as follows.

  1. First we prototype some gameplay and the gross layout of the areas inside the level, this takes 2-3 days of work.
  2. The next step is that we all play through these areas, and probably at least throw out one of ‘m. Playing through the level and making the changes according to the feedback takes roughly 2 days of work I guess.
  3. But now the level still doesn’t look that awesome. So we add some background objects, and arrange the setting of the areas to connect the areas in some manner (for instance make them look like part of a big machine). This can take anywhere between a few hours and a few days, depending on who made the first prototype.
  4. Changing the look of the level might have altered the gameplay too, so we do another playtest and make some more changes. This will hopefully not take much more than a day.
  5. Finally we tweak the ball speed in each area and the occurrence of the different powerups types to fit in in the difficulty arc of the overall game.
If you know how it works, and don't forget to save often, it's quite a good tool! :)

The Caromble! level editor

Taking in mind that we have one day a week to work on the game, the answer is that it can take anywhere between four weeks to three months of actual time between the first idea and having something release worthy. If we had no other obligations we could do it in 4 – 12 days. By the way, this is the time it takes for one person, not for the whole team. So with sometimes 4 people working on levels our velocity gets a combo multiplier.

The good news is that almost all of our 24 levels are at least somewhere in step 2. And quite a few others just need a bit of graphical love.

So when we’ll release chapter two (in the very, very foreseeable future) 8 / 24 levels are done (pending community feedback). Four more are in stage 3-4 and the others are somewhere between 2 and 3.

Making a skill level
A skill level is a small challenge taking place in only one area and is the type we can make the fastest. These can be unlocked by winning medals in the story mode. We have 3 types of challenges:

  1. Score the most points in a given time
  2. Finish the challenge as fast as possible
  3. Survive as long as possible

We have a skill level framework that allows for quickly setting up a skill level. But, most of these skill levels do require some custom code to be written, although often not very complex. For example to spawn an extra ball when a box is destroyed in Ball Frenzy or shooting balls in Spin Master.

For the graphics, we have a set of art objects, floors and skybox specifically designed for these skill levels. The number of objects in this style is far smaller than those in the two story styles (industrial and neon-city) and this makes it easier to quickly setup the design of a skill level.

The main challenge for us as designers is to come up with a good idea for a skill level. But we do find that once you pop, you can’t stop. We are working on a small tower defense skill level, a shuffleboard skill level and Peter has promised to make a race skill level for years now. Furthermore, once our special powerups are released, these ingredients make for even more interesting skill levels.

Survive as long as you can, but the walls will Caromble! ehh... crumble :)

Wall Safety skill level

So I think most time goes into designing the level in your head and once you start building it should be able to finish it in 16 hours after which the other team members will play and give feedback, resulting perhaps in another 4 hours of work.

So that would be 3 days of work (and thus about 3 weeks real time) in the most optimistic scenario.

I hope this has given you some insight in our development process. This blog only tackles the level creation parts, but we are also optimizing our engine, fixing bugs, adding new visual effect, maintaining our steam page, facebook and blog, send an occasional tweet and try and find some spare time to contact press. To do all of this we have only one day a week, so this might explain a bit why the development of Caromble! is taking so long (over 6 years already). But please, bear with us. We’re getting there and we think it’s gonna be more awesome every week. If you want to be part of this process, consider participating in our Early Access. We’d appreciate it!

Last Friday we have finished our implementation for controller/gamepad support. This means that in the next big content update of Caromble!, you can choose your favourite input device out of the big three:

You can now control the paddle with gamepad, mouse or keyboard! More input devices are on their way...

We will do a beta of our first big content update next week on Steam Early Access, and if that won’t bring up any major issues, we will release shortly after. Get ready for Chapter 2, full of explosions, introducing the 1st special powerup (!), two skill levels and support for your favourite gamepad.

Controlling the paddle is the main type of interaction in the game, so this should feel as smooth as that actor in a hot spice commercial. Therefore, during the implementation of gamepad-support, we also tweaked the mouse and keyboard controls to make those better. The implementations of these three input devices are fundamentally different and I would like to use this blog post to explain these different methods and tell you how we achieved the best result for optimal control of your paddle.

In the following snippets we have a few parameters:

  • deltatimethe time between the current and the previous frame; to make the controls framerate-independent.
  • paddleSpeed: this parameter is necessary because of the way we set the paddle position in code. Each level has a left- and right-end position of the paddle. The movement of the paddle can be between these two extremes. A value [0, 1] describes the position of the paddle with 0 as the left-end and 1 as the right-end. If our input devices would work on this value directly, then the paddle speed would be depending on the distance between the two end-point. Instead, we want the speed to be described in terms of paddle-size, which is what you would expect. The value of paddleSpeed is calculated based on the distance of the end-points and the paddle-size and is thus used to make sure that we can control the paddle in terms of ‘move 0.2 * paddle-sizes to the left’, instead of ‘move 0.2 of the distance between the end-point positions of the paddle’.
  • movement: the result of the functions on the input data and is applied directly onto the paddle to map its position to [0, 1].
  • curSpeed: this variable keeps track of the speed of the paddle when using the keyboard or d-pad. We update curSpeed every frame, so it needs to be stored.

I like mouse control the mostThe mouse has the most straightforward implementation. We want the displacement of the mouse to be mapped linearly to the displacement of the paddle, resulting in its new position.  All that is applied to this displacement is a scaling factor. This gives a feeling of direct control. You have the freedom to move the paddle over large distances quickly or apply small displacements in a very precise manner. Here is the code:

float moveX = mouse.getDeltaPositionNormalized().x;
movement = (float) (-16.0 * paddleSpeed * moveX * deltatime);

Because the input for the mouse is provided in pixels, we use getDeltaPositionNormalized() to normalize for the screen size. You want to have the same behaviour in a 1280 x 720 as on a 1920 x 1280 screen. This function also applies the mouseSensitivity setting that can be set by the player.The biggest advantage of the gamepad is that you can really 'hang' on the couch with it. I love hanging...The main difference of the analog stick on a gamepad with the mouse is that it has a limited range of positions. It can be tilted to the left and to the right in a continuous matter, which will produce an input value of [-1, 1]. How can we use that to control the paddle? If we would map this value directly to the position of the paddle between its left- and right-end, the resulting speed and behaviour of the paddle would differ per level (some levels are very wide, like a platformer game; #waitforcaromblechapter3). This is not what we want, so instead of using the analog stick value to set the paddle´s position, we will use it to set the paddle´s speed. Let’s imagine moving the paddle to the right. Keeping the analog stick at 0 will result in a speed of 0. When we put it completely to the right, corresponding to a value of 1, we want a speed of, let´s say, x, which is normalized as described before (dependent on the paddle-size and not the distance between the ends).  Now we can achieve all values between [0, 1] to give the paddle the speed we want, which also gives us a lot of control. Our first idea was to map [0, 1] linearly to [0, x], but as it turned out, it feels nicer if we apply an exponential mapping. So a value of 0.5 does not map to 0.5*x, but more like something as 0.25*x. This allows to have precise control of the paddle when you move the analog stick only a little.

There are still a few more things we have to take into account. Unfortunately, if you release the analog stick, it does not return 0 as its value. Sometimes it ‘sticks’ a little, which can even result in values around 0.2 when the analog stick isn’t touched. To fix this, we introduce a deadzone. We choose a deadzone of [-0.2, 0.2], which means that all values within this range are mapped to 0. In this context we want a value of 0.2 to correspond with 0 as well, so we remap [0.2, 1] -> [0, 1] and [-1, -0.2] to [-1, 0].

Even after introducing the deadzone, we were still not satisfied with the achieved precision when we wanted to move the paddle only a little. In a brick breaker game like Caromble!, this precision is crucial, so we have added something that we call precision mode. When the right shoulder button is hold down or the right trigger is pressed over halfway, we enter precision mode. In precision mode we scale the applied speed with a value of 0.35. Here is the code:

// amplitude is in the range of [-1, 1] 
float amplitude = actionList.getAction("AnalogStickHorizontal").getValue();
// precision mode if one of the right triggers is pressed
float precisionScaler = 1f;
if (actionList.hasAction("PaddleMoveFocus") || actionList.getAction("PaddleMoveFocusAxis").getValue() > 0.5)
	precisionScaler = 0.35f;

curSpeed = Math.signum(amplitude) * Math.pow(amplitude, 2.5) * 3 * paddleSpeed * precisionScaler;
		
movement = (float) (curSpeed * deltatime);

The introduction of an extra key for precise control works, somewhat to our surprise, great! When you need to move the paddle over a long distance you put the analog stick in its extreme. When you are close to your desired position you hold the precision button and you can place the paddle exactly where you want. Awesome stuff.
There are so many buttons on the keyboard that are not used with Caromble!. Maybe that's reason enough to find a prpose for the 'any' key
And then we have the keyboard; a bit old fashioned, but still a favourite to some players. This is a fundamentally different input device than the mouse and the analog stick. Where with the other two you have a whole range of input values, the keyboard provides… just two. One key to move to the left and one that moves your paddle to the right. It makes sense to map these keys to a certain paddle speed, but we would like to see the paddle move smoothly. More precise, we would like the speed of the paddle to be differentiable, meaning that it doesn’t ‘skip’ values. This is a property that the mouse and analog stick implementation also possess. We can achieve that by letting the two keys correspond to an acceleration of the paddle, which is applied until a maximum speed is reached. This means that the paddle starts moving slow, but while you hold down a key, its speed increases until a set maximum. As with the analog stick, we won’t increase the speed linearly, but exponentially. This provides more control when we hold the left or right key for a short time, which I use in a way I’d like to call ‘tap-tap-super-tap‘. This puts the paddle in the exact position I desire. When I release the keyboard key, the paddle decelerates until its speed is 0.
I mentioned the differentiability of the paddle-speed, but I lied a little there. When we switch from the left key on the keyboard to the right key, we want to move the other way immediately. At this moment we do not decelerate nicely, but set the speed to 0 and accelerate in the other direction.
Also, because we liked the precision mode so much in the gamepad implementation, we use the Left Alt key on the keyboard to enter precision mode. Here is the code:

float maxSpeed = paddleSpeed;
float acc = 20 * maxSpeed;
boolean hasMoved = false;
float factor = (float) Math.pow(Math.max(0, 1 - Math.abs(curSpeed) / maxSpeed), 2);
 
if (actionList.isDown(paddleLeft) && !actionList.isDown(paddleRight))
{
      if (curSpeed < 0) 
            curSpeed = 0; 
      
      curSpeed += factor * acc * deltatime; 
      hasMoved = true; 
} 

if (actionList.isDown(paddleRight) && !actionList.isDown(paddleLeft)) 
{ 
     if (curSpeed > 0)
           curSpeed = 0;
      curSpeed -= factor * acc * deltatime;
      hasMoved = true;
}
 
float focusScaler = 1f;
if (actionList.hasAction("PaddleMoveFocus") || actionList.getAction("PaddleMoveFocusAxis").getValue() < -0.5))
{
      focusScaler = 0.5f;
}

curSpeed *= focusScaler;
if (!hasMoved)
{	
      // decelerate to 0
      curSpeed *= Math.max(0, 1 - 20 * deltatime);
}

movement += (float) (curSpeed * deltatime);

Of these three input devices I personally like the mouse the most. I feel that it gives me the best control of the paddle. This opinion is not purely subjective; science supports it! Humans tend to find it easier to interact with position-control than with velocity-control. Furthermore, humans like velocity-control more than acceleration-control.

I hope this has blog given you some insight in how we approach the issue of paddle control in Caromble!. We are curious what you think of our gamepad implementation and hope you find it as smooth as James Bond. We have tested our code on these three gamepads, so we hope you have one of these three 😉

The left one is so old! It was also very sticky, but we don't know why...

Besides these three described main means of control, we are also working on a fourth input method: Intel RealSense. We will address this in a future blog post, but we can’t tell you when or if we will actually support this in Caromble! . The Steam controller is on our wish list as well. Hopefully we can get our hands on one soon!

Fun by Metrics

Fun! That’s what most games are meant for. Some people argue it’s the meaning of life. Like in the book Homo Ludens (‘Playing Man’) by Johan Huizing. At least, that’s my over-generalized conclusion of a book that I have yet to read.. It discusses the “importance of the play element of culture and society”. Hence, the importance of playing Caromble!.

Our goal with Caromble! is to create a fun game. One of the aspects of creating a fun game is that it feels immersive. This requires a fine balance between boredom and frustration; or as we like to call it: the ‘Fun Flow’. The zone where you forget about time and yourself while having fun. One of the major slowdowns when creating Caromble! is to debug something and get side-tracked by playing the game. Yes, we as developers think to know the game is fun! Unfortunately, we aren’t important.

Metrico

Metrico – A game where players themselves can have fun with metrics!

We are humble game developers serving the people’s need to have fun. You, the people, are easily bored and/or frustrated. I don’t mean to offend, but that’s the conclusion of many game design books. So, we want to avoid boredom and frustration by doing our very best in balancing the game. One way to balance a game is to collect game metrics, identify unbalanced areas of a game, and… fix them!

How do we identify these unbalanced areas? By asking the right question. However, we are still arguing about what data to collect. But it will certainly contain data like:

  • How much time does it take to finish a level?
  • How many balls are lost?
  • How many times is screen X shown.

How do we collect these metrics? Unfortunately, it seems that the Steam SDK is not designed for this. So, we searched for another, easy way of tracking data and found Craig Timpany’s article from 2009 on how to collect game statics using Google Analytics. (As a sidenote he happens to have been involved with another brick-breaker – Shatter – as stated on his so-called ludography).

Game analytics dashboard

All Work All Play – Google Analytics dashboard with game metrics by Wolfgang Graebner

Another article by Wolfgang Graebner (2014) says this about using Google Analytics:

“It’s reliable, easy to set up, tracks common metrics such as views & hosts, supports custom metrics, and the data can be shared with others. That’s basically everything [you] need from an analytics service.”. It shows a nice example of collected data:

Bingo! That’s what we need. Let’s collect some data and add more fun!

Making Sparks with Caromble! Engine

A couple of weeks ago Thomas Schmall posted an article about the new particle systems he was working on. I finally got around implementing the last system, the spark particles.

I would like to show you two ways we can use this particle system, and give a brief insight in how the Caromble! Editor can be used to place and tweak it.

The first way of using the system is to emulate sparks generated by something like welding. They spray out in a coherent beam.

timer

Timer trigger that triggers every 2-5 seconds and send the trigger to a particle system

This effect works best if the sparks aren’t spawned all the time, so I’ve used a timer to spawn a spray of  particles every couple of seconds. In the screenshot to the right you see this timer. I’ve set it to send an event every 2-5 seconds.

Now we just need to place the actual spark particle system itself, and fiddle with the parameters a bit to get the effect we want.

I’ve included a screenshot of the relevant bit of the editor screen below. Five properties are important for this effect.

First of, it is important to set the release rate (very) high. The release rate is the amount of particles we’ll spawn per second, and since we’ll only spawn particles every once in a while, we need to spawn a lot of them in this small period of time.

A less obvious parameter is the “ContinuousParticles” property, which is ticked of to indicate that we’ll provide external triggers for the particle system.

The important settings for the spark particle system.

Next to that is the “PulseDuration”, which determines how long we’ll spawn particles after every trigger.

The collision object property determines which objects the particles will bounce of. For performance reasons we won’t bother the physics engine with all particles, so you’ll have to provide a list of objects with which the sparks can interact.

Finally the “MaxAngleRadian” property determines in what direction the particles will be spawned. Since this is meant to be a coherent spray, I’ve set the angle fairly low.

Alternatively the spark particle system can be used in a more continuous way, as shown below.

 

To use the sparks in this way, you don’t need an external trigger, the particles will continuously spawn, and Perlin noise is used to control the release rate of the particles.

Again I’ve highlighted some important properties for this system.

The upper triplet of properties control the release rate animation in a somewhat mysterious manner. The “FractionOff” number corresponds to the fraction of time that there should be very little particles (the lower bound of the release rate). The “ReleaseRateAnimationSpeed” determines how fast the animation over the release rate is running.

The other five highlighted properties determine the way the particles look. The “MaxAngle” is much higher than it was in the beam example, it now corresponds to a halve sphere. The “StartSpeed” and the “Gravity” property together control how the particles will act after they have been released. They have to be tweaked together to achieve the desired effect.

Finally the “MinLifeTime” and “MaxLifeTime” parameters dictate how long the individual sparks will exist on this planet.

With that I’ll conclude this post. I was hoping to provide a small peek into the daily live of us Caromble! developers, and about the tools we have made to work with. We might release the editor with the game (or at a later stage) so you might get a chance to tinker with it too.

Also, if you have any questions or suggestions, please don’t hesitate to ask!

Interesting Animations

Almost every game will have lots of moving objects. From an animated deck of cards or a gun that’s reloading, to huge armies that are running around the screen.

In Caromble! we have plenty of moving objects. But most animations are pretty basic. Therefore, way back at the beginning of the development of Caromble!, the question arose “how could we make these simple animations look more interesting?”

When animating an object from one place to another, the first implementation is usually to move the object with constant speed to its target position. This will look very static and unreal because in the real world, objects will need to accelerate to get to a certain speed and decelerate before stopping completely.

Objects that move with constant speed from A to B will have a linear transition from A to B. We can define a transition as the relation between the difference in time to a difference in position (or to be more abstract, a difference in animation). This is often called tweening.

Transitions are not only used in games, but webpages make plenty of use of them as well. You can play around with transitions/tweens yourself.

Below you can see how it looks if we apply some transitions to the movement of objects in our engine:

HOWTO: Chromatic Aberrations

On this blog we talked about some of the graphics effects we put into Caromble!. We’ve talked about why we decided on using that specific effect, and talked about some considerations we’ve encountered when implementing and tweaking the effect. But we’ve never actually shown the code. Usually because it was complex, or because the relevant bits where a bit scattered throughout the source. But today there will be code. I’ll show you our chromatic aberration shader. Chromatic aberration is an effect in photography where not all wavelengths of light get treated equally by a lens. It is also the distortion effect shown below: Chromatic abarration So what you see is that all 3 color channels (Red, Green, Blue) get distorted in a different way. This happens in the following GLSL fragment shader (the corresponding vertex shader is trivial):

#version 150
uniform sampler2D RT;
uniform sampler2D NoiseTexture;

uniform vec3 distortionOffsets;
uniform float distortionTime;
uniform float distortionFrequency;

in vec2 vTexCoord;
out vec4 FragColor;

void main(void)
{  
    float distortion = texture(NoiseTexture, vec2( (texCoord.t + distortionTime) * distortionFrequency, 0.5)).r;
    vec3 offsets = distortion * distortionOffsets;
 
    vec3 color = vec3 ( 
      texture(RT, vec2(texCoord.s + offsets.r, texCoord.t)).r, 
      texture(RT, vec2(texCoord.s + offsets.g, texCoord.t)).g,
      texture(RT, vec2(texCoord.s + offsets.b, texCoord.t)).b);
    FragColor = vec4(color,1);
}

That is all there is to it, and this is even a bit more complicated than absolutely necessary, to allow some hooks for creating animations with the effect. Let’s go over the code bit by bit and see what happens where.

uniform sampler2D RT;
uniform sampler2D NoiseTexture;

Here we pass the render target that contains our scene, the other texture is a 1D noise texture I’ve filled with some Perlin noise.

uniform vec3 distortionOffsets;
uniform float distortionTime;
uniform float distortionFrequency;

These are the hooks for our animation system. The vector distortionsOffsets controls how much each channel is affected (and the direction of the distortion). So passing (1,0,0) would affect only the red channel. The float distortionTime is an offset into the noise texture, so we can vary the effect over time. Finally, distortionFrequency controls the scale with which we sample the noise texture. Keeping the distortionFrequency zero will apply the effect homogeneously throughout the image.

float distortion = texture(NoiseTexture, vec2( (texCoord.t + distortionTime) * distortionFrequency, 0.5)).r;
vec3 offsets = distortion * distortionOffsets;

These two lines calculated the effect. We sample an amplitude from our noise texture, based on the y-coordinate of the input texture. This gives some sort of line-based feel (as if it were a video artifact). We  add the time offset, to animate over time. And finally we scale this by the frequency. Now all we have to do is apply this amplitude to the offsets we’ve passed into the shader. Finally all that is left is apply these offsets to the input image, and return the result:

    vec3 color = vec3 ( 
      texture(RT, vec2(texCoord.s + offsets.r, texCoord.t)).r, 
      texture(RT, vec2(texCoord.s + offsets.g, texCoord.t)).g,
      texture(RT, vec2(texCoord.s + offsets.b, texCoord.t)).b);
    FragColor = vec4(color,1);

And that is all there is to it. We have now applied an offset to all color channels. If you want to get a better feel of how this works, why don’t you plug our shader into Shader Toy and see what you can make of it.

High Dynamic Range Rendering

Now that we are getting closer and closer to an actual release of Caromble!, we have to put a lock on new graphics effects and big engine changes. Since we’d got motion blur up and running, there was one major annoyance left in how we rendered the images to screen: It was very hard (near impossible) to configure how bright or dark the final image would become. We had a basic bloom render effect in place but we had very little control over how it behaved. It basically turned our ball into an huge supernova like inferno from time to time, which made the rest of the image look really dark in contrast.

One of our main issues with rendering was that the ball was often too bright

One of our main issues with rendering was that the ball was often too bright

Enter high dynamic range (HDR) rendering. Photo enthusiasts create HDR images by combining multiple pictures (in LDR, low dynamic range) of the same scene taken under different exposures. This creates surreal images were nothing is too bright while everything remains visible. In game programming it works just the other way around. You create HDR images which allows you to regenerate the LDR images under different exposures.
Previously, all our light values in an image where clamped between 0 and 1, causing us to lose all lighting details around places where the image became brighter. With HDR, we no longer clamp the image values, giving us the full (high dynamic) range.

An old screenshot showing problems with over-exposure

An old screenshot illustrating problems with over-exposure

Once we got a HDR rendered image, we still have a few little problems. Of course, we do not want our game to look as surreal as the previous photos. Neither do lcd displays used nowadays have the capacity to produce lumen as bright as we got in our freshly rendered HDR image.
The first problem is solved by mapping the HDR image to a LDR image (low dynamic range). Basically, we  recreate those LDR images a camera would make but under the exact exposure we chose. We do this by defining a mapping function that maps 0-Infinity back to the LDR 0-1 range of our choosing such that we can display it on a monitor.
Anything below our LDR range becomes pure black. Anything above the LDR range should become incredibly bright.
So how do we produce these bright colors if monitors wont help us. We simply simulate it by enabling bloom for those values, letting the bright areas spread in their neighborhood. This finally gives us fine control over the brightness of our rendered image!

hdr

An HDR image mapped to LDR images with different exposures.

Java, a .exe launcher and NVIDIA Optimus

All modern laptop CPUs have an embedded graphics chip. While not as powerful as a discrete GPU, they are far less power hungry.

To help Windows users choose between their discrete GPU and the integrated chip NIVDIA, has introduced Optimus. When the user starts an application, Optimus will determine if the integrated GPU will be enough, or if all power is needed. This is a great idea, but sadly Optimus doesn’t recognize Caromble! as an application that would benefit from a bit more firepower. And Caromble! does love the firepower.

This weekend I finally managed to get Optimus to start Caromble! on the high-performance GPU, and since it took me a while, I thought it might be nice to share how I did it. All of it is in this pdf, but applying it to Java requires a bit of tinkering around.

Telling Optimus to choose the high-performance GPU is very simple. You just set the global variable “NvOptimusEnablement ” to 1. Which is easy enough, apart from that you can’t do so from Java directly. You have to do it from C or C++, you have to do it before an OpenGL context is created, and it has to be on the same process as your java game.

So that gives you two options. Using the Java Native Interface (JNI) you can either call C++ from Java, or you can start Java from within C++. I chose the latter, since it seemed simple, and would give us a proper Windows .exe. This is nice, because we can pick our custom icon, and Caromble! will show up as Caromble!.exe in the taskmanager, and not as java.exe. And, to a geek like me, that is a bit important too.

Enough talking. The basics of starting the Java Virtual Machine from C++ are explained in the official Java documentation. Beware, it’s a tough read.

Below is my interpretation. I have omitted error checking / handling at some places, all includes, and some other stuff that should be easy to figure out. Visual Studio Express is a good choice for writing your .exe.  This post at java-gaming.org helped me quite a lot.

I hope it helps!

//Please oh mighty Optimus, give us the High Performance GPU by default
extern "C" { 
 _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}

typedef jint (APIENTRY * CreateJavaVMPROC) (JavaVM **pvm, void **penv, void *args);

int _tmain(int argc, _TCHAR* argv[])
{
	//Load the java dll. Alternative is to start the jvm directly, 
        //using the system JRE
	HMODULE jvmdll = LoadLibrary(TEXT("java\\bin\\server\\jvm.dll"));

        const int numOptions = 4;
	JavaVMOption* options = new JavaVMOption[numOptions];

	options[0].optionString = "-Djava.class.path=Caromble-GAME.jar";
	options[1].optionString = "-Djava.library.path=lib";
	options[2].optionString = "-Xms600m";
	options[3].optionString = "-XX:CompileThreshold=2000";

	JavaVMInitArgs vm_args; 
	vm_args.version = JNI_VERSION_1_2;
        vm_args.nOptions = numOptions;
	vm_args.options = options;
        vm_args.ignoreUnrecognized = false;

	JavaVM *jvm;      
        JNIEnv *env;    

	CreateJavaVMPROC CreateJavaVM = 
              (CreateJavaVMPROC) GetProcAddress(jvmdll, "JNI_CreateJavaVM");
        int res = CreateJavaVM(&jvm, (void**)&env, &vm_args);
	delete options;
	if( res != 0)
	{
		std::cout << "Error creating JVM" << std::endl; 		
                return 1;
 	} 	

        //Find our main class          
        jclass cls = env->FindClass("main/Caromble");
	if( env->ExceptionOccurred())
	{
		/* Mostly this means that you have configured you 
                   Visual Studio Project paths incorrectly */
		std::cout << "Could not find main class because: " << std::endl; 	 	        
                env->ExceptionDescribe();
	}

	//Find our main method
        jmethodID mid = 
                  env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");

	/* Prepare the arguments for the main function, 
           here we use it to bypass the menu and start a level directly */
	jobjectArray args = 
                env->NewObjectArray(2, env->FindClass("java/lang/String"), NULL);
	env->SetObjectArrayElement(args, 0, 
                env->NewStringUTF("-a"));
	env->SetObjectArrayElement(args, 1, 
                env->NewStringUTF("levels\\story\\C3L2.xml"));

        env->CallStaticVoidMethod(cls, mid, args);
	if( env->ExceptionOccurred())
	{
		std::cout << "Could not run main method because: " << std::endl; 		        
                env->ExceptionDescribe();
	}

	//Destroy the JVM, this function will now return
        jvm->DestroyJavaVM();

	return 0;
}

Smooth Animation

As you very well may know, in movies and games we fake continuous movement by exchanging individual pictures at a rapid pace. We call these pictures frames and the pace in which we replace them (frame-rate) is expressed in frames per second (fps).

Most movies in theaters have a frame-rate of 24 fps, but for games the frame-rate is a lot higher (ideally at least 60 fps). Why this difference? Let’s do a little experiment:
Make sure you have a dark background on your computer desktop. Now move you mouse cursor around the screen as fast as you can and first focus on the background, then try to focus on the cursor. What do you see?
In real life (with sunlight) you would see an object move in one natural motion. But if you look at your cursor, you’ll see it at multiple locations at once and you can hardly focus on it.
The thing is, your cursor is updated at 60 fps. This means that even 60 fps does not guarantee smooth animations!
Even on a screen that updates at 120 fps, you’ll not see the cursor move in one smooth motion. Instead, the distances between the separate cursors will be the half the size as you see them now.

But how come movies get away with only 24 frames per second? First of all, they try to prevent objects moving very rapidly on screen as your cursor just did. This is why you do not see a lot fast panning shots in movies.
Secondly, since cameras have shutter speeds, fast moving objects will blur. Through motion blur, a fast moving cursor like we just had won’t display as a few separate sharp cursors. Instead, you’ll see one smudge in the form of a line between the start position and the end position of the cursor.
Since the photo-receptors in our eye do not react to change of light instantly, we perceive fast moving objects blurred as well. That is why the blurred 24 fps movies still look smooth.

To test what I just wrote down, go to this website and set the fps of the two footballs to 24 fps; one with motion blur enabled, and one with motion blur disabled. You’ll probably notice it’s pretty annoying to try to focus on the ball without motion blur.

But now back to Caromble!. After what you’ve just read it shouldn’t come as a surprise that we are currently experimenting with motion blur to make sure movement in our game feels smooth. If you’re wondering how, read this presentation.

While it’s still work in progress, here is a sneak peak:

motionblur