Adventures in creating a Snap from an LWJGL2 based game

The old Artifact is still kicking, not too long ago I created a Snap for it. Creating the Snap felt a bit like concocting a magical snapcraft.yaml and and hoping it works out. For the first few attempts the magic never works out, and the process of figuring things out tend to be tedious at best. This was no exception. Here are some of the problems I ran into, hope it helps someone else.

Xprop missing

My first Snap attempt immediately spit out this during startup:

java.io.IOException: Cannot run program "/usr/bin/xprop": error=2, No such file or directory

This was fixed by adding these lines to my snapcraft.yaml. The layout is needed since xprop is referred to by an absolute path. See this thread for more information.

layout:
/usr/bin/xprop:
bind-file: $SNAP/usr/bin/xprop parts: mypart: stage-packages: - x11-utils A xrandr puzzle Next in line was this: Exception in thread "main" java.lang.ExceptionInInitializerError at org.newdawn.slick.AppGameContainer$1.run(AppGameContainer.java:39)
at java.security.AccessController.doPrivileged(Native Method)
at org.newdawn.slick.AppGameContainer.<clinit>(AppGameContainer.java:36)
at game.Artifact.main(Unknown Source)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.lwjgl.opengl.LinuxDisplay.getAvailableDisplayModes(LinuxDisplay.java:951)
at org.lwjgl.opengl.LinuxDisplay.init(LinuxDisplay.java:738)
at org.lwjgl.opengl.Display.<clinit>(Display.java:138)
... 4 more


This was caused by xrandr not being installed in the snap, which LWJGL2 uses to find display stuff. This was fixed by adding the x11-server-utils package, which installs xrandr.

stage-packages:
- x11-xserver-utils

For debugging snaps and finding packages these commands were great.

#This allows you to look at the system as seen from the snap
snap run --shell <your-snapname>

#This will give the package that installed an executable, in this case xrandr
dpkg-query -S /bin/xrandr


I hope this helps someone else looking to get their application in a Snap.

Artifact Snap and AppImage for Linux

Some time ago I added an AppImage for my old game Artifact, as an easy way of installation on Linux. AppImages have a neat architecture, and hopefully will keep Artifact running for a long time on a lot of systems. AppImages can also be run sandboxed using Firejail if you have little trust in me or the source of the AppImage.

Now, AppImages do not really have a nice centralized location where applications can be discovered. There are some initiatives, but it feels a bit crude and lacking some polish.

Snaps and their central registry on the other hand feel way more polished. If anything the content in the store often feels unpolished compared to the store. Snaps also run sandboxed by default. While this is good, it sometimes causes unexpected issues, and can be opted out of.

Making a Snap of a LWJGL 2 application was a bit of a headache, but it worked out in the end. My experience with the Snap documentation in general was good, and most of the work was a breeze after I got the game running as a Snap.

Now, go play some Artifact on Linux!

Less light pollution; better photos.

So I finally got to try to take astro photographies from somewhere with less light pollution. I still have trouble with movement from either my tracking lagging a bit, or me not having a remote control for the camera (so I cause movement in the telescope when I start the shot).

M42 – Orion Nebula again

M42 is so easy to find observe and shoot. I also finally got to see some of the Flame Nebula, by doing a 30 seconds exposure into what looked like nothing at all. It sadly did not turn out very well because of movement in the camera, but I finally saw something! Anyway, here is my M42 shot. Getting better at this!

M31 – Andromeda Galaxy

The moon would easily fit in this picture, but the Andromeda galaxy takes more space, so this is mostly the core and some of the arms. I think I could fit most of the galaxy if I had rotated the camera. I randomly also caught M32 (barely visible at the left edge) and M110 (in the lower right corner). Looking forward to try Andromeda with an even longer exposure, or many stacked images.

Pauper tribal – A fresh MTG format

One of the things I find most fun about Magic The Gathering is exploring deck construction under new constraints. Me and some friends are currently exploring a format which have these rules.

Rules

• Normal constructed magic rules. Decks are 60 cards, players start with 20 life, 15 card sideboards, and so on.
• Only cards that are legal in Pauper and not on the Pauper tribal ban list can be played.
• The deck must at all times contain 20 cards from the same tribe. Tribal instants and changeling cards count towards this total.
• The chosen tribe can not be Elf, Human or Goblin. This restriction is to ensure other tribes are feasible.

