FormulaProc – ProcJam

I’m creating a procedurally generating Formula One-style racing show! Check it out at https://formulaproc.com, here’s the story so far.

The Story So Far

After many years of wanting to, I jumped into ProcJam for 2021. There was always a reason not to do it, since it’s in December and I’ve commonly run out of jam-power by the time it happens. That was no exception this time, worsened by the fact that it happened almost back to back with the work I did for the Cultural Heritage Game Jam with Muyscamuy.

However, I decided to get off my head this idea that had been haunting me for years of making a spectator-sport kind of thing powered by procgen; not a game, but a kind of show around which people could build stories and create fandoms. It has had different shapes in my brain: soccer, cycling… but my renewed interest in Formula One this year made me think on a good balance between the level of abstraction vs. the amount of excitement that could be provided visually with such a simulation.

The marathon “Special Event” of Gold Medal Challenge’92 for the NES, another possible source of inspiration.

I had been talking for some weeks with Simernio and Gecko about this idea, and while we plan to have something more structured and elaborate in the future, I figured it could be a good idea to put the idea to the test at a smaller scale.

A clear inspiration was the F1 Visualized channel: “Formula 1 results and stats visualized using pixel art. Rewatch the latest races in minutes, without missing any part of it. Keep up with any of the drivers to see the race unfold from their perspective.“.

However, their visualization is much higher level (understandably so, since their idea is to compress a long F1 race into something you can watch much quicker), I wanted to create a somewhat abstract visualization of a race, not seeking to be a representation of the race itself but rather of how the race unfolded, leaving the players to fill the gap in usual roguelike fashion.

The main work in the implementation of the simulation happened from December 6 to 12 (when the jam ended). The jam encourages post-jam work for people not to stress (ha!), but we all know the entire point of a jam is to generate stress so that you produce something complete by a fixed end date, so I ignored that and pushed forward to have something solid by the end of it.

But wait, is this procgen?

I figure this may not be considered a “normal” procedural content generator; for procjam you’d more often expect something that creates things such as maps, level layouts, buildings, worlds, or maybe even something that awkwardly tries to come up with a written narrative or story.

What am I creating here? my intent is to create some facts, events that happened, and around which you can build stories and maybe even a community. And the main tools I’m using for this are physics simulation and artificial intelligence (both at a very, very simple level)

I shared the question in the procjam discord: can something like this be consider procedural generation? There was an interesting discussion about it, in general most people agreed the complexity or level of detail of the algorithm used to generate the content shouldn’t affect whether something is procgen or not.

“PCG is the algorithmic creation of content with limited or indirect user input”

from “Procedural Content Generation in Games”

As always, nothing is completely defined in the field of procedural content generation; but I would say that as long as you are generating content relying on algorithms and there is (pseudo) randomness involved (and you can be genuinely surprised by the results as the author), it IS procgen, and don’t let them tell you otherwise.

How it works

At the core of everything is an abstraction of the circuit based on its corners and the speed needed to transverse them safely; this is derived from the telemetry data of the drivers of recent races and is a bit loose because I’m not looking for a super accurate simulation but rather something that feels good enough.

The circuits are one-dimensional, and the racing is simulated based on both the stats of the cars affecting their acceleration, braking deceleration, gearbox efficiency, max speed, and the drivers having different reaction times, gearbox proficiency, and profile risk. There is a qualifying mode where the cars don’t interact and it’s all up to the performance of the driver and the car, and a race mode that adds more variables into the mix with the interaction between the drivers.

In order to provide the illusion of speed, some bars are placed on the track every 300m. In addition to this, an important aspect of the theming of each circuit is the name of the curves/corners, which are also placed as bars and provide visual feedback of the places where the cars brake.

I also added a kind of “minimap”, scaled-out version of the track, to make it easier to have a glimpse at the status of the entire race especially when the lead cars were too quick and left slower cars behind.

FormulaProc.com

The jam was just the start… while I delivered a complete simulation that could be parameterized with track data and would provide different results every time, I decided to have a single so-called “exhibition race”, happening in the Spa-Francorchamps circuit, be the published “results” of the jam.

But my plan was to build a complete series of this. I thought it would be cool to have the fantasy races happen on par with the real Formula One races, but the F1 2021 season had just finished (Go Max!), so I decided to start with the rebuild of the 2021 season, incrementally building the simulation quality along with the visuals and stuff based on the feedback of a hopefully growing community.

I set up a YouTube channel, a WordPress website, and a Twitter account for it, and started recording some more videos. So far I’ve done 4 races and posted about them in the official newssite. It still hasn’t had a lot of reach but that’s fine because every video is sligthly better than the last one, as I add new stuff to make the races more exciting!

The Portugal race, for instance, added non-critical accidents, allowing for much more varied stories that still felt believable, and the next race will feature some awesome soundworks by QuietGecko.

There is still a long way to go to make this feel more engaging; one of the things I’m already experimenting with is giving the drivers some visual shape so that people can relate to them; Simernio had the idea of using Unreal’s Metahuman Creator which has already yield some interesting results; for now we are just testing but it might be a good idea to make full use of it and render the characters in a fully controlled environment, as well as including more appropriate racing attires.

Biskup T., driver for the Queenscape team in 2021

As always, I’ll keep working on this until I run out of steam… hopefully when we catch up with the F1 2022 season we’ll have something more engaging and fun! in the meantime make sure to follow and subscribe 🙂

Distant Friends – js13k 2021

