A Gradle Primer for Libgdx Users

Every time I set up a new project I learn something about how Gradle works and the default project setup for Libgdx. I’ve decided to write this down so the next time I start a project I don’t have to relearn all of this from scratch. I’m using Intellij IDE, and from what I read things are different in Eclipse. If using Intellij it is important to note that a Gradle run configurations targeting a sub-project run task  can be used in lieu of an application run configuration. The advantage of doing this is that asset location and jvm arguments are all handled in Gradle files making project set up easier for multiple users.

Most start-using-Gradle sites say you should start by installing Gradle. Good news is Libgdx uses Gradle Wrapper, which provides scripts for both Linux and Windows allowing Gradle to be run without installing. Yay!

The next thing most start-using-Gradle tutorials will say is ‘create a hello world task’ and this is where we’re going to diverge a bit, since files and tasks were created automatically during by the libgdx project setup program. So I’m going to discuss the various Gradle files the Libgdx project setup program created.

The Files


gradle.properties

  • Not totally sure what this does, but it appears to be arguments for when Gradle gets launched by the wrapper.

settings.gradle

  • This is a short file indicating the structure of the project. It indicates how the various sub-projects are organized. The basic setup just lists ‘core’ + all of the target platforms.

build.gradle

  • There are a number of build.gradle files; one in the main folder and one in each of the platform folders. Having multiple build.gradle files the standard format for Gradle projects with subprojects.
  • The build.gradle file in the main folder contains dependencies for both external libraries and the internal subprojects. This is where the platform subprojects are related to the core subproject and the libgdx and other library dependencies are managed.
  • The build.gradle files in the subproject folder contain build tasks associated with each of the projects. For example the desktop subproject has a run task that can be used to launch the desktop application.

Now let’s look at modifying things.

If we want to add a runtime argument to indicate the location of a log4j2 configuration file we would add the line

“jvmArgs = [‘-Dlog4j.configurationFile=log4j2.xml’]”

To the top of the run task.

 

If a client-server project is desired where the platform and core projects become sub projects of the client project this can be done by prepending ‘client:’ to the existing project names in the settings.gradle file and the main build.gradle file. This assumes that both the platform and core sub-projects are contained in the client folder as shown below.

Bot Escape Demo released

Hey Look A Thing!

You can download the demo release here.

About the Game

What do you in Bot Escape? Drive around a robot and look for a door. How do you do it? glad you asked.

  1. Use a controller! One of the purposes of this project was to learn how to get controller input and that works.
  2. Keyboard Controls (keyboard controls can be changed under options)

‘a’ left

‘d’ right

‘w’ jump

‘e’ shoot missile

Here’s some screen shots

Even More About The Game

Generally don’t expect too much. This project originated as a way to learn about box2D, controller input, Wang tiles, and maze generating algorithms. I think there’s some potential to be a decent game if some good levels are designed. I tried my hand at designing two levels and have come to the conclusion that level design is hard and I’m not currently in the mood to do it. So who knows when we’ll get real levels for Bot Escape. In the mean time try out the maze and let me know what you think of the controls.

Known issues

Sometimes the robot catches on horizontal surfaces in the generated mazes. This is an artifact of box2D, jump to unstick the robot.

Tiled Maps in Games 2

Well I’m still apparently on vacation time. Hopefully it gets better before it gets worse since I’m going to be traveling for the next three weeks. If I get ambitious maybe I’ll write a post in advance and figure out how the scheduler works.

This time I’m continuing the series on Wang tiles in games. For those of you who are counting this is part 10.  and for those of you who can’t count – talk to your technology service provider about an upgrade. The first part of the series can be found here.

According to the outline this post is going to be devoted to terminology.

Tile

A small colored region, generally, although not always, rectangular.

Examples:


Tile Set

A group of tiles where each tile appears only once. Typically this is how tiles are stored in game resources.

Examples: the example tiles from Tile, Low Frequency Feature, and High Frequency Feature could each compose a tile set.


Tile Map

An array of tiles. Each tile may appear multiple times and may be adjacent to copies of itself.

Examples:


Low Frequency Feature

Features that occur only a few times per tile. For differentiation purposes we’ll say that low frequency features can be counted easily

Examples:

 


High Frequency Feature

Features that occur more times than can be easily counted on a tile.

Examples:

 


Seamless Tiles

Tiles that when placed adjacent to each other have no easily distinguished boarder.

Example:

 

I think this is all the terminology we’ll need for this discussion. If you notice something missing feel free to leave a comment.


Which brings us to the second topic of the day. What are the problems with tile maps? I’m mostly going to talk about one reason: tile maps almost always look like a bunch of tiles (or are incredibly boring). Sometimes the clearly tiled look is a good thing. For example in a tactics or strategy game like Civ, or if you’re trying to evoke the aesthetic of a classic system they are great.