Ban list

The point of a format is to explore magic in an interesting way. If single cards dominate or are too obvious choices, they might end up here.

My thoughts so far

I really like that the constraints for this format are so simple. It is easy to make a format that is fresh, but where the constraints are complex. For some reason such complex constraints make a format feel inelegant and less appealing to me.

Babynavnvelgeren – Fast exploration of Norwegian given names

My good friend Feda Curic recently came to me and wanted to make something together during his parental leave. At first we started out with something a bit too ambitious (for the time we had set aside), but then his wife came up with a great idea we could finish in our limited amount of time.

She wanted an app where you could quickly look up names for babies. Here in Norway Statistisk sentralbyrå (SSB) has statistics for all names used 4 or more times. The SSBs user interface leaves something to be desired though. It is either small lists containing some names, or a name search, where you input the exact name, and then get statistics about that specific name.

The SSB interface is not at all useful for exploratory search for names. In Babynavnvelgeren (the app we made) we have a lightning fast interactive search and filtering options. The data is available locally in the app, so it mostly works offline as well.

Babynavnvelgeren makes searching for names easy and fun. My 8 year old daughter loves searching while sorting for the least popular names. She found some very interesting ones like:

• Sau – Sheep in Norwegian.
• Lillebil – I initially thought this was a bug for sure, but it is a name. My daughter finds it hilarious (“Lille” means small and “bil” is car in Norwegian).

More generally I think Interactivity and responsiveness is essential for exploration, and the process of exploration often leads to accidental discoveries and new hypothesis building. UIs which support this kind of interactivity are very useful in my experience, and I think more applications/data providers should have this in mind when presenting their data.

I also think there is a lot of low hanging fruit in this space, and small improvements in interactivity often cause massive increases in efficiency. For Norwegian names, Babynavnvelgeren has got you covered. Go get it!

One way to stop a 2D spaceship as fast as possible.

For a quite a while, I have wanted to try and create simple touch based interface for a 2D spaceship game. I want to allow the player to simply drag anywhere on the screen, and the spaceship moves to that position and direction in an efficient manner. Ideally the most efficient manner.

Spaceships in 2D games usually have one main engine that allows forward thrust, and some that allow rotation around the ships center of mass.

Moving from point A to B efficiently (in minimal time) is not trivial with such constraints, as changes to direction and thrust may have huge consequences for later possible movements due to inertia.

So instead of looking at the full A to B problem immediately, I wanted to look at something simpler first, namely to go from having velocity $$v_0$$ and pointing in direction $$\theta_0$$ to have 0 velocity as fast as possible.

The idea I use originally came from talking to a colleague, but something very similar sounding is mentioned in planning algorithms, though examples always seems to involve driftless systems. Anyway, my current approach involves these known quantities and assumptions:

• $$a$$ – Acceleration – The ship can only accelerate by a constant amount, and acceleration turns on and off instantly.
• $$s$$ – Turn speed – rotating the ship requires no acceleration, and the ship has constant rotation rate.
• $$\theta_0$$ – Initial orientation.
• $$v_0$$ – Initial velocity

These quantities allow me to find a legal, but very suboptimal way to stop. It simply involves to turn the ship to face its velocity vector, and then accelerate until it stops. Both the time needed to turn the ship $$t_a$$ and the time $$t_m$$ needed to turn and reverse the velocity are easy to calculate.

It is also easy to see that this is suboptimal, it would clearly be faster, to start burning some time before the turn is fully completed, but the question is when to start the burn.

To allow for this freedom in my model, I therefore introduce a third time variable $$t_s$$. $$t_s$$ is the time to start turning and accelerating at the same time. $$t_a$$ now becomes the time when I stop turning and only accelerate.

Given these intervals, two integrals describe how the velocity will change when $$t_s$$, $$t_a$$ and $$t_m$$ vary.

$$v_x = \int_{t_s}^{t_a} a\cos(\theta_0+st)dt + \int_{t_a}^{t_m} a\cos(\theta_0+st_a)dt$$