Js13kGames is a JavaScript coding competition for JavaScript Game Developers. The fun part of the compo is the file size limit set to 13 kilobytes. The competition started on 13th August and ended on 13th September 2021. The theme for 2021 was SPACE.

I managed to participate in the competition for the fifth time in a row, this year I teamed up with fellow game jammers and friends: mapedorr and QuietGecko, as agar3s went lone-wolf with his entry for the decentralized category.

We ended up creating a cute space exploration arcade game. You can play online here. Source code is here. There’s a gameplay video here.

My main inspiration, in the end, was “Tokyo 2020 Google Doodle Champion Island Games”, a fun little game made by a company called “Google” for this year’s Olympics. I wanted to recreate its feeling of relaxed quest-completing gameplay with challenging minigames.

The Story

I wanted to do something simple this year, but I also wanted to start as quick as possible so that there was something we could polish along the way instead of rushing it thru the end.

When the theme was announced I immediately thought of the idea of a space exploration sim; however I also thought it would be a common approach, given how easy it might be to exploit procedural generation to create infinitely expanding, boring universes with thousands of planets. I decided instead to have a more focused world, with unique planets, characters and quests, using procgen only for non-critical content (such as the stars in the background, and the random asteroid fields). Everything else was to be made manually, quest types would be sparsely reused, and tied to a hand-written story line.

The theme of cute visuals and audio was also something I thought from the start, maybe I just wanted to make a cute game for my daughter, or I thought the visuals could be easily adapted to vector illustrations without yielding quality, and the nature of the sound tools we could use for the jam worked very well for the type of audio that would support these visuals.

What Went Right

We ended up with a solid, finished entry with nice visuals and audio, and hopefully a fun and challenging experience with some interesting story moments.

What Went Wrong

While I still haven’t received feedback from the community, I don’t think anything went particularly wrong.

One thing I really wish I have had the time (and the bytes) to implement, was the additional game mode focused in building your home in a lonely planed, spaced away from civilization. The idea was for it to be the game mode you would unlock for the web monetization category. Maybe I should have implemented the roots of it along with the core gameplay, so that it wasn’t left out in the end (but then maybe that would have prevented me from filling the core content first, since we did run out of SPACE in the end).

The mobile controls could also be improved with more iteration on it, so that the players could shut down the engine more easily while turning the ship at the same time.

The DevLog

Day 1

The theme for this year was SPACE. I had an initial idea on my head of making a simple educational simulator, with a cute children theme, showing a journey from Earth to Moon of a multistage rocket.

I decided to use my entry from 2018 as a starting point, and started fiddling around with some “lander” physics and a simple camera that could go back and forth (Duet of Aces was forward only).

Day 2

I changed my mind about trying to make it physics based. Went in a more “arcade” route by removing gravity and also implemented open movement in all directions. Did some work in the rockets so they exploded after some time instead of only upon impact, as I thought the player would have to make his way thru asteroid fields and aliens in the open space by timing the rocket explosions.

Day 3

The idea now was for the player to travel to the planets to find the fragments of the song, (a multi-track song in the background would only play the tracks for the instruments you had found already).

To make this possible for the player, I added the navigation pointer at the bottom, and allowed switching waypoints.

As QuietGecko jumped on board, I also set up ZZSFXR, since there was music and sounds to be added.

The plan was to populate the empty space with aliens and asteroid fields. But aliens should behave more like animals than enemies, you had to push them away.

I also increased the resolution of the game to cover all the window (but this was eventually kind of rolled back.)

Day 4

I managed to integrate some test music and sound effects, including troubleshooting an issue with the ZZFXM web tracker exporter.

Day 5

I improved vector objects rendering, replacing my own path rendering functions from 2018 into using Path2D directly, which was a great step to allow more complex quadratic / bezier paths, as well as save a big chunk of code. I also did some foundations for the conversation system and drew some “test” objects (spoiler: some of them stood until the very end).

I used MiniSVGcreator by xem, it was great to produce optimized SVG paths (although by this point its usefulness was limited by its inability to save/load)

Day 6

Decided that the game would be about finding your missing friends instead of completing a song, and made a basic structure for this questline (hoping from planet to planet looking for them)

Also added asteroid fields serving as obstacle for your planet-hoping journey.

For the visuals, I added a parallax effect with cute stars and reused the pseudo 3d effect when turning from Duet of Aces. QuietGecko continued working in the audio.

Day 7

Sent a small patch to xem’s MiniSVGCreator to allow loading SVG data (to improve the art workflow), also added new music tracks from the gecko, and worked on the plotline to have an idea of how much text I’d be able to fit.

Day 8

I had to travel to fetch some hardware, but managed to do some airplane coding implementing conversations with multiple fragments, word wrap for text, and a lot of writing for the dialogs and plot (measuring how much is viable to add inside the limits, because text taxes you HEAVILY in js13k!).

Day 9

Added rocket particle effects, hints to friend locations, and city labels. Also integrated more test conversations.

So far I had a huge JS file with all on it, so I decided to split it into modules and modify the gulpfiles to merge them at build time.

Day 10

Asteroid mining with minirockets. Character portraits composition with test cat, dog, and fox.

Day 11

Integrated new SFX by the gecko and added mobile controls and scaling.

Day 12

Worked on quests (for mining and space racing) and speed booster powerups. The idea was that you would have to complete some quests to get hints to your friends’ locations.

Day 13

Implemented the “time trial” quest, including improving the obstacles track, and adding boosters to it.

Also worked further in the mobile controls, and added scoring to the game, based on how long it took you to complete it.

Day 14

Focused on a better user experience, by improving space navigation tying it to the current known location of friends instead of all the planets in the universe, as well as adding some onboarding and hints