So, what makes a tile map always look like a bunch of tiles? The succinct answer is, “low frequency features”. The human brain is adept at finding patterns (even in cases where there aren’t any).  Low frequency features can be counted and grouped almost subconsciously, allowing anyone to identify when tiles are being used. This is true for both seamless and seamed tiles. The grass and stone tiles from Malwrath are all seamless, so the edges between like tiles are hard to find, but they have low frequency features and make it easy to see that tiles are being used.

The obvious solution to this is to use only high frequency features in the tiles. In fact lets take this idea to the extreme and use the ultimate high frequency tile.

Obviously a certain amount of features are needed to provide visual interest. While it is impossible to identify the edge of the monochrome tile or even that it is a tile it is incredibly dull. Features also allow the player to note that the character is moving. Without some form of terrain or reference, it just looks like the character is flailing around on screen. Thus tiles with only high frequency features will never have an organic feel to them. The dirt tile from Malwrath has only high frequency features and it looks a unnatural; even Mars doesn’t have dirt like that. Also included: an instance of human susceptibility to optical illusions – or an Martian rodent… take your pick.

https://i0.wp.com/livrespensadores.net/wp-content/uploads/2013/07/mars-rodent-orig-rover-composite1.jpg?resize=449%2C276

 

Stay tuned (subscribed?) for next time when I’ll talk about a way around the low frequency feature problem.

Platformer Update 9 – Bot Escape

Well I’m back from vacation, but I’m apparently still running on vacation time. The good news is I did some coding over vacation, which means we finally have some screen shots. Woot!

I’ve been using the working title BotEscape for this project for a few months since one of the original thoughts for this project was that you’re a robot escaping from your alien overlords, a crumbling factory or some combination of the two. As you can tell from that detailed description, I haven’t developed a storyline yet, so the current “levels” are just piling all the pieces together to make sure the interactions are working correctly. I haven’t checked to see if this name overlaps with any existing properties so I’m just going to run with it for now. It might get changed later if it looks like it poses a conflict with existing works.

There are three main tasks that need to be completed before I put up a demo of sorts:

  • Menu screens
  • A health system (read: a way to leave you a twisted pile of scrap metal)
  • A couple of levels that have some thought in them and aren’t just piles of clutter.

So over the next few weeks I’ll be working on these and any thing else that comes up to get a demo ready.

Tiled Maps In Games

This is the first in a multipart series on Wang tiles. The current sequence of topics covers a wide range: the Background of tiled maps, Terminology, Aperiodic tiling, Wang tiles, how to make your own Wang tiles, and how to procedurally generate a Wang tile map. And (if I get really ambitious) how to generate Wang tiles procedurally from a larger texture. Of course, all of this is subject to change since I haven’t written any of the articles yet.

Anyway, onward to our first topic: the background of tiled maps.

What are tile maps?

A tile map is a picture created by placing sub regions (a.k.a. “tiles”) at fixed intervals to form a grid. Good examples would be tiled floors, a checker board, tessellation artwork, the board from Settlers of Catan and the world map from any game in the Civilization series.

A tiled floor
A Chess Board
Free Civ World Map

How are tile maps used in games?

Tile maps are primarily used for both world and level maps in games. Of course, with current games that frequently depends on how strict of a definition is being used for a tile… Can a repeating 3D space be called a tile? Does drawing a repeating texture on the surface of a 3D object count? In any case, many games use tiled maps, and nearly all games for the good old NES and SNES used them.

Why use tile maps in games?

Since my cursory search of the Internet provided no resources on why tile maps were originally adopted in games, I get to speculate wildly (hehe). The most likely reason that tile maps were originally used is actually rather blase: resources were extremely limited. Let’s start with storage space. Tile maps allow a much larger space to be rendered than could be stored by a system if it was a single image. For example, let’s consider the Nintendo Entertainment System which has 2 kB of on-board ram and a game everyone should be familiar with The Legend of Zelda which clocked in at < 100 kB.  If the world map in The Legend of Zelda was stored as a single 24 bit RGB image it would occupy 23,000 kB (world 16 x 8 screens and each screen is 256 x 240 pixels) of memory. It’s clear that some form of image compression needed to be used to create larger worlds on the NES. One of these compression methods was the use of a tile map to build the world.

Other resource limitations to consider are money and time. Specifically, even paying a lowly artist to draw all of these images would become incredibly expensive and be a massive time sink. Let’s just look at what it would cost if the artist was paid per screen of images drawn. If the tile set used occupies approximately one screen you could reduce the cost of the art by 99% and use it to make the game mechanics better – or increase your profit! That number is if you estimate that there are ~38 unique tiles in the over world map and a screen is 14 x 10 tiles. Of course, you can also reduce the number of unique tile drawings required by just changing the tile color.

