daanvanyperen

LD30

For all you java/libgdx/playn fans out there

For all you java/libgdx/playn fans out there

If you are java addicted like me, and are looking for a way to structure your games, go check out Artemis-odb!

Artemis is an excellent and free entity component system (ECS) originally created by Arni Arent, improved upon by Adrian Papari, with a focus on performance, convenience, full GWT support and a proper wiki.

Artemis has helped me quickly prototype jam games in java, while squeezing the most out of my weekends: Here are some of my most recent games based on Artemis-odb + LibGDX <3:

MiniLD 50: Naturally Selected 2D: source | ns2d | timelapse

Zvg5p3r.jpg

LD 29: The Underkeep: source | play online | timelapse

So go check out Artemis! It might tickle your fancy enough for the next ludum dare!

Comments

pakoito
21. Aug 2014 · 21:25 UTC
I already have Artemis included in my project and I have a doubt. Let’s say I have a system A that adds components X and Y to an entity, and system B that requires both aspects to see the entity. If I execute process in them sequentially, apparently B is not capturing the entity after it gets out of A.

LD33

LD36

Onwards Genuine earthmen! To Jam and beyond.

22396-shot0.png-eq-900-500[1]

.

Two man team from such smash one-day hits as Steve Can’t Zen, Dreamcake Rescue can’t wait to clone Pokemon Go and drive each other bonkers!genuine_earthmen_transpJam Toolkit

Artemis ECS framework (check it out!)

libgdx-artemis-quickstart

artemis-odb-contrib

LibGDX

Photoshop, IntellIJ IDEA, Java

.

Kick some ass everyone!

.

lundum-blogpost-kickassery

Comments

26. Aug 2016 · 23:41 UTC
Let’s do this! \o/ All right… I’m going to bed.

LD 38

Little Fortune Planet Breakdown - Part 1: Brainstorming

Before diving into the meat of it, here is our process for kickstarting a game.

image18.png

Spend as long as possible on the idea phase. Start by going as wide as possible, shotgun all your thoughts onto paper. Don’t zoom in. Let it ferment a bit. After a while some ideas will start to stick out and you can develop them further. Liberally use Wikipedia, image search, google to feed the process.

image4.png

After that, sketch it out into features. Now remove as many features until your idea breaks, and add the last one back; it might not seem like it but you have nowhere enough time for all the fluff.

image13.png

In our case, we settled on a terrarium / sandbox toy of sorts mixed with a card mechanic to drive events forward based on an old concept. Since we’re not too original we’ll name it Little Fortune Planet. A nice technical challenge mixed with the potential of some nice visuals. In this case I wanted to see how the java to js (web) transpiling would deal with a non trivial non optimized game design.

image14.gif

To keep things relatively stress free, start with the hardest tasks first. Typically for me this means graphics and music beforehand but in this case @Flaterectomy and @MeatMachine took care of that. Phew!

We targeted desktop and web with the java framework LibGDX and an Entity Component System framework called artemis-odb. I’m a big fan of artemis-odb as it allows quick prototyping and helps keep code clean and specialised, even when in a hurry. It has a time saving fluid-API that gets rid of some of the verbosity (disclaimer, I occasionally work on artemis-odb!)

So let’s jump right into our world simulation!

Read Part 2: Gravity of the simulation, man! or play it here!

Little Fortune Planet Breakdown - Part 2: Gravity of the simulation, man!

We're eager to get started after several hours of Part 1: Brainstorming so lets consider what it takes to simulate a world in an Entity-component system (ECS)?

Developers starting with ECS typically struggle what to implement as entities, and what to exclude.

We could simulate each particle with an entity and use a physics engine, but since we’d have to check neighboring cells constantly and we’d lose a lot of time understanding a third party physics engine, a simple two dimensional array feels a lot less risky. The grid size is static, which means no real lifecycle management is necessary.

Our world simulation system iterates over each cell, passing cell state to a behavior subsystem for magma, air, dirt, etc, and apply changes in a second pass. Subsystems add modularity in exchange for a small performance hit.

