Posts tagged games development
Very early this morning, and after 20 days of voting, Ludum Dare #26 came to an end, giving way to the much anticipated final results.
How did I do?
Without further ado, these are the scores for Lightbyrinth compared to those of my previous entry.
|Category||Position||Percentile (2346 entries)||Score||Compared to #LD24|
Despite the obvious room for improvement, I’m quite happy with these results.
Primarily, my performance compared to that of #LD24 has seen a significant increase in the most relevant categories, Whoooh! This game wasn’t supposed to be funny nor have highly polished graphics. My focus was on gameplay and, fortunately, people valued that positively. Actually where are my manners? Thanks everyone who’s taken the time to play and rate it, you’re awesome and made me happy.
Secondly and speaking in absolute terms, Lightbyrinth is above average in every single category and among the best 20% in many of them. This strikes me as a great surprise having seen the extremely high standards displayed in this Ludum Dare edition. This is, of course, considering the tight dev time. Moreover, the game has passed the 2.50 milestone in everything but “Humor”, which is fair enough.
Summary, I’m very pleased but determined to improve my jamming skills toward the next edition. More gameplay and drive to get a right feel.
Don’t miss these
I would be an egotistical prick if I didn’t point you to those who stand champions of the mighty Ludum Dare #26.
Hail to them.
Seriously, go check it out.
The community delivers once again
Among the things that make Ludum Dare incredibly awesome, the community stands out. There’s people out there that took the time to gather most of the games to make a gigantic trailer. Hats off.
More compilations here.
See you in the next Ludum Dare!
Last weekend was as sleep depriving as rewarding. While I could have easily been surrounded by the joys of procrastination and beer, I went for Ludum Dare #26, as announced in my previous post. Lightbyrinth is the result of that and, despite its flaws, I’m fairly happy with the outcome. Please don’t embarrass me by looking at the source, I was in a 48 hour rush.
Lightbyrinth is a light based maze which tries to stick to the “Minismalism” democratically voted theme. You control a small blue sphere that has to find the exit of the labyrinth it’s in. An infinite swarm of red spheres will try to stop you from doing so, reason why you should move fast. Beware though, as it’s quite dark and you will only see what’s in front of you.
Here’s my humble postmortem of the experience.
I may have a terribly bad memory but thanks to my notes, here’s an overview of my executed plan of action for those who might be interested.
Saturday April 27th
- [6.00am] Woke up, read the theme and introduced some caffeine in my body.
- [6.30am - 7.00am] Game design on paper.
- [7.00am - 10.00am] Basic project setup, level loading, character control, camera movement and maze exit.
- [10.00am - 11.00am] Loading physics data, collisions callbacks setup.
- [11.00am - 12.00pm] Box2DLights integration and GWT compatibility.
- [12.00pm - 1.30pm] Lunch break!
- [1.30pm - 2.30pm] Box2DLights configuration and tweaking for gameplay purposes.
- [2.30pm -3.00pm] Enemy spawn points.
- [3.00pm - 5.00pm] Pathfinder.
- [5.00pm - 7.00pm] Path follower and local steering for collision avoidance.
- [7.00pm - 9.00pm] Dinner break, and some TV shows!
- [9.00pm - 10.00pm] Basic enemy behavior setup and tweaking.
- [10.00pm - 10.30pm] Death condition.
- [10.30pm - 12.00am] Shooting mechanic.
Sunday April 28th
- [12.00am - 2.00am] Game director, procedural enemy spawning system.
- [7.00am - 8.00am] Level progression.
- [8.00am - 8.30am] Temporal level brightening up the level when the player is hurt .
- [8.30am - 10.00am] In game tip system.
- [10.00am - 12.00pm] In game HUD.
- [12.00am - 1.00pm] Lunch break.
- [1.00pm - 3.30pm] Main menu.
- [3.30pm - 5.00pm] Tileset.
- [5.00pm - 6.00pm] Sound effects.
- [6.00pm - 7.00pm] Background music.
- [7.00pm - 9.00pm] Dinner break.
- [9.00pm - 12.00am] Level design.
- [12.00am - 1.30am] Polish.
- [1.30am - 2.00am] Submission and collapse!
What went right
- Technology: using libgdx has proven to be the right decision once again. I had the very core of the game up and running in the first few hours thanks to its maps API sweetness and awesome Box2D integration. Its rapid iteration approach is a big win as well, as I could test it on my desktop without having to deploy it on a server every time.
- KISS: some people didn’t like “Minimalism” as a theme. However, I think it ended up being the perfect way to enforce the Keep It Simple Stupid philosophy. It helped me focus on gameplay and feel rather than presentation, which was a clear mistake in my previous Ludum Dare attempt. The game boils down to: spheres as characters, two types of tiles for the maps and the lights, which were part of both aesthetic and mechanics.
- Help system: people like to play and rate games after the compo but they certainly dislike reading through walls of texts to learn all the gameplay mechanics. Therefore, adding an in game data driven tip system was a plus. Little pieces of text would momentarily show at the top as new mechanics were introduced. For variety sake’s, tips were mixed with atmosphere creation messages. I’m no writer and that clearly shows, but hey, it wasn’t a bad idea at all.
- Desktop and WebGL: libgdx multiplatform capabilities were extremely helpful in this case. You get Windows, Mac and Linux out of the box but that’s not all. Even though I had to invest some time in order to get Box2DLights working on GWT, it paid off big time. Having a WebGL version of your compo game available makes it much easier for people to give it a try. I know not downloading other’s people games when they’re desktop exclusive, kind of makes me a bad person. Ain’t nobody got time for that!
What went wrong
- Camera: all the negative feedback I got agrees on the camera. It doesn’t follow the player fast enough, which makes seeing where you’re headed a not very pleasant experience. Bad time management, clearly should have dropped something to work on this.
- Design polish: let’s get this out of the way, I’m no designer. Nevertheless, this would be a lame excuse for level design, I’m trying to get better, promise. The intent was to progressively introduce mechanics using little tips, which I did and that’s great. However, I feel like the maze and enemy spawning components could have been used much more intelligently. Reminder for self: practice your level design skills.
- Bugs: a couple of vicious bugs slipped from grasp but didn’t go unnoticed by some people. It seems that you can still control the character in between levels, while there’s no physics, this could make you end up inside a wall, which is no good. Again, I should have allocated more polish time.
I care not about the Ludum Dare hangover, it was an amazing experience once more. I keep learning so many things about games development and extreme time management. Not to mention the wonderful community behind all this. We all know the Internet is a hazardous place full of mean people who like to destroy other folks’ work. Ludum Dare is nothing like that, of course not all the feedback was positive, but the not so good comments were all constructive and will help me get better.
On a side note, Mario from libgdx, put together a simple tool to search Ludum Dare games as an experiment to see how many people used the library. It’s ridiculously popular, shocker!
That’s brilliant. Now onto some games rating.
This time I’m going to try vote as many games as possible (30 entries so far). Towards that end, I think this Ludum Dare based drinking game could help a lot!
OMG. How does this work?
Black, arcane magic. I would presume it sacrifices a dozen virgins during the third full moon of the year to make it happen. Just don’t ask.
Considerable win? Yes. Silver bullet? No.
This is utterly awesome for obvious reasons. Only, an insignificant amount of extra code is needed for your games to be fully playable from any WebGL browser without requiring any extra plugins. Take that Flash, Unity and the like!
However, as they say, not everything that glitters is gold. GWT doesn’t support every Java feature and this could potentially be a deal breaker depending on your existing codebase. Moreover, you could get unlucky and find out that the library that was about to make your life so much easier is not GWT friendly. Damn!
Last weekend, I was doing some work with libgdx that absolutely required browser compatibility. I happened to need a way of automatically placing tree nodes on a 2D surface. A smile was drawn on my face when I found the sexy treelayout library. Of course, it couldn’t be that easy, there’s no joy in victory when it hasn’t been preceded by some pain. I had to adapt it to the GWT build process and fix a few compatibility issues.
If anything, this made me realise that including new Java libraries in your WebGL libgdx game is not so straightforward. Hence, this small survival guide.
If you’re lucky, Setup UI
Chances are, you’ve setted up your project using the magnificent Setup UI tool. Aurelien Ribon’s free tool automatically creates cross platform libgdx Eclipse projects, including the libraries you want. Even though it has a system to add optional third party libraries, only a couple of them are available at the minute.
Long story short. As long as that external library you want is either Universal Tween Engine or Physics Body Editor loader, you’re good. Otherwise, read on, as you might have some work down the road. Hopefully, this situation will change in the future.
GWT build process 101
Bare in mind this is a guide so you can fix your library problem and move on, those who seek a proper explanation, I’d recommend the official documentation.
Let’s get going! You will find a very special file named GwtDefinition.gwt.xml under the main package folder in the HTML5 project. It’ll look something like this.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <module> <entry-point class="com.siondream.mygame.client.GwtLauncher"/> <set-configuration-property name="gdx.assetpath" value="../tranches-android/assets"/> <inherits name="MyGame"/> <inherits name="aurelienribon.tweenengine"/> <inherits name="com.badlogic.gdx.backends.gdx_backends_gwt"/> </module>
Its main purpose is to tell the GTW compiler what modules the application depends on, and therefore, inherits from. As you can see, it’s also used to specify the entry point class and add configuration params such as the assets folder location. I’ve obviously made MyGame module up, this would correspond to your core project. Look under the src folder of your core project and you should find a MyGame.gwt.xml file.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd"> <module> <source path="com/siondream/mygame" /> </module>
As you can see, the MyGame module contains a single source path which is located under the com.siondream.mygame package. If you wanted, you could add more source path entries in this file as long as they point to packages under the same project.
Now you’re a GWT expert, right?
Integrating a third party library
It’s not hard to guess what you need to add an external library to your GWT build process. You’ve guessed right, it’s necessary to add a new module inheritance entry in your GwtDefinitions.xml file that points to a module file, which in turn, points to where the source code is.
Does that mean that I can’t get away with just adding a third party jar to the build path?
Exactly. This is a bit of a downside because it requires you to import the whole library source into your workspace, and that means you need to be able to access the source in the first place.
Well, it’s actually not too bad. In my particular case, I went to the treelayout Google Code repository, checked out the source using Tortoise SVN and imported the project, easy peasy. The next step would be to add a module definition file under the src folder in the treelayout project, let’s name it TreeLayout.gwt.xml.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd"> <module> <source path="org/abego/treelayout" /> </module>
Hang on, we’re almost there! Finally, add the inheritance entry to the GwtDefinitions.xml file.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <module> <entry-point class="com.siondream.tranches.client.GwtLauncher"/> <set-configuration-property name="gdx.assetpath" value="../tranches-android/assets"/> <inherits name="MyGame"/> <inherits name="TreeLayout"/> <inherits name="aurelienribon.tweenengine"/> <inherits name="com.badlogic.gdx.backends.gdx_backends_gwt"/> </module>
Done! If you take 10 minutes to offer some prayers to $deity and press GWT everything should just work.
Note: after someone saying, “it just should just work”, I’ve come to realise that such situation is hardly ever the case.
Errors, expect them
Before carrying on with this section, I would always recommend to add these options to the GWT compiler.
-optimize 9 -strict
Optimize speaks for itself but strict means that the build process will bail out as soon as it encounters an error, rather than trying to keep going.
As long as you’ve followed the process, your library should be detected by the GWT compiler. However, like I’ve said before, GWT doesn’t support every Java feature. Every time you use an unsupported class or method you’ll get an error that looks like the following one.
[ERROR] Line 84: No source code is available for type java.util.Formatter; did you forget to inherit a required module?
This is going to hurt, isn’t it?
Again, GWT is not a silver bullet but it generally does a pretty good job. To tackle these issues you could try replacing every problematic class usage or method call by an equivalent, or an alternative of your own. Fear not, most Java stuff is there, the common troublesome areas I’ve come across are reflection, AWT and String.format().
Off you go
These steps helped me with treelayout integration and I hope they can aid you too. In my case I had to go through them all as the library used unsupported features. We’re done here, feel free to comment with your own experiences. Also, if you find any errors in the text, please point it out so it can be promptly fixed.
A few weeks ago I was contacted by an former professor at Kingston University asking whether I was interested in delivering a talk next on next Monday, April the 8th. An offer I gladly accepted.
Who would have thought, huh?
How come? You might ask. Well, just over a year and a half ago I arrived into Kingston, a little posh south west London borough, as an Erasmus student with the prospect of continuing my MSc in Computing Science. Leaving the crazy international student experience aside, which I got plenty of, the fact that Kingston offered a games course seemed highly appealing. Not to mention that the UK has the third biggest games industry in the world.
Coming from southern Spain, where the games industry is effectively non existent, this had life changing potential.
Oh boy, it really did!
Barely three months later, I got a job as a junior programmer at the Nottingham based Crytek studio. I didn’t start until February though, when the semester was over and the coursework was delivered. As some of you may already know, I’m currently part of the Homefront 2 AI team, which is utterly brilliant.
I cannot express how much I’ve learned during the little time I’ve been in the games industry working at a triple A studio. However, I’ll do my best next Monday. I’ll be talking about how is to be a programmer at Crytek like and how the hell I ended up where I am today. Something like a v2.0 of what I delivered in my home university last November. As you can imagine, going back to where these exciting times started is great and I’m looking forward to it.
Obviously, work on my side projects has been affected by the preparation for this talk. Activity on them shall promptly resume!
It pleases me to say that this past week I’ve been able to keep it real and stick to my humble set of tasks:
Victory and defeat mechanic: the spaceship has a limited amount of energy which diminishes after each collision with the world geometry. Once it’s empty, the game enters the defeat state and restarts. If the player manages to abduct all the astronauts in the level, the game goes into the victory state. The whole entity creation – deletion cycle has allowed me to spot some bugs and flaws in the entity system design, which is good.
Placeholder HUD: I’ve used the simple and yet powerful libgdx scene 2D elements to compose a minimalistic HUD which shows remaining astronauts, spaceship energy and elapsed time. Relax, it won’t look this bad forever as the assets will be replaced by the final art in due time. I just wanted to get something functional.
Improved control and abduction system: this is where I’ve put most of the effort. Speed limits, collision restitution, impulses and so on have all been tweaked to make the spaceship control feel good. Luckily enough, I’ve made it a lot smoother and pleasant, which was paramount to make the game fun. However, beware! For abducting all the astronauts shall not be an easy task.
This week I’ll be working on:
- Refucktoring: some modules need a small cleanup.
- Animated toasts: adding some effects for victory, defeat, abduction and collision situations.
- Level system with locked/unlocked levels.