Mapedorr jumped into the game designing some nice portraits, I did an initial test integration for them.

Day 15 and 16

Implemented space fishing and Galaxian fishing quest.

Days 17 and 18

As the end drew near, I called for friends to help test and did a lot of small fixes and tweaks in the mining and fishing, and also improved responsiveness for mobile.

We were already over the 13KB limit, so had to call for help on the js13k slack. I was pointed to ECT which was a last-minute life-saver.

SFX and Music were also revamped by the gecko.

404 Rhythm Not Found – js13k 2020

Js13kGames is a JavaScript coding competition for JavaScript Game Developers. The fun part of the compo is the file size limit set to 13 kilobytes. The competition started on 13th August and ended on 13th September 2020. The theme for 2020 was 404.

I managed to participate in the competition for the fourth time in a row, this year I teamed up with an elite team of game jammers and friends: agar3s, mapedorr and QuietGecko. We ended up creating a robot dancing game. You can play online here. Source code is here. There’s also a gameplay video.

The Story

This year I had two goals in mind: First off, I wanted to do something using a palette based sprite renderer, so that I could create a visually rich game under the size limit. The basic idea is, instead of drawing image files directly, have image data encoded to a more optimal (and lightweight) format and then using that data to manipulate what is displayed in the end (more details below).

The other thing I had clear was I was not going to jump on it alone; I had been talking with agar3s the months prior to the competition, entertaining the idea of joining forces for this year. Once the compo had begun we started brainstorming ideas and technical aspects and decided it would be nice to have a good pixel artist on board in order to make the best use of all the technical stuff we were doing under the hood, so we invited Mr. Mateo Robayo to join. He was a bit hesitant at first since it seems he didn’t enjoy his previous js13k participation a lot, but since this time he’d focus on the pixel art, he accepted to join.

As the first days passed, we considered doing some kind of action “roguelite” (ugh) with a robot exploring an abandoned factory looking for the correct URL, but as Mateo started coming up with art for the robots, and I implemented a basic “idle” animation with the parts we had, I thought it would be great to have a dancing game. We invited sound and music artist QuietGecko (with whom I’ve done a lot of work in NovaMundi and Emerald Woods), to create some cool tracks and SFX for the robots to dance.

In reality, I had a secret plan to have these 3 guys work back in a game together, but that’s not the kind of things you mention in a blog post.

I was able to do most of my contributions during the first week, luckily the guys were there to push through including the final days which required some big effort to close the scope, integrate everything and deliver an exceptional entry IMO.

The Sprite Renderer

There are many components on this entry, but my main contributions in the coding side I believe were aligned to what I was pursuing with my participation; I’ve always wanted to do a NES or GB emulator, this comes from back when I used to do some simple sprite ROM hacking, and reading about how graphics work in these kind of consoles. js13k seems like a perfect opportunity to use similar techniques for displaying visually rich content using as little storage as possible, and I bet I’m not the first one to think so, but I had never jumped into doing it.

So, with the fundamentals of the idea on my head, I jumped into it and together with agar3s we were able to put it together working great, this a summary of how it works (not that it’s something ground breaking, but I figure someone might find it interesting).

I aimed to support indexed 8 colors sprites, so we had each pixel take up 3 bits, and thus the entire pixel data (128×112 pixels) would fit about 5KB before any encoding or compression. We used a PNG file as the source of image data, thus allowing Mateo to work in whatever tool he wanted (I believe Aseprite is his weapon of choice); this file is then processed by a nodejs script which reads the image data into an array of bytes, encodes the array and exports it to a JS file used by the game.

Encoding the byte array was a bit tricky; my initial ideas worked but the string representations I was able to create ended up using special characters which wound up taking 2 bytes instead of one; as I thought on some workarounds for this, to restrict the symbols to safe 1 byte printable ASCII, we also did some research and ended up following xem’s latin-1 string trick.

On runtime, this data is decoded by the game, and then the renderer displays a sprite by crossing the data from a given palette of RGB values and the index defined in the sprite, thus allowing 24bit color depth display, without having to store the color data for each pixel.

In order for this to perform well, however, the pixels should be rendered “offscreen” using an image data buffer and writing to its pixel data directly, and then putting the entire image data on every frame.

Besides potential savings in storage space, this also allowed us to use palette animation effects (Mateo seems to have had a lot of fun with this) and to include variety in the game.

Ultimately, my contributions to this were mostly infrastructure work; the rest of the team did a great job extending and actually applying it into the game!

Soundworks

This being a dancing game, music and sound effects were bound to have an important part on it. As QuietGecko joined he struggled a lot first with the tools, trying out different trackers trying to make the JS conversion plugins work.

All I could do was recommending using Soundbox, the tool I used for my past two entries which worked great to me; however, everything changed when Keith Clark, the author of ZzFXM, released the beta version of ZzFXM Tracker. Everything worked perfectly from there, and as a plus, the code that was exported made a lot of sense and was much easier to work with.

I’m not sure what happened during the final hours, but in the end we had great SFX too. But you cannot expect less from the QuietGecko.

In his own words:

Having to convert .mod files to .js and translating synths was very difficult until Keith Clark released his tracker, although I experimented creating synths using his sfx creator and it ended up being very helpful. Also, having the issues with the instruments was a bit frustrating at first but it gave me a chance to try different trackers and strengthen the composing muscle which was useful when the time to rush came.

Additionally, having to use 64 note sequences seemed to be a bit too constraining, I wanted to test smaller sequences so we could have a procedural approach but it would be something to revisit next time.