But since most simulation requires some gravity, we first need to figure out what direction is ‘down’ for each location. Calculating gravity live for 250000+ cells could become a bit of a performance problem, so instead we could precalculate a 2d array mask with the direction of the core of the planet. A bit premature perhaps, but with limited time got to go with the guts!

image15.png

Initial naive solution we could calculate the direct angle by subtracting each cell x,y coordinates from the planet center, and determining the angle of the resulting vector. In effect, we end up with a grid of ‘downward’ directions. So let's run it:

image5.gif

Uh-oh. The planet ended up as a octagon.

We end up with 8 Intercardinal sectors making gravity direction (for example) always left in the right section, while if you’d draw a pixel line from a cell to the core it might go left left, up, left left, up. Sort of like what you would get with Bresenham's line algorithm.

832px-Bresenham.svg.png

Since we basically want things to fall from circumference of the planet to the center, why don’t we draw loads of lines using the Bresenham's line algorithm from core to circumference and use each previous pixel as the direction of gravity?

image16.png

We end up with this:

image20.gif

A lot better! It’s worth getting quick-and-dirty when not too mathematically inclined.

Now we have gravity, we can move on to simulating something interesting!

Read part 3: Simulation time or play it here!

Little Fortune Planet Breakdown - Part 3: Simulation time!

After finishing adding gravity in part 2: Gravity of the simulation, man! , it's time to start simulating a world.

Basic solution is cellular automata-ish. We make each particle aware of its immediate surroundings, and decide if it wants to swap with a neighbor, transform into a different type, or do nothing. Simple enough right?

Given the available time we get @Flaterectomy to draw us a planet, and convert each color of that planet to a different type of particle on our simulation grid.

image1.png

Let's start by turning all darker blue into water, light blue into air, red into magma/lava, and everything else to ‘static until replaced’. We also add some basic behavior to air; swap with any skyward non-static neighbors.

image19.gif

Looks pretty good already! We can make things a bit more interesting by having water settle; if there is air horizontally, try to flow there.

image7.gif

That's strange! Since we apply each change immediately we seem to be getting some weird behavior. Particles move faster left to right. What about if we predetermine behavior for the whole grid in one phase, and wait to apply those changes in a second phase?

image10.gif

Good enough! Now we want magma to erupt. To do this, we add a global ‘pressure’ counter. The higher the pressure, the bigger the chance we’ll convert one of the nearby air blocks to magma/lava. Each new block of magma/lava lowers pressure. To spread the lava growth more universally we add a low random chance for spreading; this prevents the top rows in the simulation from spawning all the lava before we get to the bottom bit. We also want the flow to appear to come from the core of the planet, so we decrease the chance of spreading the further out it is.

image12.gif

And there you have it, basic particle simulation! You could refine it by adding more cell types, make types interact (steam, fire, clouds) coloring lava- and water borders to make the volumes visually interesting, adding more exceptions, etc.

Now we want to add some inhabitants to this world. But how?

Continued in part 4: How to dunk minions in lava or play it here!

Little Fortune Planet Breakdown - Part 4: How to dunk minions in lava

Continued from part 3.

Part 4: How to dunk minions in lava

Since we decided to run the simulation outside our Entity Component System (ECS) in part 3, if we simulate our inhabitants in the ECS they’d fall straight through our planet. So what now?

All we need is to give each entity a sensor that tells our inhabitant what is under its feet. By wrapping the logic of converting entity-space into simulation-space in a system we keep complexity local and it doesn’t leak into your other systems, We also get a sensor we can slap on buildings later. Great!

Next we start with the fun part ECS: adding components and system for each behaviour we want on our entities. Some examples: Don't worry too much about getting this right, just start adding!** - PlanetBound: Entity can ‘feel’ what is under its feet. - Gravity: Entity is pulled towards the center of the world, providing the sensor tells us the entity is currently in the air. - Mass: push the entity up when it is inside water. - Dolphinized: Entity shows dolphin behaviors. Does not like to be on land, that sort of thing. - OrientToGravity: Entity turns feet towards gravity. Nice for humans, dolphins don’t care for it. - Flammable: Kill the entity when it dives in to lava. (Ouch!) - Ghostable: Turn the entity to a ghost upon death. - Wander: Entity wanders left or right randomly.

