pschichtel

LD 38

Too many cooks spoil the broth

Hi fellow gamedevs,

I'm part of Banana4Life, a team consisting of @rahtainka, @faithcaio, @jqnas and me. We made the small horror-ish game "Where Is Mommy?":

Title.png

One thing we noticed during the development of the game (or more precisely nearing the end of the jam): We produced a lot more and higher quality content in a shorter time span compared to our previous Ludum Dare appearances. During the last Jam we had three additional team members working on the game, yet we barely managed to publish the game in time. This time we easily finished several hours before the submission hours and had an overall better game.

This made us think about what went wrong last time, because our process stayed largely the same. In my opionon, there are two possible reasons, why this might have happened:

  1. Management overhead: Intuitively more developers would mean more work can be done and in theory that is probably true. However the larger the team gets, the more difficult it becomes to keep everyone on track with the project. Everyone needs to have a common vision of the game and everyone needs to be roughly aware of what others are doing. Communicating the vision and work will consume more time as the team size increases. Failing to communicate will most likely result in slowdowns due to duplicate work, merge conflicts and will lead to a distorted end result.

  2. Experience gap: Our core team (the previously mentioned people) work pretty well together and we have already participated in four previous Ludum Dare jams together (more in other constellations). Our mode was always the same: One artist working on visual assets, one artist working on acoustic assets, two programmers working on the logic and game/level design shared across all four (we generally make all our assets from scratch). The three new guys were unexperienced in game jams as well as with the technical platform (Unity3d). This lead understandably to a lot of questions which in turn took a lot of time away from the more experienced members. Additionally a lot of communication, which normally happens implicitly in the small team, did not happen across the entire team which lead to more confusion and slow downs.

For us, four people actively working on the game seems to be the sweet spot with maybe one additional member for some dedicated task (e.g. UI).

I'd like to hear your opinions and experiences on the topic: Do you work in teams? How big is your team?

And of course opinions on the game are just as welcome.

Submit for all the platforms!

Hi, I'm from the team Banana4Life (we made "Where is Mommy?"). Until now, I have been the one in charge of packaging the game and making it available to the world. @jqnas in the meanwhile makes the submission post for the game.

From our previous 6 game jam submissions and a lot of hours playing other submissions, I have collected some experience when it comes to submitting the game.

When to start Exporting?

Unexpected problems during the export process can easily delay your submission process beyond the submission hour. Depending on your internet connection, uploading the files will take another chunk of your submission time. We make our games using Unity3D since the last few jams (libGDX and other Java-based frameworks before), which makes exporting to various platforms very simple, but there are still a few gotchas like stray imports that cause compilation errors due to missing references. Most of the problems can easily be googled and are fairly easy to solve, but this all takes time. Many of the problems can be detected and prevented early on. So the punch line really is: Start testing your build early as if it was already submission hour.

Which Platforms and in which Form?

Short answer: All the platforms.

Generally more supported platforms means more people can play your games. In addition to supporting platforms, it should also be as easy as possible to run the game on every supported platform. An easy to start game would be a single executable file that can be executed from a graphical desktop. An hard to start game would be a huge number of files that require various other things to be installed beforehand.

In our libGDX days, we build a multi-platform self-contained JAR and a Windows executable wrapper using Launch4J. This worked ok, but still required to install a Java runtime and usually a shell on Linux desktops. libGDX' native components also limited the support beyond the common 3 operation systems and the x86 processor architecture. While it does support a web export using GWT, it was usually too time consuming to setup and keep working for our game jam projects.

Unity3D supports a lot of platforms, usually a lot more than the game will ever be played on. The best thing however: All platforms are supported natively and are easy to export to, including the Web.

So now we usually build Windows and Linux versions for play-testers, because this are the platforms we develop the game on and they are fast to export in Unity. For the submission we go with dedicated exports for Windows, Linux, MacOS and the Web. Native versions are great because they typically run smoother and they can be stored by the users for later replaying. A Web version is great because it runs everywhere, where a WebGL-capable browser can run.

Web versions are also the easiest to play, because LD users will already using a browser and it is most likely capable to run the game. This is good, even if it performs sub-optimal. If web version can generate enough interest in the game, a player will probably download a native version (if available) to get a better experience.

So my recommendation is: Export at least for the Web, but if your game performance intensive provide native version as well. Today ther are quite a few options to get your game into the browser like GWT (Java) and emscripten (native), so get familiar with them.

Where to Host?

Hosting the game is the last step you have to figure out, since ldjam itself doesn't provide hosting space. There are a lot of options here as well, some nicer than others. As a user I prefer to download games from sources I know and trust, so more common and well known the better. I also prefer to know from what the binaries were built and the possibility to build it myself, even if I rarely do that.