I like that we ended up having a cohesive retro style sound even though I wished to have it more balanced mix wise. I really liked it. I would also have wanted to have a way to teach or suggest rhythm or patterns to players other than beat subdivision.

QuietGecko, September 2020

Discarded Gameplay Ideas

As I mentioned, I could not contribute a lot of code after the first week… besides being stuck with a lot of work in other projects, I also felt kind of stalled regarding the game. In spite of being the one who proposed we went that route, I had never made a rhythm game, and I didn’t think I could contribute a lot to the design so in a way I decided to see what the rest of the team could come up with.

However, one of the things I experimented with after seeing how the game was evolving, was making it so that instead of pressing sequences of random (but varied) letters, you had to do some patterns that would be translated into special moves into the game and give you bonus points. The idea was you would find out about these moves from your opponents, and would replicate them using your individual robot-part movements.

While it technically worked, it was pretty hard! almost impossible as the BPM went up. So we decided not to integrate it in the end, may be it could work for a different kind of robot dancing game.

What Went Right?

Teamwork worked great but this was no coincidence. We are no strangers to game jams and we have worked together in many projects, so everybody knew how to contribute and we also let the project evolve organically with all our ideas. Again, it was great to know the project was going to be completed because the guys were serious about taking it to the finish line.

Besides making the pixel art for the game, Mateo ended up coding a lot of the GUI, as well as the palette animations. I already mentioned QuietGecko’s contributions, and agar3s…. well, let’s say besides contributing a lot of build, tooling and engine infrastructure, he made sure everything worked together and extended the engine towards what we needed. I hope he manages to write down his experience so I can link it here.

What Went Wrong?

Now, if we evaluate the end result, maybe we didn’t really integrate the 404 theme a lot into the game; it ended up being a shallow aspect, when you miss a beat you get the 404, if you don’t find your rhythm, you fail.

Onboarding was also not great, I didn’t like the key layout a lot (D, F, J, K ?), but I was told that’s what people uses nowadays especially on laptops. How the bonus mechanics work inside the game is also not very explicit, but on the other hand it can be deduced after some game play so I don’t think it’s a big deal (as it was in Lost in Asterion).

Overall, one could think if we had a clearer vision of the game design from the beginning, we could have integrated the theme better, and polished the mechanics, but I actually feel the journey of exploring different gameplay ideas was a good experience, and was in a way more fun and exciting than just following a set plan.

The Future

This is one of these rare jam entries for which I don’t feel there needs to be any further development; not that it’s a perfect game, but I believe it’s just as good as it should be for a js13k entry (If anything, we could add support for mobile, and that would not be a big deal).

Paladin’s Quest LCD

20180509_183241

An entry for the LCD Jam, about 8 hours dev.

JavaScript + Phaser as usual for great quickness. Pretty happy with results, nice feedback received, may develop further afterwards.

Play online here (Source code here)

Screen Shot 2018-05-07 at 7.51.39 AM

The game is a simplified dungeon crawler, classic style roguelike, which emulates (loosely) a LCD game display.

There are 4 different enemies: Headless, Floating Skull, and Phantom. Scattered in the dungeon you will find strong weapons and replacements for your shield, you will need these to survive!

Each level is 3×3 rooms, you must find the exit which is located in the middle of one of the 9 rooms.

Screen Shot 2018-05-07 at 7.51.11 AM

The LCD shapes (i.e. the different parts of the paladin) were made by Giovanny Ramirez, the wiggly dungeon room and the “brick game” frame I made myself.

1884 – Golf over Africa, LudumDare 41

The theme for the Ludum Dare 41 was “Combine 2 Incompatible Genres”. I’m pretty familiar with genre mashup, and I accepted Jim Shepard‘s challenge to jump in.

As usual for the LudumDare, I wanted to do something different than what I always do. That usually means doing something more accessible to the casual public, as well as ditching pixel art, and including real-time stuff and animations.

Here’s what I came up with: (Play online!)

golf

1884, the European superpowers have met to decide the future of the African continent… now their leaders face each other in an Open golf tournament to divide the land between themselves!

Screen Shot 2018-04-24 at 7.01.56 PM
Title Screen

I went for a combination of a Golf game with territory based war game (think Crusader Kings / Europa Universalis, or maybe RISK). It’s made for 2 to 4 players who take turns to play, the first country to occupy 10 territories wins the match.

In order to try to occupy a territory, you must land your ball on it, every turn the player decides the direction and power of his shot. The outcome depends on the stats of his country.

You can also invade other player’s territories, where the success of the invasion depends on the Military stat of each country. Countries also have other 2 stats: Logistics affects how far your shots will fly (with Great Britain being the best on this) and Leadership affects how accurate your shots are.

Game Screenshot
In-Game

Since I knew in advance my time would be extremely limited during the span of the compo, I went for my usual toolkit: Phaser2 + ES6. All art was done on GIMP, basically a lot of repetitive work extracting the different countries from a colonial map of Africa, and some flags and UI stuff.

Africa-colonial1
Colonial Africa

Due to the “weird” square and “high” resolution of the game (as in being about 800x800px, high for browser games standards) ended up doing a lot of work to make sure it would display fine on browsers with a smaller window height (you’d be surprised this is still very common in 2018) as well as the fancy retina displays which always mess up with scaling calculations.

This one went from ideation to fully complete product in less than 12 hours. I’m really happy how it turned out. Here are some areas where this could be expanded in case I work back on it ion the future:

  • Adding a “zoomed” version of the territory the player is doing his shot from. And an animation of the country leader shooting-
  • Making the viewport landscape and adding scrolling (and maybe a scaled map)
  • Enhancing the appearance in general.

