Turnament Devlog Nr. 24 - Playing Custom Levels


Now that I had an editor, the next step was to let people play what others have created.

This required an upload function. Originally, I planned on doing the server-side implementation from scratch using Perl and MySQL on my own server, but after talking to my wife, she suggested I try AWS with DynamoDB.

We sat down together to build a basic API using AWS for storing and retrieving maps. The end result looked like this:

Behind the API sat a lambda function (written in Javascript) that tackled all the database stuff. DynamoDB is simple, but requires some puzzle solving (or rather, very specific use-cases) if you want to tackle fancier stuff. Also, you are more aware about costs this way, which is good and bad, I guess. But I'm glad I did it this way. It's extremely easy to set up and I don't have to deal with a lot of the technical things that I dread. And if my own server ever dies, I can still sleep knowing that AWS will (almost) always be up.

Playing Levels

I created a new scene (PlayerLevels) and fetched the latest maps using Unity's webrequest and the new API that we built. And it didn't take long to succeed.

Playing levels required me to load the editor class for building/destroying a level, which required only a handful of adjustments. I also wanted people to "like" a map if they enjoyed it, so that needed a new API endpoint and a new database table.

Pagination of the maps was a different beast, but also took only a couple hours. (I don't want to load ALL maps at once, that would cost too much.) Now you get 8 maps and then you can click "more" if you want to see the next page.

I also added a "Random" button, in case you want to quickly play any map. Random in DynamoDB does not exist and is pretty tricky to get right, but I managed to get an acceptable solution working with a random "limit" on the scan and some local caching.

Performance

As I stress-tested the levels, I noticed that I needed to improve performance by a lot. A scene with roughly 300 seekers was causing the game to run at around 7 frames per second.

Here are a couple of things that I did to improve it and get it to ~80fps (on my laptop inside the editor):

  • The level border consisted of several individual PNGs, I think it was 200 or more gameobjects and sprite renderers. I made an image that looked just like it and copied it to every side, so now the game only had 4 images to display instead.
  • Caching the "transform" variable also seemed to help, but not by much. In my code it's used a lot to change an object's position, so everytime you write gameObject.transform.position, it gets the transform anew, and caching it helps a little bit for >100 objects.
  • Instead of having a FixedUpdate() on every seeker, I now handle it in one function. Apparently, there is an overhead if Unity has to check FixedUpdate/Update functions on many objects.
  • The three little antennas of the seekers were also separate objects. That's 3 antennas and three dots for highlighting, so 6 gameobjects per seeker. With 300 seekers, that's an additional 900 objects. I made one PNG that had all 3 antennas and dots in it, and simply changed the sprite to one where the dots are white, so now I only had one additional gameobject for each seeker.
  • Probably the biggest one: Every seeker had a CircleCollider2D to check if a projectile is in its range, so the game can be slowed down. Collision detection is very expensive with that many colliders (I noticed that in Catty & Batty with all the spirits running around in one level). I changed it so that the collider is only active when you're currently controlling the seeker, OR if there are less than 5 seekers in total on screen. If you have more than 5 seekers, the slowdown won't help you that quickly anyway to see which seeker is in danger.

There's still an issue with a level full of creators though, because they have individual "claws" that can open and close. They also highlight to indicate when their next shot appears. But I'll probably find a solution for that as well. For now, the changes above also help the regular campaign and endless mode to perform better.

Polishing

Levels now could be created, edited, uploaded, played and rated. Performance improvements should help with older hardware. Now it felt like I was free to add some polish and quality of life changes.

  • I added new sounds to the level editor and a new sound to when you select something on the splash screen. This was a lot of fun and added new life to the game (which is helpful for continuing to develop).
  • I added "Level Editor", "Player Levels" to the splash screen, and "Return to Title" in the start screen.
  • I fixed a few more weird issues with UI misbehaving. I think I got it all now.
  • I made the cursor smaller (thanks SaimizZ). Still needs an energy display in the UI somewhere.
  • I added Neco-Arc as a projectile for creators (this is an easter egg and will be hidden later), but it served as a test for other easter eggs I want to add.
  • Made sure the editor works well with controller.
  • Improved toolbar selection (selected prefab is highlighted now) (also R1/L1/mousewheel work now to cycle through them).
  • Save statistics to savegame data when you play custom levels. This made it possible to show checkmark and a medal (for succeeding) in the level selection screen. (Savegame data also supports Steam's Cloud, something i took care of in Catty & Batty.)
  • Fixed numbers 1-9 on keyboard not working correctly for selecting multiple seekers.
  • Repair seekers now only light up when they have enough energy.

I've also made another music track, which is track number 6 now. It will be used in the final level. Currently all music amounts to a total length of roughly 15 minutes.

The Road Ahead

The editor was probably the biggest technical hurdle I've tackled in quite a while. To be honest with you, there were several times where I questioned its existence and thought to just drop it. But I told myself I would continue, one step at a time. Sometimes only working one day per week and just resting and relaxing on the other days.

To see it all finally work has absolutely restored my motivation and ambition. I'm definitely seeing the light at the end of the tunnel now. So, with this new vision, let's take a look at the roadmap:

  • Publish the editor with the free demo: I want to gather as much feedback as possible before launch. This should happen rather soon.
  • Editor QoL: There are a few things on my list that will make editing a lot easier and more convenient (i.e. drag & drop, copying objects).
  • More music: I want to make three more music tracks, to have at least a total of nine.
  • Credits: I finally want to tackle the end credits scene.
  • Achievements: I had a really cool idea for this recently, namely a Database of things you encounter. Every entry is linked to an achievement. So the more you discover, the more you achieve. Looking forward to implementing this.
  • Hardmode: With the new level editor, it will be extremely easy to make hard versions of the campaign levels. These will be available in a separate menu, I think, or in the campaign level selector as alternate options.
  • Translations: As I said previously, I'm looking forward to adding at least the same languages as in Catty & Batty. I will work on this as soon as all the text is locked in.

And I think that sums it up for now. I have around 17 weeks left before launch. And I'm excited.

Make sure to wishlist Turnament on Steam, if you haven't already.

To be continued... 💎