It’s also possible that the use of tiles provide some additional benefits at the hardware rendering level. But, since I’m not familiar enough with the hardware and graphics implementation in these systems, I’ll stop my speculation with the obvious advantages I mentioned above.

 

I think this is enough for now stay tuned next time where I’ll discuss the terminology and shortcomings of tiled maps.

“New” Soundcloud account

I was definitely right about being swamped with other projects last week and it looks like this week too.

So rather than having a proper update, I’m just going to post a link to Sarcastibots “new” sound cloud account that was just set up 5 months ago.

So far we’ve uploaded a preliminary theme for Malwrath which maybe handy if we ever go back to that project.

Platformer Update 8

And another slow week although for different reasons. Last week I discovered Wang Tiles and remembered that aperodic tiling is a thing. So instead of working on adding features. I spent time figuring out how to implement Wang Tiles.

I’ll discuss aperiodic tiling and Wang Tiles next week, since this is going to be another slow week due not to me being distracted by a new shiny but because of life.

Platformer Update 7

It’s definitely been a slower week. Mostly I’ve been working on the animation for breakable crates. I tried a couple out and have settled on this one for the time being.

Not exactly sure what’s going on with the crenelations at the top of the box, but those were the shapes I got when I subdivided the original crate. Fun fact since it’s animated I can use lower resolution images and still not have it look terrible; so that little *.gif is pixel for pixel the final size.

Beyond the crate I made a number of other fixes to the working graphics for the player and the HUD.

Continuing Fun Times With Box2D

I’ve spent most of the week working on making destructible boxes for the platformer. The actual mechanics of this are fairly simple, and psedocode for the process is below.

if condition is met then

destroy box

The conditional statement can be checked during the regular update cycle (otherwise known as polling) or whenever a different condition is met (otherwise known as a listener).

For the destructible boxes the condition would be met if the impulse on the box would exceed a threshold value. I decided to use the listener method of checking the destruction condition; since, I already had a Box2D contact listener for the projectiles.

And now the fun starts so let’s add some equations. first impulse courtesy of Wikipedia.

\mathbf {J} =\int _{t_{1}}^{t_{2}}\mathbf {F} \,dt=\Delta \mathbf {p} =m\mathbf {v_{2}} -m\mathbf {v_{1}}

According to our good friends at Wikipedia impulse is the sum of the forces applied over a time period (t1 to t2) which can be expressed as a change in momentum and as mass times change in velocity.   hyper physics

It is not surprising then that the initial implementation measured the change in velocity between when the Box2D contact listener called beginContact() and endContact() on the destructible box. (there are legitimate issues with this implementation I know about them. If you’re having trouble imagining them think of someone pushing a sled gradually up to speed and then the pusher stops abruptly.) This was done because velocity is relatively easy to visualize and calculate. for example if the box were to start falling and impact the ground the some time later. The impact velocity could be calculated using either the fall time or the distance.  Assuming the velocity prior to impact >0 and immediately after impact is <=0. This should make it easy to tune the destruction velocity threshold depending on how many stories an object is expected to fall and remain intact.

After doing some mathematical manipulation and assuming initial velocity is zero. we get v² = 2ax. And we’re already to pick out some velocity thresholds.  So let’s move into the real err platformer world; where I took the liberty of having destructible box impact velocities logged for the record as well as start heights.

Experiment acceleration distance expected velocity actual velocity
Experiment 1 12 m/s/s 7.4 m 9.4 m/s 2.4 m/s
Experiment 2 12 m/s/s 7.3 m 9.4 m/s 1.99 m/s
Experiment 3 12 m/s/s 20.5 m 15.7 m/s 3.4 m/s

Something weird is definitely going on here. I’m currently assuming this is an artifact of how I was getting the velocity from Box2D. But I didn’t really dig into it too far since I realized there were other problems with this method, and switched to getting a ‘PostSolve’ impulse reading from Box2D which is closer but still different from the values I’m calculating. I suspect that I’m getting readings at the wrong time or that Box2D is taking additional things into consideration that were left out of the simple motion equations. (e.g. friction).

My conclusion for the week is, since a 10 cm difference in height resulted in a massive shift in impact velocity. This is annoying because it means that objects will require manual tuning of impact forces.

Platformer Update 5

This week I created a bug/feature list to better keep track of issues and what I wanted to do. And the list says that this week missile rate of fire was limited, explosion rendering was fixed, the player’s physics body was updated, jumping was converted jumpjets rather than legs, the player can now be controlled using an x-box controller, and work was started on a HUD. That sounds like progress to me! w00t!