Rogue Program – Github GameOff

(I must have posted this some weeks ago, but I’ve been a bit busy!)

Some months ago, a conversation on twitter inspired me to make a game inside a character based UI from the 80’s…. for some reason.

twitterChallenge

I decided to go ahead and try to implement the idea as an entry for the Github Game Off, whose theme for this year was “retro” (very fitting). Since github provided the location for the Roguelike Celebration (and was publicizing the jam at the event), I felt more encouraged to participate.

TitleScreen

In Rogue Program, you are a character living inside the Alameda Video Rental System. The Rogue Program has activated and is turning the characters of the system into vicious monsters. Adventure through the different modules and menus of the system looking for clues and tools, while learning what has happened to the outside world.

rp1

I went for a P1 phosphor green monochrome 80×25 CP437 characters appearance, using a fixedsys font and unicodetiles.js. I used my JSRL boilerplate as a foundation but despite looking as a traditional roguelike, the game is more of a simple cRPG with fixed locations and plot (REXPaint by GridSageGames was a hugely helpful tool to draw the maps). I think however that it should provide a fun time and a decent challenge.

rogueProgram

Source code is available at Github. Play now at itch.io and don’t forget to report thy feat if you manage to win 🙂

Postmortem: Lost in Asterion – js13k 2017

Lost in Asterion is a game I made for the js13k 2017 contest, you can check it out here!

I decided to write one final piece of text about my first participation on the contest. I already described my journey in detail through the 19 days of development here, here and here; but I wanted to record some things earned and some lessons learned which may come in handy for other people or myself in the future

lostInAsterion2

My Story

Whenever I participate into a game jam or contest, I try to ask myself what is my motivation:

  • Learn a new language or tool
  • Create something cool
  • Win the contest prize

This was the first time I participated on the contest so I started a bit clueless, knowing not what to focus on.

Later, I set my goal on trying to create a FULL game, something that you would not believe was contained within 13 kilobytes. I was inspired by Aquaria… could I create a similar experience within the boundaries of the contest? besides the size limit, there was also the time constraint: One month of work, with very limited availability due to some other more important personal projects (it was around the release date of a human being I created). But I jumped in.

In the end, I think I succeeded on that (which is great!) but I cannot deny the results from the judges, which put the game pretty down the list, were pretty disappointing for me at first.

Screen Shot 2017-09-30 at 10.52.14 PM

Later, after giving it some thought, I understood it made sense… there were many entries this year, some of them really good, and when I created my own I didn’t even consider the judging process that was going to take place: I didn’t really aim to make a good impression on the limited time the judges have to check the entries.

Giovanny Beltrán shared some tips, and my opinion in general terms is you need something that grabs the attention of the judges in the first 5 seconds: animations, music, an inviting environment or an intriguing setting.

What went right

A huge world

I managed to create a BIG world, thanks to a couple of things: The cavern level generator which used Voronoi diagramas and Celular Automata, and the compact map format for the 2 areas with fixed maps.

I’m glad one of the jurors got to experience EXACTLY what I was going after! I wanted the players to actually try to make a map of the world, in paper, somewhere. This is why I didn’t include an automap. I followed a similar design on Stygian Abyss, with less exciting results.

A full run through the game may take over 2 hours (may be even more) if you are playing for the first time.

Breaking the pixel art mold

I created another game without using pixel art (a personal goal I’m trying to go after), instead all graphics are vector based. Everything is represented using geometric shapes: the background, the player, the enemies, even the bubble particles.

wp-image-1750981584

Atmosphere and Feel

I managed to create a believable atmosphere using the symbolic vectorial art with a color palette which worked pretty well, as well as the limited sound effects and the textual messages that made up the plot.

Greatest Challenge: The 13k barrier

It hit me REALLY hard and I had to spent a lot of time doing both technical tricks as well as design choices of what to keep and what to take out. I didn’t really expect to have to battle this hard with it since I wasn’t using any image files just to make sure I could have as much space as possible to build the world and the story, but it happened.

The main causes for this were the inclusion of the Voronoi diagrams library (used for map generation and background graphics) and jsfxr (Used for the 2 sound effects in the game).

The first one was completely necessary (no way to remove it) and very hard to reduce size other than trying to optimize the module structure and playing around with the uglifier. I put a lot of work on it with minimal effects over the package size.

As for jsfxr, there was little that could be done other than deciding whether it was worth keeping it or not. Because of the goal I set myself, I decided it had to remain, and I was gonna try to make the most out of it. (In the end I’m not sure it was worth it, since I could only keep two sounds)

Since I couldn’t do much to reduce the size of these two dependencies, I had to start optimizing my code (which was fineΩ) and cutting content (which was painful!)

What went wrong

Removed critical content

I cut some critical training / instructions as well as some interesting plot. People had trouble understanding what the “Drill” was for (and of course instinctively tried to use it to cut the rocks), and the plot was a bit too light.

Looking back at it, I think a better choice would have been removing some type of enemies, or even one of the fixed map areas.

Use the arrows, Z to drill
That’s about all the instructions given to the player

Ran out of time

This is because I didn’t have a clear idea on what to do since the beginning.

However, I’m not sure I’d say that was something bad or it could have been avoided… I think sometimes it’s ok to start with a general idea (2D cavern exploration game, vector art) and then let it evolve.

In any case, I spent a lot of time working on something that didn’t end up in the final product: The “collisions” with slopes. That was educational but would have been better invested on playtesting.