image22.gif

ECS allows you to naturally grow your game. Reusable components mean saving time, which is great for time constrained competitions!

Continued in Part 5: Performance Persmormanche! or play it here!

Little Fortune Planet Breakdown - Part 5: Performance Persmormanche!

Continued from part 4.

Part 5: Performance Persmormanche!

Uh-oh. Trouble! The browser simulation runs at slideshow speed. To be expected given the naive implementation. Besides going for a more technically sensible solution, how about we try to improve what we have.

First we start by freezing cells that don't need attention. Eventually we could keep track of a queue of cells that demand attention, but given the available time we decided to give each cell a sleep counter and skip the simulation subsystem for that cell if it is asleep. Things like dirt can typically sleep for multiple frames without affecting the simulation much.

Q9VxPhc.png

What if we only run half the simulation each frame? We can double the simulation performance by interlacing; calculating all even rows on frame 1, all odd rows on frame 2, etc.

image23.gif image6.gif

Luckily the simulation seems visually identical. Can you spot the difference? This pushes the game outside the slideshow experience. Still slow, but it will do!

Continued in part 6: Finishing touches, deck of cards! or play it here!

Little Fortune Planet Breakdown - Part 6: Finishing touches, deck of cards!

Continued from part 5.

While we coded the simulation @Flaterectomy spent his time drawing loads of pretty cards. We’ll have to code mechanics so the user can pick a card, and have that card act upon the world.

To save some time for coding we’ll want to enable @Flaterectomy to work on card metadata by creating an external library of cards, a CardSystem will be responsible for loading the metadata+scripts from a JSON file into our library.

image24.png

The CardSystem will also keep track of the cards in the player's hand, and spawning those cards as clickable entities in our ECS.

image21.gif

A second system could execute the scripts on each card (CardSystem) and interact with other systems to apply desired effects.

image8.png

This is where earlier choices start to pay off. Our toolkit of components and simulation systems can be easily expanded with scripted effects like clouds, steam, evaporation, aliens that live inside a hollow earth and fall away from gravity, raining coffee shops, heat, etc.

image11.gif

We create stencils of magma chutes, hollow earth, that we can rotate and apply onto the simulation whenever certain cards are drawn using the same logic we used to load the planet, just ignoring certain preexisting blocks.

image2.png image9.png

image17.gif

There we go! Since the sandbox aspect is where we had the most fun, we reward the player with achievements that can be used to edit the world directly.

image3.gif

That’s it! Hope you enjoyed the series. You can play around with the source, return to part 1 of this breakdown, or blow up your own planet!

Little Fortune Planet Bonus Breakdown - Part 7: LibGDX/GWT performance tuning

As mentioned before Little Fortune Planet was a bit of an experiment with non trivial, non optimized game design using LibGDX and GWT. Loads of nested loops O(n2), and dynamic textures. The game ran horribly slow on web, so we set out improving performance post jam.

Disclaimer: Food for LibGDX/GWT devs, but still got some meaty bits for others. We used LibGDX, a java game development framework that targets a wide variety of platforms. Keeping a couple of gotchas in mind, it transpiles your Java game (using Google Web Toolkit) to JavaScript fairly effortlessly. While the tooling is pretty good, it can be a real pain to profile.

Goals

Ideally the game would run at a steady 60 fps. Let's see what is eating all our performance. If you are using artemis-odb, grab the excellent profiler plugin made by @piotr-j for low cost profiling in game.

profiler.png

A target of 60 fps means we have ~16ms to spend per frame. Currently on my high end machine frames take at least double that to render on Chrome. Firefox and IE are even worse. Throughout optimizing Firefox generally seemed to struggle with our game.

Profiling Your (LibGDX) Web Game

So how to proceed? We'll run Chrome's built in profiler (F12 - Performance tab). Firefox and IE dev tools have similar features, so use whichever you prefer. Let's see what a couple of seconds of record button yields:

obfuscate.png

Oops! Looks like our function names have been obfuscated. We could use Google Web Toolkit's superdev mode to solve this for us, as it provides bridge between your Java naming and the browser dev tools, but since I'm not 100% sure on the side effects on profiling, we'll keep things vanilla and disable the obfuscator instead.