We in our team heavily use Git and Github. We develop all our games in the open with the code and assets on Github and the process live on Twitch. Many people here are familiar with Github, which does provide two very valuable features: Releases and Pages.

Releases are great because they allow you to directly link a source code state with the binaries built from it. New releases will not replace old ones, will coexist with previous ones.

Pages are nice, because the hosting is free and versioned through git just as everything else. This is perfect for the web version of your game. Just create an empty branch called gh-pages and put your web version into it. As soon as it's pushed to Github, it will be available at https://.github.io//, which can be linked from your release description.

Where you host is your choice, but you should prefer places, that are fast (can take a lot of downloads) and will stay for the future. Github covers that well while being free for open source projects.

How to Post?

There is a lot to say about good and bad game posts, here just a few things about mentioning your game release. You should mention all supported platforms explicitly, so the user can directly see if he can play it and sites like Feedback Friends can determine the supported platforms for filtering purposes. You should also make it clear, if certain builds of your game are not tested, you can even ask for feedback from users on these platforms.

TL;DR: Make the game playable in the browser or at least don't forget Linux!

PS: Play our game on Windows, Linux, MaxOS or directly in your browser: Where is Mommy?

Improved Post-Jam Version of Where is Mommy!

Hi guys! @faithcaio and I have worked on an improved version of our game "Where is Mommy". We have read the feedback and tried to fix the most them in this new version.

You can now rotate the camera freely around the player and we improved our game play hints, so you guys should better understand how to play it!

Where is Mommy?

Post your horror games and I'll play them!

We, Banana4Life, submitted "Where is Mommy?" to LD38 as our first ever attempt at an horror game. Getting the mood without breaking it throughout the game was a real challange, but we are pretty happy with the end result.

Did you make an horror or have you played one? Please share them, I'd really like to play them!

Where is Mommy?

LD 39

Please export for Web and/or Linux!

I'm a Linux user and from our team only the graphics guy is using Windows. Anyone using a recent version of Unity or libGDX should be able to export a Web-version or at least versions for Linux and MacOS.

Not only will you make me happy, but you will probably receive more rating as well due to the higher accessibility!

Our game Legendary Space Space Space has a Web version, versions for Windows, MacOS and Linux and is completely Open Source.

Last chance to rate an awesome space game!

So we at Banana4Life made a cool little game called "Legendary Space Space Space", which is a really fun space shooter. A few more ratings on it would be really nice!

https://ldjam.com/events/ludum-dare/39/legendary-space-space-space

If you rate and comment on our game I well definitely play and rate your game as well!

imageem2017-08-01/em03-16-38.png

Ludum Dare 47

Publish for Web!

Come on everyone, publish your games to the web.

Personally, I will not play games that only provide binary downloads.

  1. Most games don't publish for my OS (Linux), which is fine, I guess most of you are on Windows
  2. Binaries are kinda untrustworthy. I've seen several games that produce (probably false-positive) anti virus warnings on Windows systems.
  3. Most games do not publish sources, at least not directly in the ldjam page.

I will play native binaries iff the web version or the screenshots really hooked me and the native version promises some enhancements (usually better performance or controls).

Publishing for the web is pretty easy in probably all commonly used game engines (Unity, Unreal, Godot, LibGDX, ...).

For Unity you might need to disable compression in the web player settings before exporting (there are known bugs around it), but other than that it's just:

  1. Install web publishing support, if not already (in the Hub: "Add Modules" on the installation)
  2. Go to build settings
  3. Select WebGL
  4. Click Switch Platform
  5. Click Build, Select a Folder
  6. done.

It takes a bit longer than a native export, but it should generally work. If you are using UnityEditor classes (Handles and Gizmozs probably), you need to wrap them in #if UNITY_EDITOR #endif blocks or move the code to separate classes in the Assets/Editor folder, but the export errors are fairly clear on that.

"But where can I upload the export then?" you might ask.

I wrote a post about that for LD 38: https://ldjam.com/events/ludum-dare/38/where-is-mommy/submit-for-all-the-platforms

We at Banana4Life host our code in Github, so its natural to host the web export on corresponding Github Pages in the same repository as the source. Recently Github changed it, so Pages are not enabled automatically, when you push the "gh-pages" branch. You can now use any branch, but you have to enable Pages in the repository settings by selecting a branch and root directory.

Legendary Orbit Golf: Lessons Learned

trajectory.gif

Trying to solve NP-hard problems in realtime is not a good idea