No Playtesting

Due to how the time frame ended, there was no playtesting at all. I was lucky that the game was fairly stable and I only had to submit a single patch, however I missed some details which would have been very easy to correct and could have left a better impression:

  • Scaling to use the whole viewport / going full screen
  • Removing enemies from the starting area so players could read the instructions peacefully and building a better ambient

The Future

This is not the end of the story for Lost in Asterion… I plan to make it evolve into a more complete game, keeping the core design but adding better sound effects, music, a complete plot (based on the original one which was chopped up), cutscenes, boss battles and an infinite exploration mode. More info soon!

Also, some things I want to do next year:

  • An arcade game bringing full action from first second of gameplay
  • Complete music track

Lost in Asterion – js13k 2017 – v0.2 released – final compo update

This is the final update of the development of Lost in Asterion for the 2017 js13kgames contest. I managed to create an interesting exploration game, and I’m pretty happy with the results (check it out here). Giovanny Ramirez created a cover art for it and it’s amazing

Following is the journey thru the last 10 days of development. You can see the previous days here and here.

lostInAsterion2

September 2 – Added enemy support with a single kind of enemy.

Enemies (actually, general “entities”) are updated once on each iteration of the game loop, they have their speed affected by gravity, are checked vs collisions with the world objects (in which case they are completely halted).

Enemies have a simple AI where they check if player is close enough. If that’s so they’ll calculate the direction to the player (in simple manhattan terms, not degrees) and then propel towards the player using they acceleration in x and y.

They are also drawn on each iteration of the game loop, scaling simple geometrical operations based on their size, around a central point.

September 3

Attack enemies using bubble beams: Every time the player presses ‘z’, a bubble beam is created in the direction he is facing. The bubble beam is a group of bubble created in sequence within milliseconds between each one, all originating from the same spot and in the same direction (with slightly different speed).

On each update cycle, entities are checked for collisions with these bubbles, in which case their health is diminished and they are drawn in white for some millis to show they have been hit.

Added sound effects using the jsfxr library. At this point I wasn’t still worried about size. I just added it and used it for movement. The way it works is providing the library with a set of parameters mirroring the configuration of the asfxr player, and they are played using the web audio API.

Also added support for plot messages tied to positions within the world fragments

September 4: Designed and added more plot. Designed the overall world map too.

September 6: After wondering how I’d tackle some variety on the maps, I decided to try to generate then procedurally with a simple “rogue” like 9 interconnected rooms algorithm.

The way it works is a random size is defined for each of these rooms, and some of them may be discarded. Connections are then defined, and then it’s drawn.

While it’s a simple generator, in the middle of implementation I noticed: a.) it was taking too much time to implement, b.) it was eating quite a bit of source code and c.) it wasn’t really worth implementing it since I wanted to have fixed maps in the end (I intended to seed the map generators)

So, I discarded the initial idea and went instead for something completely different. I rendered the maps in a spreadsheet and encoded them as bytes. The map is represented as a bitmask of open/closed spaces, I chunked it in 8 spaces long fragments, and encoded them as an hexadecimal byte representation.

Screen Shot 2017-09-16 at 4.29.19 PM

This allowed me to represent a 24 spaces segment in 6 bytes. The full map for the first temple section, which is 18×24 sectors big, is represented by this string: FFEFFF398FC1018781011C800185C1458DEFFFFDEFFF8187FFE184000084000080FF0184FF0184FF01ECFF03EEFFFF87FF0780FF87FF

When the map generator is creating a fixed map sector, it decodes the String into a boolean mask, and generated solid blocks based on the desired scale.

I used this technique to create the map for the Temple.

September 7

I had a corporate leadership training during the morning. I designed some creatures while waiting for it to develop. All of them using basic shapes.

I was running out of time and the world was not yet ready, so I focused on trying to complete it.

I added some sections requiring the player to have a given orb to pass thru, else player’s speed was drastically affected. This acted as a simple “plot device”, making players have to transverse the map in 3 different “segments”, giving the player a sense of non-linearity while still having some strict control of the game flow.

Added more world content by configuring the map generator for Volcanic Rift (simply using fiery colors for the background) and creating another fixed map for the City Ruins (thus capitalizing on the code added to handle it on the temple ruins).

Having the world definition in a good shape, I continued by adding enemies generation on demand. As the player moves around a sector enemies will be constantly generated off screen up to a given limit.

Finally, I added Game Over flow, the game loop will check if player is dead and render a different screen instead.

September 8

One remaining piece to make the game playable was having a better victory condition, so I worked on adding an end boss. Also started working on support for different kind of enemies.

September 9: Rendered different creatures types based on the designs I had made. Used simple canvas 2d content drawing directives such as fillArc, as well as paths being stroked and filled.

September 10: Assigned enemy level / difficulty based on sector (harder ones as the player progresses).

Also made some missing powerups work: Made the bubble beam work only if the player had the Orb of Verra Kera, and hull recovery only happening if he had the Orb of Gabrielle.

Also added the “title screen” of sorts, and continued polishing the “plot”.

September 11 – Begun the quest to reduce space. Started by questioning myself whether I wanted to keep (and may be even extend) the plot and content OR if I’d rather work towards keeping sound support. I decided for the latter. Started having 2.76 KB of compressed code to take away.