Add style PRETTY or DETAILED to html/build.gradle in your libgdx project.

java import de.richsource.gradle.plugins.gwt.Style compiler { optimize = 0 style = Style.DETAILED }

After redeploying the game and rerunning the profiler we get:

profiler2.png

Now we can read the function names! We'll run the profiler for a couple of seconds, and then sort 'Bottom-Up' to find hotspots in our code. In our case we're interested in functions that have a large amount of 'self-time', these functions are eating all our valuable frame time.

In our game we've identified two possible areas for improvement: Simulating and rendering the planet.

Improving Simulation Performance

Improving performance is relatively straightforward. Find the functions with the highest self-time and the least amount of effort to reach your set end goal.

rngisevil.png

In this case it seems the GWT random number generation is the culprit of bad performance. We use RNG heavily throughout the simulation; What direction does water flow this tick, where does stream spawn, etc. Since all simulation logic is run within a loop, this ends up being extremely expensive.

We could limit the uses of RNG but we don't want to rewrite everything or break the sim, so instead lets just precalculate our random numbers and see if we can fake it!

```java public class FauxRng {

private static final int PREGEN_COUNT = 10000;
private static int[] pregen = new int[PREGEN_COUNT];
private static int cursor = 0;

static {
    Random random = new Random();
    for (int i = 0; i < PREGEN_COUNT; i++) {
        pregen[i] = random.nextInt(Integer.MAX_VALUE);
    }
}

/**
 * Returns a random number between 0 and end (inclusive).
 */
public static int random(int range) {
    return nextInt(range + 1);
}

private static int nextInt(int i) {
    cursor = (cursor + 1) % PREGEN_COUNT;
    return pregen[cursor] % i;
}

/**
 * Returns a random number between start (inclusive) and end (inclusive).
 */
static public int random(int start, int end) {
    return start + nextInt(end - start + 1);
}

public static boolean randomBoolean() {
    return nextInt(2) == 1;
}

} ```

Don't show my boss.

Besides this change we limit the neighbor checks needed for each cell where possible. There are also some things that won't hurt the simulation much if they are run less often, like updates to the heat map.

Improving Rendering Performance

On LibGDX dynamic textures are generated using a Pixmap, which is fast on desktop, but slow as a snail on the browser. Lets check LibGDX's Pixmap implementation on web platform to check out what is so costly about this.

```java this.ensureCanvasExists(); if(this.blending == Pixmap.Blending.None) { this.context.setFillStyle(clearColor); this.context.setStrokeStyle(clearColor); this.context.setGlobalCompositeOperation("destination-out"); this.context.beginPath(); this.context.rect((double)x, (double)y, (double)width, (double)height); this.fillOrStrokePath(drawType); this.context.closePath(); this.context.setFillStyle(this.color); this.context.setStrokeStyle(this.color); this.context.setGlobalCompositeOperation(Composite.SOURCE_OVER); }

    this.context.beginPath();
    this.context.rect((double)x, (double)y, (double)width, (double)height);
    this.fillOrStrokePath(drawType);
    this.context.closePath();
    this.pixels = null;

```

Yikes! Pixmap is backed by a browser canvas. Since we draw tens of thousands of pixels, a fat loop won't perform very well as a tight one would.

If we could push an array of color data straight into the canvas it might perform better. Google Web Toolkit allows you to directly hook into Javascript, so lets write a little function to feed the canvas our pixel buffer. This ended up fixing rendering times to 4ms on Chrome, but Firefox still struggled. Dang!

Take a Break or Educate!?

Ultimately reading the google scriptures on the matter would help, but I tend to end up with too many browser tabs of interesting topics and no work done. Sometimes taking a short break and giving your mind a rest can be as effective; got an idea! Lets try something else.

Since only a small amount of particles in our sim change each frame, why not keep track of those and only do the expensive pixel plotting calls when we need to? We use an in-memory buffer outside of the GPU to track pixel changes, and plot changed pixels to a persistant FrameBuffer in GPU memory.

Delta's visualized looks something like this:

5921aa9170f27591622802.gif