Legendary Orbit Golf (https://ldjam.com/events/ludum-dare/47/legendary-orbit-golf) procedurally generates a small universe, which is a field of planets. In order to not look over clean and make the paths between the start and the destination hard enough to be interesting, we didn't want just spawn them into a fixed grid (quad or hexagon grids come to mind). Instead they should be spaced unevenly and the planets with various sizes should try to pack close together while never overlapping. This problem is commonly referred to circle packing, specially circle packing with different circle sizes. Unfortunately this problem is NP hard and kinda time consuming to find good solutions. The original game idea included a infinite universes, so that you can shot into any direction are guaranteed to eventually hit a planet. We cycled through a various approximation approaches to get a stable planet layout in a reasonable time, the final solution is fairly simple, but is unable to execute continuously, because it is too slow. So we are now just generating one finite universe on startup and that it. Trying various approximation approaches and trying to integrate them and debugging problems around it probably took 2 people over half a day of time.

Celestial mechanics are kinda complicated

The game is basically a gravity physics simulation. But instead of being perfectly realistic, we are making a game, so we have to bend physics. So a general n-body simulation would not fit the intended game play, as this would be to hard for the player to easily chose stable trajectories and for the game it would be too hard to procedurally generate a "fun to play" planet constellation in a reasonable time. Hardcoding a universe would take too much time too.

So we ended up doing simple 1-body simulations, considering the masses of planets and the spaceship vastly different, make the ship insignificant. Planets do not interact with each other gravitationally, they have a gravity well defined by a simple radius and these radi do not overlap, so the ship is only ever being affected by one planet, making a log of game logic and gameplay a lot simpler.

A surprise here was, that single precision floats are not precise enough to do even these simplified simulations, which lead to various inconsistencies between the displayed path (which was simulated using fixed time steps) and the actual movement of the ship (which is simulated using Unity's Time.deltaTime) causing all sorts of problems. Trajectories that were predicated to fling-shot around a planet suddenly spiraled into the planet, orbits where unstable when they should be stable, stable ellipse trajectories around a planet converged to a circle and so on. In the end this took some gameplay adjustments ("it's not a bug, it's a feature") and some more math (kepler's equations) to get consistent results. The simulation and all the problems around it took one person easily over a day.

Learned Lesson

Develop your ideas further early on, invest some more time into researching solutions and possible complications around your key problems (here universe creation and simulation). Toying around and cycles through various, possibly vastly different, approaches during the jam, possibly needing massive refactorings will slow you down and will introduce lot's of subtle bugs.

Is it me or does the blog kinda suck?

I see very little technical posts, time lapses, post mortems or other interesting blog posts about the jam entries.

What I do see a lot however: Lots of people spamming "please rate my game" posts.

This feels like abusing the global blog feed to circumvent the karma/coolness/whatever-it's-called system Ludum Dare lives by. Play games, rate games, write feedback and eventually your game will be played, rated and receive feedback.

In many cases games that get spammed onto the blog tend to have received lots of ratings, yet haven't actually given a whole lot, which is kinda sad.

Apart from the possible unfairness in the rating process, it also sucks that all the interesting posts that get written are quickly moved out of visibility. I have yet to find a way to search for content in anyway. There is no way to categorize posts, there is no search function on the site, no way to filter away advertisement posts.

Am I the only one annoyed by this?

Ludum Dare 48

HOWTO: Employing Minecraft Players as 3D Artists

  • Step 1: Get a Minecraft Community.

    Luckily we at Banana4Life also have a small Minecraft community called Cube Island (German), which was eager to help out!

  • Step 2: Setup a Minecraft Server with a flat world.

    Simply download the official Minecraft Java server and set the following values in the server.properties file:

    properties level-type=flat gamemode=creative

  • Step 3: Unleash your ~~minions~~ creative team.

    We placed a wall with the models we needed for the game, basically like a little kanban board.

All models build in Minecraft

  • Step 4: Get yourself a tool to export parts of a Minecraft world as 3D models.

    We used jMc2Obj which produces models in the Wavefront (.obj + .mtl files) format. The released version has a few issues with backface culling (Unity kind of requires it), so we fixed that. If you plan on using the textures from the export directly, make sure you use a texturepack you are allowed to redistribute. This is not the case for Minecraft's official texturepack. We were lucky again as a community member built their own texturepack. Alternatively you can also just use random blocks and skin them however you want in post-processing. Colored concrete blocks might come in handy here.

    If you plan on animating parts of the model, make sure the builders keep the sub-models separated or tell your exporter to generate a separate object/mesh for each block.

The exporter view of the Minecraft world

  • Step 5: Import the created models either directly into your game engine or into a 3D modelling software for post-processing.

    In Unity specifically we had to change a couple of settings on the textures and materials. Since we used a Minecraft-inspired texturepack we wanted to retain the blockyness of the texture and disabled texture filtering and enabled transparency from alpha.

    From your first model export, take the .mtl file and give it a generic name (we called it minecraft.mtl), since jMc2Obj generates a full material list (full as in it contains all Minecraft blocks) for each export.

    Before importing the .obj file, open it in your text editor of choice (it's a simple text-based format, so any editor will work) and replace the first line starting with mtllib by mtllib minecraft.mtl. This is important, so you can reuse the same materials for all objects later on, when you customize the material settings in Unity. When importing the .obj file into Unity, all materials will be embedded materials that cannot be changed. In order to change them, they have to be extracted using the "Extract Materials..." button on each model. The extraction will generate Unity material objects for each material used in that particular model, even if some already existed. You might want to delete the duplicates to avoid confusion later on (e.g. using find \( -regex '.* [0-9].mat' -o -regex '.* [0-9].mat.meta' \) -delete. This will also require you to remap the materials in the model using the "On Demand Remap" feature on the model. For naming you will need to select "From Model's Material" and you might have to play with the search option depending on where you placed your materials when extracting them.

    For the materials of non-cube blocks (e.g. plants, sugar cane, chains, ....) you might want to switch the material rendering mode to "Cutout" and for materials with transparency (all glass blocks, water, ...) you should use mode "Transparent".

  • Step 6: Profit

    Minecraft models in actual game

    If you want to see these models in action have a look at Drillromantik, the entire sources including the textures, models and materials are all on Github.

LDJam API misbehaving

I'm currently working on a new feature for the website of our LDJam team (https://banana4.life) that's using the api.ldjam.com in order to pull certain things. I'm only using /vx/node/get/..., /vx/node/feed/... and /vx/node/walk/....

While trying to fetch the feed of platform tags (the values of the "platform" dropdown when you add downloads to a game), I noticed a weird behavior in the API.

When I get the feed as one large request with the following link, I get the 89 unique node IDs I expect: https://api.ldjam.com/vx/node/feed/0/all/tag/platform?offset=0&limit=250

This can be reproduced with: curl -s 'https://api.ldjam.com/vx/node/feed/0/all/tag/platform?offset=0&limit=250' | jq -r '.feed[].id' | sort | uniq | wc -l

However if a get the feed in two chunks by doing the request first with offset=0&limit=50 and then with offset=50&limit=50, while still the same amount of node IDs, the list contains duplicates.

This can be reproduced with: curl -s 'https://api.ldjam.com/vx/node/feed/0/all/tag/platform?offset=0&limit=50' 'https://api.ldjam.com/vx/node/feed/0/all/tag/platform?offset=50&limit=50' | jq -r '.feed[].id' | sort | uniq | wc -l

The first command prints 89, the second command print's 57 (at least at the moment I tried this today).

I looked at the implementation of the API over at https://github.com/ludumdare/ludumdare to see what is going on. When I follow the code paths for the given argments (root=0, method=[all], type=tag, subtype=platform, offset=..., limit=50) and it seems to eventually end in a SELECT ... ORDER BY n.published DESC LIMIT 50 OFFSET ... query against the MySQL database, where n is the table with all the nodes.

From what I read about MySQL, OFFSET happens after ORDER BY, so the result should be consistent, however the behavior I see tells a different story.

Can anyone confirm the behavior and possibly even explain it?

Code path that's taken:

  1. Controller code behind /node/feed at the line it calls into the DB access code: https://github.com/JammerCore/JammerCore/blob/8f8e2366083fbd57865a7baa874b2d6305aa37af/public-api/vx/node.php#L481
  2. The DB access code at the point where the DB query is executed: https://github.com/JammerCore/JammerCore/blob/8f8e2366083fbd57865a7baa874b2d6305aa37af/src/shrub/src/node/node_feed.php#L514

Automating your Unity WebGL export on Github

We at Banana4Life develop our games on Linux. Unity on Linux most of the time works fairly well, but every now and then we have some issues during the WebGL export. This time the export kept failing due to an incompatible python version on our systems.

Instead of looking into how to fix the export on our systems I started looking into ways to export the game using a containerized version of Unity. It doesn't take long to find the Game CI project and eventually Unity's official docker containers.

When using the containerized version of Unity, you still need a license file for it to start. If you are a free user of Unity, which I'm guessing is probably most of you, you can either take the file from your local installation or use the manual activation process. Try not get too confused about all the different "howto" guides for building your project with Unity's CLI, most of them are probably outdated. Stick to the official Unity documention, it covers all the options pretty well.

Building locally in container, while working perfectly fine, was suddenly not enough for me anymore and I started looking into building the export and deploying the WebGL version using Github actions. Luckily the GameCI project also built a ready made Github action that is pretty well documented: https://game.ci/docs/github/builder.

If previously blogged about how we deploy our games: here and here. So we simply create an orphaned branch for gh-pages and put the jam submissions into separate folders in there. Likely, there is an action for that as well.

So with this workflow on Github we now have a fully automated build and deployment of the WebGL version of our game within 10-15 minutes after the push to Github. This almost feels like cheating.

Ludum Dare 51

Don't forget us Linux Users

I've posted this before and will do it again: Please publish for Linux or even better for Web.

I'm aware that it is not easily possible with all game engines and it might not work for every game, but many Unity-, Godot- and Unreal-based submissions can probably be easily exported for Web.

An added bonus since LD51 is, that you can directly embed your web-exported games into the game page. Checkout the announcement and the related guide.

My previous posts on the topic:

  • Some explanation for web exports in Unity: https://ldjam.com/events/ludum-dare/47/legendary-orbit-golf/publish-for-web
  • Guidance for the publishing process: https://ldjam.com/events/ludum-dare/38/where-is-mommy/submit-for-all-the-platforms
  • Howto automate WebGL publishing with Unity: https://ldjam.com/events/ludum-dare/48/drillromantik/automating-your-unity-webgl-export-on-github

Ludum Dare 56

Rating without Playing

Our game just passed the 20 rating mark. It's a multiplayer game at its core, but we made sure it's playable alone as well, since we figured that most of the time not enough players are playing to be viable as a multiplayer game during the rating phase.

As part of the multiplayer, since we've set it up as a peer-to-peer game, we also built a master/match making server that also provides somewhat up to date server and player counts, which the game client fetches to show the numbers in the main menu.

Shortly after the game went live we added a log line to the master server when ever the stats are being fetched, which under normal circumstances should always happen at least once when starting the game.

The log currently shows 11 unique clients that fetched the statistics I think we had 2-3 rating when we added the log line, which suggests that ~10 people (about half) never even started the game, but rated it.

Maybe some of these people have restrictive firewalls that blocked outgoing connections, but 10 people seems a little high for that.

Have other people some data on this? I've recently seen a JamBrain issue that briefly mentioned this problem. We never had issues receiving our 20 ratings in the past, but we are usually 3-4 people playing, rating and commenting games, but now I'm unsure how many people actually played our games.

Ludum Dare 58

Making a Game about playing Games

We found the theme "Collector" to be rather limiting, leading to mostly "obvious" game ideas about collecting things. Generally, we like to implement the theme with a twist, but we struggled to find a twist for this theme.

That is, until we realized that Ludum Dare is about playing games and collecting ratings, so in a sense ldjam.com itself fulfills the theme. So idea was clear: Build game for ldjam about playing and rating games of ldjam ... a meta game ... MetaJammer.

A while back I toyed around with ldjams API, so I had some basic code laying around to query the node graph around jams and games, which we took as a basis. The lack of documentation of the API and a bunch of (probably unintended) behaviors of the API still swallowed quite a bit of time, but eventually we got something working with a bunch of caching to not overwhelm the API.

The original idea was that you login with you ldjam.com account in our game and then, if you submitted a game to the current jam, your game would be permanently placed on a global hex grid with the camera centered on your game. You could then pan around the map to see other games, that were previously uncovered by people joining the game, or you can yourself uncover new games by clicking on empty tiles.

Unfortunately ldjam.com does not support OAuth or any other delegated authentication mechanism, such that we can perform actions in the name of the user without receiving the credentials of the user, so we ended up with a "login" that consists of merely providing your ldjam.com user, which we will then lookup using the API. We considered alternative authentication approaches, but they all seemed too convoluted and error prone to reasonably expect players to use them.

Since the ldjam.com API also doesn't provide details about what games you played and what rating you have given, we decided to go with our own rating systems in our game, persisted globally. You can rate games and assign awards. The awards will be shown as particles on the game grad for everyone to see, the rating can be seen by interaction with the game.

Games with web versions are uncovered with priority and games with a web version receive a button to immediately launch it in additional to the button leading to the ldjam.com for jam ratings and comments.

We used three.js with TypeScript for the first time, which worked ok for the most part, but we will probably not get back to it. The backend was written in Scala as part of our website. Source code is on github as usual. The game can be fully self-hosted by running the website in a stripped-down mode that only hosts the API endpoints for MetaJammer.