This was extremely painful, some of the things I did were:

  • Ditched the original minified version of the Voronoi library. Instead included the original source code into the minification flow, and removed some parts which were not being used.
  • Move code into data, placing redundant code sections into methods executing batches of operation based on arrays of parameters.
  • Change formatting of definition of function prototypes using Class.prototype = { fn: {} } instead of Class.prototype.fn = function(){}. *
  • Replace all const with var*
  • Reduce HTML infrastructure to a bare minimum, no css nor styles, very plain index.html with no HEAD section or encoding declaration, etc.
  • Remove “use strict” from all modules
  • Shorten plot and ending messages.
  • Move “private” functions outside the functions prototype (effectively allowing uglify to mangle their names)

For the things marked with *, I found of they didn’t really help much in the end since zip compression took care of repeating Strings pretty well. The only thing that helps is actually removing content.

Additionally, I adding the knock back mechanics to make “combat” more interesting (and making the game less hard by allowing player to tackle enemies away). I also added the drill as a default “melee” weapon before acquiring the sonic beam.

September 12 – I was running out of time and hadn’t done proper testing so I released a first version for public testing.

I worked hard to reduce the package size more and more, doing the following:

  • Use the same SFX for the movement fans and for the drill
  • Modularize the Voronoi library. Extracted the different classes used by it on different modules, hoping to refactor them to move private functions from the prototypes into module scope functions. I actually had to roll this back afterwards since the additional module management increased size, but it was helpful to simplify the modules individually and prevent introducing bugs into an unknown code base.
  • Configure uglify to mangle properties starting with underscore (both functions and attributes). This was extremely helpful! I proceeded to use it mainly on the Voronoi library.
  • Cut more plot.
  • Remove unused error message Strings.
  • Ditch the minified jsfxr file and include the already minified source into my own minification process.
  • Merge modules into single files, making the code less readable for now.

Went to bed with 50 bytes left and the plans to finish thru next morning as well as doing some testing…

Then, while already on bed around 1AM, decided to check the deadline and found out it was 13:00 CEST, not Central American Time as I initially thought. That meant it was happening in less than 5 hours. The panic.

There was no way I was going to lose all the time I had invested, so I got up and finished the adventure by completely removing two kind of enemies and cutting the plot text even more.