$$v_y = \int_{t_s}^{t_a} a\sin(\theta_0+st)dt + \int_{t_a}^{t_m} a\sin(\theta_0+st_a)dt$$

This gives two constraints, that must hold for all solutions of this kind.

$$0 = v_{0x} + \int_{t_s}^{t_a} a\cos(\theta_0+st)dt + \int_{t_a}^{t_m} a\cos(\theta_0+st_a)dt$$

$$0 = v_{0y} + \int_{t_s}^{t_a} a\sin(\theta_0+st)dt + \int_{t_a}^{t_m} a\sin(\theta_0+st_a)dt$$

The most efficient solution to this problem, is the $$t_s$$, $$t_a$$ and $$t_m$$ triplet with the lowest value for $$t_m$$.

This information allows me to formulate this as a optimization problem.

Since I want to minimise $$t_m$$, the objective function simply becomes $${t_m}^2$$.

This is subject to the two equality constraints given.

Since the objective and constraints are non-linear, I plug i into Optizelle which is a framework for solving non-linear optimization problems.

The implementation can be found on github, it uses autograd, to calculate derivatives and hessians. This is an incredible time saver since calculating 9 combinations of partial derivatives would have been a major pain, not to mention having to recalculate them whenever I did something wrong.

Running the program with inputs $$a=2.0$$, $$\theta_0=0$$, $$v_0=[2,0]$$ and $$s=\frac{\pi}{2}$$ returns:

The optimal point vector contains the values for $$t_s$$,$$t_a$$ and $$t_m$$. This means that for a ship with the given input, it should start turning immediately, then start the burn after approximately 1.43 seconds, stop turning and only accelerate at 2.43 and finally be at rest after 2.57 seconds, approximately 0.43 seconds faster then the naive version.

To test the result, I implemented a quick and dirty javascript program that simulates these choices and renders to a canvas:

Sometimes the ships end up drifting a bit after the simulation has finished. This is due to the discrete nature of the simulation not perfectly emulating the continuous solution (I do not integrate rotation analytically in the simulation). This could also have been a problem if I applied this style of planning to a game that did the same, from the simulation above it looks negligible though, which is great!

I am very happy with this result, it seems like it could work for the larger problem as well. The next step I’ll try, is to tackle some specific cases of moving from point A to B efficiently. For those cases there will be many more time variables involved, and possibly many constellations of safe initial starting points as well as possible freedoms to introduce in the model. It will be interesting to see how that works out.

Start a draft

For a while I have been working on a generic draft engine for card games. In trading card games (TCGs), drafting is a way to distribute cards in a semi random way, where players interact with how cards are distributed. In the TCG world this is distinct from sealed deck (semi randomly distributed cards, but no player interaction during dustribution) and constructed (you design your deck before playing from a set of allowed cards).

Supported draft styles

My draft engine supports two styles of draft:

• Grid draft: A draft style for two people where you select rows or columns of cards from 9 face up cards.
• Regular draft: In this draft style you pick a card from a pack and pass the pack to the next player. It works with 2-8 players, but 6-8 is recommended.

These forms of draft can be used for most kinds of TCGs. Since the engine is not tied to any specific kind of game, you can draft anything you can give a name and an image. You can draft your family photos if you want to.

Drafts with custom content

The engine works by using a very simple JSON structure to supply card names and card images, it looks like this:

[
[
{
"name": "CardOnePackOne",
"url": "http://crazymedia.com/cardonepackone.png",
"id": 0
},
{
"name": "CardTwoPackOne",
"url": "http://crazymedia.com/cardtwopackone.png",
"id": 0
}
],
[
{
"name": "CardOnePackTwo",
"url": "http://crazymedia.com/cardonepacktwo.png",
"id": 0
},
{
"name": "CardTwoPackTwo",
"url": "http://crazymedia.com/cardtwopacktwo.png",
"id": 0
}
]
]


The values are pretty self explanatory, but for clarity:

• “name” – The name of the card, which you can export when finished drafting.
• “url” – An URL pointing to an image of the card.
• “id” – Not in use, so 0 is a fine value.