Success! We managed to drop rendering time to 1-4ms on our target browsers.

Final Results

We've managed to get the time to generate a frame down to about 6-10ms, which is pretty good. We still hit the 30ms sometimes but overall the simulation is pretty smooth.

muchbetter.gif

Wanna try it out yourself? You can play the sandbox version here (WEB). Press P to open up the profiler.

Zwfduhc.png

LD 39

Artax! (Web)

We’ve made our emotional puzzle platformer hard to spare you the heart-wrenching ending!

artax-wakeup

Play it here! (HTML5)

 

LD 41

POST 1: Wreckless Rally: Brainstorming and merging two genres

title-part1.png

Guidelines we follow, tips for you!

Some things to keep in mind that has helped us greatly in our ludum entries. Players will only have a minute or two to rate your game, so time your game! You are targeting a broad audience, and you more than likely won’t have enough time to satisfy hard core fans of a genre, so keep the game simplistic and intuitive. Ideally it has to have some replayability. Prototype your core mechanics asap!

Brainstorming and merging two genres

Just submitting to the theme can make brainstorming a lot of fun. Are we going to make an FPS mixed with Murder Mystery where you were the suspect? A stock broker RTS? A poetry brawler? The possibilities!

We settled on taking a very mechanically juicy core loop jewel matching game like bejeweled with something completely opposite: a top down cart racing game.

bejeweled-3-nitro.png

Whiteboarding a core loop

The player’s experience has to be fun and intuitive. Infusing one genre with the flavors of the other and boiling it down seemed like the best way to achieve that; just stacking all mechanics would make it too hard to understand and loads of work to code.

mashup.png

After torturing my girlfriend for her jewel game knowledge and google-fu ing this infographic and exchaustive blog post by Jonathan Bailey we got a good grasp of the meaty bits:

The goal of the game is to score points by making easy-to-hard matches. The track is the board. The cars are the pieces. Player controls the board indirectly, with his tow truck.

whiteboard.png

Easy enough. But how will we make the player control the pieces exactly?

Next up: Prototyping Smototyping!

More posts will appear here!

Come play Wreckless Rally! (HTML5)

PART 2: Wreckless Rally: Prototyping Smototyping!

title-part2.png

Back to Part 1: Brainstorming and Merging Two Genres

Prototyping Smototyping!

We could have the player knock or tow cars into pit stops. Perhaps it is more fun to make chains in place. Would it be fun to allow the player to reorder the cars on his towing chain? It’s hard to gauge any of this without a prototype, so we set our goal for day one: have a working prototype!

What didn’t work

Approaching this like a typical jewel-matching game doesn’t work out of the box. A screen filled with cars becomes really hard to process when the camera moves and you are also trying to avoid crashing into things.

car-overload.png

So lets tune down the number of cars. We also tune some other aspects until they feel right; scrolling speed, car control.

Towing cars onto pitstops feels fun but can be a bit hard and one-dimensional, chaining cars on the track feels pleasing as well and provides a lot of freedom. If we keep both mechanics and make one a bonus mechanic the whole core loop becomes a lot richer.

Reordering the cars on the tow chain doesn’t really add much except requiring an extra button, so let’s just allow the player to release the tow with a button press.

Oh no! All our cars are off-grid!

For the player making chains of off-grid cars is very hard, and our algorithm a lot more fidgety, so lets make them gravitate towards a grid.

grid-snap.gif

Not perfect, but it makes the game a lot easier to play.

Giving players more control

Towed cars count as chainable pieces on the board. Making sets on the chain feels really rewarding and intuitive, but players will never be able to tow more than two cars at once without them instantly plopping out of existence. It also means longer pit stops have to be multi color or players cannot fill them easily.

insta-chaining.gif

Good matcher/jewel games allow you to intuitively pick up the mechanics, but have more meat to them. What happens if I chain four gems? What happens if i make two chains cascade?

Lets count cars in tow as out of the game and using a button to release. Hey presto! Suddenly longer pit stops work, and players control when to cash in multiple color chains at once. Fun achieved!

chain-popping.gif

“But the cars aren’t moving and this is a race”