Lost – js13k 2017 (Update #2)

There’s about one week left for js13k 2017. As usual the jam has sequestered my mind, draining my processing power, thinking about it all day long how to push it further.

Here’s the story from last update, reconstructed from twitter + the git log. It’s been a fun journey so far.

August 19 – Added background stones using Voronoi. Keeping up with the goal of not using pixel art, got the idea from a shower curtain. May need some additional details to make them look like rocks without using textures.

Screen Shot 2017-09-02 at 11.25.29 AM
Walking around alien caverns

August 22 – Infinitely spawning maps, generated on the fly. This was tricky but needed in order to not be completely irresponsible with memory. One of my goals was to create a huge spawning world within the 13k limit, that of course was going to involve procedural generation (but I intend to keep the world fixed by seeding the pRNG properly). For this I’m dividing the map in 4 quadrants, and based on where the player is I clean the opposite sector and generate the closer ones.

August 23 – Implemented a CA module for Voronoi diagrams and used it on terrain and background to smooth them out. I used the output of the Voronoi library and post processed it adding the neighbor sectors. The CA module I made allow simple rules as in “For a cell of given type X, if there are (more/less) than N cells of type Y around, change its type to Z, P% of times”.

Also added a jetpack for easier exploration. I still didn’t have a clue on the theme of the game, was thinking it was may be going to be a space explorer ala Samus Aran.

August 27 – Added complete zoom support for the camera object (still thinking if it’ll be used in game, for now just using it for debugging purposes). All positions and dimensions are scaled based on the zoom factor, and then repositioned based on the camera position (which right now keeps synced with player, but may change that in the future)

August 29 – Worked hard trying to add support for smoothly walking on the slopes. I almost got it but there were some edge cases where the player would become stuck, or go through the slope and into the rock.

The way it worked was by tracing a line between the player’s hitbox center and an imaginary point below representing the gravity drag. Then I checked for the intersection of the polygon sides vs it to see what side was colliding with the player. Previously, I calculated the slope of all sides of the polygons. Then when the player was walking against the polygon, I changed his y position too, based on the slope.

One of the issues was faced was that when walking between stones the player may sometimes hit the wrong polygon side (one inside the rocks) .

August 30 – Figured out the issues with slopes were going to eat up all my time and I wouldn’t ship without them working perfectly. So decided to change theme to underwater caverns.

Tweaked the physics to allow the player to “float” (weaker gravity) as well as removing jumping since you can thrust upwards anytime now.  Initially made a “radial” movement schema where you could rotate and then thrust forward, but then decided to simplify it so you just move in the direction you press the key to. Also changed collisions so you’ll be stopped completely when colliding with anything (removed slope calculations), but they were still a bit buggy at this point.

Screen Shot 2017-09-02 at 11.31.59 AM
Floating in the caverns

August 31 – Up until now, the player had just been a colored squared so I decided to jump into changing it to what it was going to be in the final game. I considered several options from the beginning but since I was not going to use pixel art, adding humanoid characters with animation would have been quite painful, taking a lot of time and I wasn’t confident the end result would look good since I lack the skills. So, give that I had switched the theme to underwater, I decided to use a rigid body (a vehicle).

Did some research on deep exploration vehicles (Bathyscaphes) and in the end settled for a fantasy bathysphere. Also went ahead and added some “bubble” particles, generated from the sphere’s fans depending on the direction the vehicle was moving. Then as a last touch added a simple emulated head light, using a semitransparent white triangle.

September 1 – Started by doing some needed upgrades into the boilerplate project, mainly replacing using the uglify module with uglify-es in order to be able to use ES6 features in the source code.

Then I finally got into fixing the collisions, so right now I’m checking the intersection between the four sides of the player’s “future” hitbox vs the nearest stones, and calling it a collision in case there’s any intersection. I’m also keeping the case of projecting a line from the hitbox center to the future center and checking for intersections, to prevent cases of high y acceleration by gravity. It works pretty well now.

Did some cleanup using jshint and upgraded some parts to ES6 syntax, just for easier maintenance in the future and for the code to look better too 🙂

I got my hands into a more serious high level world layout generation, I designed the fixed world map which is composed by different sections, each section has a given type (which defines the parameters for the sector generator to build the map) as well as expected connections with neighbor sectors.

After the Voronoi diagram has been generated, the generator marks some of the sectors as special types: Unbreakable stones at the borders of the sector, and fixed open spaces representing the connections with its neighbors, these represent the constraints of the sector in order for it to fit the overall map, the CA rules don’t affect them.

I defined the parameters for some of the sector types: The Gate, Caverns, Open Areas, Farmlands and the Darkness Abyss (In which you can only see your headlight)

darkness
The Darkness Abyss

Then I added The Gate and the orbs needed to open it. In order to win the game you have to explore the depths, find the fours orbs and come back to open it, without getting lost in the process.

I also resized the viewport to 800×600 (was 400×400), and modified the physics a bit by generating a bit of “lift” with the vertical movement (akin to the sphere having some kind of “fins”, I guess)

lost
The Gate

Coming up

In order of relevance seeking to make a fun game

  • Enemies
  • Powerups
  • Parallax effect for background
  • Vegetation in the foreground
  • Enhance sector connection
  • Temple generator
  • City Ruins generator
  • Volcanic Ridge generator

 

Lost in the Underworld – Day 1, js13kgames

Alright, I decided to participate for the first time on js13kgames!

The plan is to create a cavern exploration game with a huge world and multiple paths on it, where the player has to find treasures and powerups. I also hope this series of blog posts is more informative and useful than usual.

The idea is to do terrain generation on the fly using Voronoi diagrams and Cellular Automata, also I won’t use pixel art but instead vector graphics (at least for the terrain).

After checking some of the options in the tools page, I decided to use Florent Cailhol’s JS13k Boilerplate. It is probably the simpler starter project there… it has some game loop logic, seedable RNG and gulp scripts for packing and minifying. It also comes with a sample simple implementation for physics.

I started adding keyboard support so you could jump and move around.

const pressed = {};

module.exports = {
	init: function(){
		window.onkeydown = function(e) {pressed[e.keyCode] = true};
		window.onkeyup = function(e) {pressed[e.keyCode] = false};
	},
	isDown: function(keyCode){
		return pressed[keyCode];
	}
}

Also did some foundations of the “physics” system based on the original, since the terrain will be irregular, what I’m doing for the collisions is checking if the future position of the player will be located inside one of the polygons. I used the “inside” function from James Halliday Point in Polygon repo, an implementation of the PNPOLY algorithm. There’s still a lot of potential optimizations to be done.

stones.forEach(function(s){
  if (e.dx != 0){
    if (e.dx > 0){
      if (inside([tx+e.w,ty+e.h/2], s.vs)){
        hCollision = true;
      }
    } else if (e.dx > 0){
      if (inside([tx,ty+e.h/2], s.vs)){
        hCollision = true;
      }
    }
  }
  if (inside([tx+e.w/2,ty+e.h], s.vs)){
    vCollision = true;
  }
}

Had to add a special case for high acceleration caused by gravity, which would make the player go though thing barriers because the updated position would just go through it. For this one I’m checking if the line traced from the current position to the future position intersects the polygon, based on a stack overflow response by Dan Fox.

if (e.dy > 100){
  //Prevent falling through thin borders at high acc
  if (polygonIntersects({
    a: {x: e.x+e.w/2, y: e.y+e.h},
    b: {x: tx+e.w/2, y: ty+e.h}},
    s.vs
  )){
   vCollision = true;
  }
}

Added simple camera support, centered on the player, for this I have a camera object whose position I affect along with the player’s. Then I substract that position from the world position of all objects when it’s time to draw them, to translate them to viewport coordinates.

js13k-2

Then I added super simple Voronoi map gen using Raymond Hill’s JavaScript Voronoi, it adds quite a bit of weight to the package but works pretty nice. I may have to slim it down for the final dist.

js13k-3.1

For now, I’m just randomly picking Voronoi cells, next up will use CA for the caverns to look less random.

var voronoi = new Voronoi();
var bbox = {xl: -300, xr: 1450, yt: 0, yb: 3550};
var sites = [];
for (var i = 0; i < 450; i++){
  sites.push({
    x: rand.range(bbox.xl, bbox.xr),
    y: rand.range(bbox.yt, bbox.yb)
  })
}
var diagram = voronoi.compute(sites, bbox);
const stones = [];
diagram.cells.forEach(function(cell){
  if (rand.bool())
    return;
  let vs = [];
  cell.halfedges.forEach(function (halfedge){
    vs.push([halfedge.getStartpoint().x, halfedge.getStartpoint().y]);
  });
  stones.push({vs: vs});
});

Navigating around the map made evident that my physics system still needs a lot of work. I will post it here once it’s more polished so it can be useful for someone.

I found out the core of the RNG module of the boilerplate isn’t working, so made it use Math.random instead for now. It also seems the current gulp tasks don’t work well with some ES6 syntax, I’ll take care of that later.

Current package size is: 7.13 KB