The engine comes with several predefined card list. Packs will then be drawn from those lists, but if you want to supply your own set (for example a cube or your own game) it is possible to start a draft where you send in any number of packs of cards using the JSON format shown above.

Have fun drafting.

BitBreeds stand with the humans; we won’t let it slide.

Aliens

With the discovery of a possibly habitable planet around one of our closest stellar neighbours, it has become clear that sooner rather then later, there will be aliens and UFOs around.

A new hope

This summer, UFO Hunter, a simulator for waging war against UFOs was revived and released to the public.

Since the future of humanity rests on the shoulders of this simulator and spacex, we have called back one of our most important assets (a veteran from future wars carefully regrown from DNA retrieved in the Artifact) to perform a thorough test of the simulator.

The force awakens

In the spirit of Shi Qiang, Lou Ji and Thomas Wade, we at BitBreeds have declared for the humans. Like our spacex and UFO Hunter friends, we have set our sight on the stars, and we are going for the goal.

What will you do?

Webtorrent; we get signal.

Lately I have been looking into WebRTC which is an open standard for real time communication between browsers. It allows communication styles in the browser which previously were not possible.

WebTorrent uses WebRTC for a protocol similar to bittorrent. Instead of having to download a program or install a browser plugin, you can download a webtorrent (which currently must be seeded as a webtorrent, by forexample instant.io) directly in the browser.

No seeds

If there are no seeds, you can seed the file yourself by visiting the differently styled button below. This button uses a feature of WT-widgets that does a fallback to XMLHttpRequest after 5 seconds. When it is finished downloading the file, it will start seeding. Then the first button should work, since there is a seed.

Suggestions or pull requests with fixes/additions are always welcome. I hope to expand WT-widgets with some widgets that show progress horizontally, as well as some widgets that more clearly show when it is in the different states of a download.

What Webtorrent sorely needs

While seeding in the browser works great, I do not want to have a browser fired up at all times to ensure there are seeds for my content. The best option I found for seeding webtorrents was webtorrent-hybrid, but when I tried it, I sadly could not get it to build.

Once Webtorrent has a solid solution for server side bootstrap seeding, I think it is will become a great alternative for distributing some kinds of content.

Take off every ‘ZIG’!!

Pear pram construction

My 3 year old daughter’s current favourite book is Jakob Martin Strid’s Den utrolige historien om den kjempestore pæra. In the story a giant pear is made hollow, and eventually turned into a boat. I decided to try and make a similar upright floating pear-boat out of a normal pear. One that my my daughter could play with once finished. Off I went to buy a pear and tools, the pear I ended up with have these specs:

• Weighs around 238 g.
• Displaces approximately 225 ml of water. This means it is slightly more dense then water since the weight of that water would be approximately 225 g.
• Judging from the pears available in the shop, the one I chose was slightly more symmetric then most pears.

In addition to the pear, the tools I used are shown in the image below:

The first step in pear pram creation, is to cut the windows using a knife. Once that is done carve out the inside using the melon baller. I recommend making the windows close to the top of the pear. If you make them too low they will result in water intake when launched. It is better to create the windows high initially and expand them downwards once you have a feeling for how the pear floats.

Another great reason for making the windows high up is lowering the center of mass. Pears have not yet been cultivated to float upright, and the center of mass is way too high for that. Having a too high center of mass on a ship is catastrophic. In its unmodified form a hollow pear will most likely perform worse then the Vasa on its maiden voyage.

To lower the center of mass even more, it is important to carve out as much as possible of the “roof”. Since the stalk extends into the pear this is difficult. It is easy to ruin the pear if you use too much force; be careful.

Even with the windows high up and a very light roof, the center of mass is still too high. Initially I added coins on the inside as ballast, this worked if I put the pear very carefully into the water, but it was still prone to capsizing.

To remedy this I moved the center of mass even lower by adding ballast on a thread below the pear. This was done by creating a knot on the thread and using a needle to get it through the bottom of the pear. Then the coins were added as shown in the picture. To ensure that water would not leak along the thread into the pear, I greased the entry points.

In its finished form the pear is quite stable, it could hold a surprising amount of Lego men without capsizing. I never got around  to test adding a sail, but I think it might be stable enough to support a small sail.