Collaboration is both a lot of fun and a lot of frustration at the same. The game feels fun, and now our graphics guy @Flaterectomy is complaining the race isn’t a race! Drats.

boring.gif

Getting the cars moving quickly turns the game into an impossible task; suddenly either the scroll the map faster and have pit stops race past, or the cars scuttle all over the place giving our poor player a chaotic cat herding experience, what can we do?

everythingmoving.gif

Let’s compromise. Have a couple of racer cars run in from behind, and have the majority of the cars appear crashed. Surprisingly this provides a great sense of immersion to the game without frustrating the plyer, and as an added bonus, it introduces some themed hazards to avoid.

some-cars-now-move.gif

Next up: Meat of the Code

More parts here!

Play wreckless-rally here

PART 3: Wreckless Rally: Meat of the Code

title-part3.png

Back to part 2: Prototyping Smototyping!

Meat of the Code

Recycling Earlier Projects

Since we can start with any code base we can save a lot of time by just recycling all the base systems we need, so let's just grab our previous ludum dare game Spacelitch, and refactor it a bit.

pasted image 0.png

We want the screen real estate so lets change scrolling to the right, rip out all the systems we won’t use (dialog, shooting, ai, etc). Add a starter tileset and we’ve got the basics!

prototype-spacelitch.gif

Chain-o-rama algorithm!

The chaining algorithm posed two technical hurdles for us; how do jewel game matching algorithms work, and how do we deal with fast moving cars.

With 72 hours there rarely is any time to design proper algorithms. If you’re anything like me, i’m more of a wing-it-orithm guy anyway, so let’s wing it!

Basic plan: overlay a grid over the camera area, and have a system plot every visible car and pitstop location on it.

whiteboard-cars.png

After that, scan the grid and create groups of horizontal and vertical touching cars of the same color. Any chain longer than 3 will get a payout.

whiteboard-carchain.png

Pitstops

We also do the same for pitstop groups. If all touching pitstops have the corresponding car color on them, a payout results. Easy!

whiteboard-pits.png

Cutting corners

Generating the map procedurally would be a lot of work, so let’s just use a map editor to slap it together. We don’t have a proper physics engine like box2d in our library. So instead of spending hours coding it let's just avoid proper collision and physics. Cheating is fun!

Next up: Flavouring!

More parts here!

Play Wreckless Rally here

Wreckless Rally Coding Timelapse

Thanks for the theme, this was a blast to code!

ezgif-2-7f9abd052b.gif

WRECKLESS RALLY, where you drive your tow truck around a race track, playing some kind of Bejewelled along the way. Drop off wrecked cars for points, but mind the frog! 🐸🏎️🏎️🏎️

https://youtu.be/V3wt-auXdIg

PART 4: Wreckless Rally: Flavouring!

title-part4.png

Back to part 3: Meat of the Code

Little bits of flavouring!

Adding some fluff can really help make a game feel like a game. So let’s fluff it up!

Spin out!

When cars collide take control away for a bit, have them shoot in a random direction and spin. Added bonus makes the collision hazard more of a hazard to avoid; it’ll ruin your chaining.

spinout.gif

Nice! Taking control away from the player can be immersive but too long and it becomes annoying. So we tune it down a bit and make them shoot away a bit further. Perfect!

Tire tracks!

Lets add tire tracks! Particles are relatively cheap so we use a transparent dark smudge and project it under every wheel. Fade out over distance. Or better yet, it might actually be faster to code just to have a single sprite with all the wheels on it. Hey presto! Looks amazing combined with a spin out.

spinout-with-tracks.gif

Racing start

Cherry on the cake in Wreckless is the start of the race. We spawn active racers on all the starting positions, have them wait until the starting lights tick down, and let all the systems combine into happy little accidents! The player slow little truck bubbles behind them, racers collide and provide the chaotic narrative we need for the game. Perfect!

chaotic-start.gif

We obviously planned this. Ha! Haha!

Hazards

Adding some barricades, barrels and pylons that the player can knock over will help the map feel a lot less static, so let’s do that!

hazards.gif

Next up: Game Balance and Intuitiveness

Check out other parts here!

Play wreckless-rally here