So… I said I’d do it but never did, so it’s time for a rundown on Adventures development.
It’s a kind of TL;DR post so I won’t hate you if you don’t read it.
At first, the game was meant to be made only with android UI. My partner had the idea, and started to write the story and code the basics of the game. At first he wanted to have 3 characters (classic warrior, rogue, mage) and a pretty long story.
Then he persuaded me to get into it, which I agreed, but only if we were doing some 3D. At first it was just making a 3D view with the dices rolling. But quickly we got a bit over our head and decided to make a full fighting sequence in 3D, with animated characters and all…
We were pretty motivated so at first it got pretty fast.
Dices on a sheet
The dice rolling view, came first. We setup a transparent opengl view over the android UI. You can do that by choosing Alpha supporting pixel format in the android Harness (config.BEST_TRANSPARENT).
So we decided that all the game logic would be on the android side and that the JME view would be just that…a view.
I made a quick and dirty dice with blender (a cube with a texture).
The idea was to use jbullet of course but I know it was pretty slow on android so I went straight ahead and used bullet native. The question was, since the physics are deterministic, do we randomize the roll result by code and then make so the correct result is displayed on the dice, or do we randomize the impulse applied to the dices and “read” the result? We went with the later as I had absolutely no ideas on how to do the former. Also “reading” the dice values wasn’t too complicated since we only had 6 sided dices.
So the algorithm is pretty simple :
for each dice{
pick a random Impulse;
pick a random direction;
applyImpulse to the dice and let it roll;
}
I had setup some ghost walls (RigidBodies in physics space with mass 0) around the area so the dices doesn’t go out of the Field of view.
To each dice we apply a control. This control is responsible to “listen” to the RigidBody angularVelocity (is the dice rolling in physics space?). When it’s not moving anymore, we compute the dice orientation.
here is some code (idk if it’s the best way to do it…but that’s working pretty well):
rot is a Quaternion and yNomal, xNormal, and zNormal are vectors. Each vector is meant to be the direction of the rotation compared to each axis. diceControl is the RigidBodyControl.
rot.set(diceControl.getPhysicsRotation());
rot.mult(Vector3f.UNIT_Y, yNormal);
rot.mult(Vector3f.UNIT_X, xNormal);
rot.mult(Vector3f.UNIT_Z, zNormal);
int value = getValue(xNormal, yNormal, zNormal);
the getValue code
private int getValue(Vector3f xNormal, Vector3f yNormal, Vector3f zNormal) {
float epsilonUp = 1.001f;
float epsilonDown = 0.999f;
if (epsDiff(yNormal.y, epsilonUp, epsilonDown)) {
return 1;
}
if (epsDiff(yNormal.y, -epsilonDown, -epsilonUp)) {
return 6;
}
if (epsDiff(zNormal.y, epsilonUp, epsilonDown)) {
return 3;
}
if (epsDiff(zNormal.y, -epsilonDown, -epsilonUp)) {
return 4;
}
if (epsDiff(xNormal.y, epsilonUp, epsilonDown)) {
return 2;
}
if (epsDiff(xNormal.y, -epsilonDown, -epsilonUp)) {
return 5;
}
return 0;
}
the epsDiff method is here to deal with float magi and approximations errors.
So basically we compute the alignment of the dice’s axis and check if the Y component is 1. That’s enough to know what face is on the top. That can only work for 6 sided dices though.
there can be some cases when a dice lend on an edge, and the algorithm returns 0. In that case, I apply a very slight impulse to the dice again until it’s in a correct position. In some cases that can do funny things like this
http://i.imgur.com/C7hQ40z.jpg, but it works fine.
So … once we had the result we had to send it back to the android side.
The thing is, JME android’s structures implies that, you can access JME things from the android side, but not the other way around.
So we had to set up a message management between android and JME. For this we used a pretty classic event bus pattern. A client registers to a broker, for a particular type of message. once a message is sent the broker broadcast it to all subscriber clients. Easy and efficient, we didn’t need much more.
Animations sequences for characters
For the fighting system we wanted something kind of like old style rpg games. Each opponent is on one side of the screen, they never get that much in contact…but somehow manage to damage each other…on a turn basis :p.
So we wanted to have animated characters that somehow interact. One is issuing an attack animations, if the attack lends, the opponent is playing a “got hit” animation.
The outcome of the exchange is precomputed on the game logic side (android) except for the result of the dice roll that will be determined on the JME side (yeah I know that’s game logic in the view, but the other way around was too complicated).
The android side sends and a serie of events to the JME side, with the following information : how many dice should be rolled, what’s the success threshold of the dice roll, what kind of attack is being triggered, how much damage will it lend.
So now , on JME side, that’s just a matter of rolling the dices, get the result, compare it to the success threshold, and play the animations.
The problem is that if you just naively chain all animations it looks dumb. The attacker will make his move, and then the opponent will play his ‘got hit’ animation…
We need the opponent to start the ‘got hit’ animation at the moment the blows lends in the animation.
For this we used something we called the attack Momentum.
That’s a float that represent the moment, the next animation should start since. We have one for each animation and it’s stored it in the UserData of each model. So basically, that’s something that’s edited by the artist directly in the SDK.
Special Effects
Most of the special effects has been made with particle emitters and some classic primitives (quads, cylinders, etc…). You can go pretty far with JME stock particle implementation but I reckon it’s not very flexible…But I guess this will change at some point.
The neat part is that you can attach a particle effect to an animation track. You can check that option in the SDK. Open a model with an AnimControl, create an emitter in the model, expand the animcontrol, right click on an animation and you’ll see you can add An EffectTrack. I made a video of it once here Effect and AudioTrack editing i
Most “slash” effects are particle emitters with one textured particle.
Art…and it got long and difficult
Coding is fun and games, it’s our work, and it’s somehow straight forward and fast. Now, if you want something that is appealing to the gamer you need some eye candy and interesting intrigue. Nobody would play to a game made of cubes with no story (uh wait…).
I had some blender/photoshop skills, and my partner had some writing and photoshop skills too. So we started to make art assets. My partner wrote the entire story, all the icons and UI and I made all the models and illustrations.
I started with a Wolf model. Low poly, no fancy equipment etc pretty easy. Quadruped though so need for a quadruped rig which I never did. I was kind of happy with the result.
Then I went head first into the first hero, the fighter. Made a model I was happy with, and so on, and so on.
In one year I made like 25 to 30 models, some more difficult than others, from fully animated characters to static scenery for illustrations or effects directly in the SDK.
Here is an imgur album with shots of some of the models that are part of the game.
http://imgur.com/ucoKyja,ClUvn7w,DmA9isO,OW5BRBC,K4iIDIQ,S37EzNC,zAMlins,Z1vUbev,oQ9lH9i,BS75TYm,3tyFKub,Yrst2Ud,wcfU7Yg,Vv1y3Yk,HMXhOvX,lie8ZEl,ccImGlO#0
Meanwhile my partner was writing a book… around 400 paragraphs, with complex chaining (some paragraphs are close one to another with slight variation depending on what you did before and what you chose).
Along the way we kind of realized we had been too optimistic, and we were well over our heads. So we decided to scope down the game a lot. Only one character : the fighter (since the story was almost completed for him and also the model). Only write one chapter of the story, and continue on later if success was met.
Near the end, I was getting better…and some models I made looked really better than the Hero model… So we decided to make a new one, and in a last resort, we changed a bit the game play so that it’s more enjoyable. We added the gestures, special techniques and decided to go with all clichés for the new Hero : young with white hairs, muscles like no human being, plenty weapons with one being so huge you couldn’t carry it, aesthetic clothes but offering very inefficient protection for a fighter, but who cares uh?.
The only cliché we didn’t go to was tatoos… somehow we didn’t…
This model is in my opinion the best I did so far. I usually stop to work on a model when I’m happy or even proud of the result, and it happened for most models I made. But with time, the pride wears off…and when you look back at a model you feel like you could have done better, “his eyes are too close from each other”, “his arms are too short”, “he doesn’t actually look human…”.
This model is the only one that I’m still proud of when I look at the pictures today.
Making money
That’s where it gets a bit out of our reach. In comparison, making a game is like thousand times easier than selling a game.
Of course, marketing is not what we were trained for, and if you’re blessed with someone with that skill in your team, just don’t let him go, because you’re gonna need him even more than the artist or the developer. There is no such thing as “My game is so good it gonna sell anyway”.
Android offers a real opportunity, and a nice marketplace for indie developers. But the offer is so dense and varied that it’s hard to find your place.
Here are my 2 cents advices. It’s more a “don’t do the same mistake as we did” kind of advices list, not really a “key to success” list.
1- Talk about your game, anywhere you can. Get on those fancy social networks even if you don’t like them and talk about your game. Give eye candy shots of it. Don’t be afraid that someone takes your idea, just talk about it and be quick to make it real.
2- Don’t wait for the end of the dev to talk about your game. You’ll be tired of it at the end and you won’t be enthusiastic enough about it. Tweet, blog post, facebook, google+ about a new feature/idea/shot/video AS SOON AS it happens.
3- Have a web site and update it frequently. It’ll cost time and money, but it can help with 1 and 2.
4- Don’t give it for free in the end because you despair to sell it. For what it worth, a dime is a dime and even low revenues are better than naught. (At least we didn’t make this mistake :p)
Enjoy it all the way, or take a break
Indie often mean hobbyist or hobbyist+. Professional indies are pretty rare. This means you do this in your free time. So make sure you enjoy it or you’re gonna depress and do crap. If you don’t enjoy it anymore, do something else : another project, go on holidays, play the next AAA game. Get back to it when you feel like you’re gonna have fun.
If you feel that a break will mean the end of the project, then drastically scope it down, and FINISH it. Half made projects are as good as “this game i’ll make some day” : nothing real.
Not doing it alone does help in that matter, the more you are the more unlikely everybody will be discouraged at the same time…or it’s really time to give up 
I could talk for hours, about it, so I’m just gonna stop there.
If you want some more informations or have questions just poke me.