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.

Velocity Partners Hackaton 2017

The company I work with organized a hackaton. I was hesitant to participate (too many projects already underway) but in the end decided to jump in with a turn based stratategy game I’ll write more about in a future post.

In the meantime, here are the other projects that participated. It was a single day event, but even so there was a pretty good level all around:

ExtrasApp: An application to connect extras (actors) with producers looking for them. The actors sign up and fill their profile, the users can then search based on what they need. They used neo4j, kotlin and reactnative.

Park.me, One of the two entries for parking space optimization. This one focused on the user experience, allowing people to register and free up unusued spots for a given day, and building a product any company or shared parking space could use. They used Angular, bootstrap, sailsjs, nodejs and mongodb.

LoRegalo, a website where people can post things they want to give out, and then pick who gets to keep them, from the people interested on it. They used typescript, bootstrap 4, auth0 expressjs and nodejs.

API workflower, who ended up as the winners of the event, worked on an API integrator. They created a HATEOAS based API which you could use to register APIs (using Adapter objects) and then defining workflows that used these APIs. Then you could trigger these workflows using an operation to transparently connect with different services. For their proof of concept they tweeted a quote obtained from a service. They used nodejs and expressjs.

VP Parking, The second parking solution project, using firebase, angular, nativescript and golang. They focused on designing an algorithm to allocate the available spaces.

Queen of Westeros, made by yours truly and Paranoia Viral. I’ll post detailed info about it tomorrow! 🙂

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

OpenArthurianX6: Design and Planning

I don’t think there’s a perfect way to approach planning this kind of project, so we’ll shoot for one, then once we have done some iterations of it we’ll evaluate and see what’s the best way to continue.

The first iteration of the engine we are looking forward to have is having all basic systems working, keyboard only, desktop only running in a browser.

Capabilities

One facet we are using for planning are actions the player can do

World

  • Move around the map
  • Pick up an item from the map
  • Examine map
  • Examine item on world
  • Examine mob
  • Read book or world feature (signpost, plaque, etc)
  • Examine world feature (find secrets)
  • Open and Close doors
  • Doors with keys
  • Doors opening with buttons / levers combinations

Dialogs

  • Talk with a NPC
  • Asking a NPC to join the party
  • Talk with a Party member
  • Ask a Party member to leave the party

Party

  • Check the status of a party member
  • Set the Tactics / Manual for a party member

Inventory

  • Check the inventory of a party member
  • Drop an item on the map
  • Move an item on the inventory to a container on the inventory
  • Move an item on the inventory to a party member
  • Move an item on the map to a container on the map
  • Check a container on the map
  • Pick up an item from a container to the inventory
  • Examine item on inventory
  • Use item on inventory

Combat

  • Enter and leave combat mode
  • Attack an enemy within melee distance
  • Attack a far away enemy

Engine Aspects

A second facet of planning corresponds to some features of the engine which may or may not be related to the player actions.

Maps

Moving around the map is a capability, but managing and displaying the maps themselves is an important aspect of the engine.

  • Overlay layers
  • Map transitions
  • Multiple stories
  • Day and Night Cycle

Mobs

  • Follow player
  • Select action in combat mode (AI)
  • Select action in peace mode (AI)
  • Schedules
  • Action scheduling in Peace mode
  • Action scheduling in Combat mode

Use Item effects

  • Recover HP (% or fixed value, mob or party)
  • Recover MP (% or fixed value, mob or party)
  • Recover hunger (% or fixed value, mob or party)
  • Enter music mode (Play instrument with keys 0 to 9)

Use Feature effects

  • Light / Extinguish
  • Open or close door
  • Set puzzle flag

Use mob effects

  • Milk cow

The Future – Other iterations

Capabilities

  • Make camp
  • Board a vehicle
  • Move around in a land vehicle
  • Move around in a sea vehicle
  • Move around in a air vehicle
  • Repair a vehicle
  • Attack and object on the world
  • Ride mount

The Ancient Art of War at Westeros Part 2: The Queen of the Iron Throne

The second video for the SlashBit Retro Cinema is up!

While I didn’t invest as much time on this one as I did on the Castlevania one, this one has a long story going back to 2015 when I started working on the map hoping to have something like the video ready before the start of Season 6. That didn’t happen but I pushed forward to finish the 128×256 tiles map and then further worked on it by adding google maps support for it.

shot1

It stayed that way for over a year but with the spectacular Season 7 underway I decided to revive the project and got working on it after finishing the Castlevania one. Ashton created an extended version of the track and I made the sigils of the houses using an EGA palette. I also did some tweaks on the map graphics specially to make some castles and places look more like the ones on the series..

shot2

The first version I created didn’t have the zoom effects. I still think it looks more authentic than the final cut but the feedback I got was that it was hard to appreciate the scale of the world. I am not sure something like this could be achieved back then without a special video card, at least not on a PC with an EGA or VGA card.

I did some research in order to assign the stats for each one of the houses. Most of them are just raw approximates which I thought made sense from the little available data.

Enjoy!

Curse of Walachia, finished

Curse of Walachia is a tribute to the recent Castlevania series on Netflix. It is loosely based on Castlevania 3 so I wondered how cool it’d be if Castlevania 3 followed the same plot as the series? 🙂

This is my first video for SlashBit RetroCinema, a youtube channel where I intend to post similar content (second video is almost ready :))

It took about 17 development days to take this from an idea to a reality. Far much more than I anticipated I would invest. I was pretty happy with the end result, but I should be more cautious in the future regarding what projects to start (since I now feel this religious duty of not letting things unfinished).

I had some plans to include all the content in the show but I had to cut it out. These plans included the catacombs stage with the cyclops boss, Sypha joining, the defense of Gresit, the deep catacombs and Alucard’s fight. I figured out this was enough to show my idea (may be I’ll do these in the future, if there’s interest on them).

Here’s the tools I used

  • JavaScript: This is actually a “playable” game which runs in a browser window
  • Phaser.io: Arcade physics engine, timers, tiled map loading, music playback as well as basic spriteworks.
  • Tiled: To created the tile maps
  • Google Translate: To create the Engrish by translating from English to Japanese and back.
  • 8Bit Photo Lab: Nice tool I used to create the character portraits. Wish there was a Mac version.
  • Quicktime Player: To record the vid from screen capture.
  • Soundflower: To redirect audio output into Quicktime Player.

PS: The Engrish is intentional, of course.

Following are the dev chunks per day (Day 10 to 17)

Day 10

Made the weapons work. This involved positioning them based on the mob heading and position, and manually checking the collision vs targets.

Day 11 

Didn’t advance on the project itself since I jumped into the JavaScript animation side-project side-project. But started writing the intro.

Day 12

Worked on the intro.

Day 13

Finished work in the intro, including assembling some scenes. Also worked on Stage 1-1

Day 14

Level design for stage 1-2 and 1-3

Day 15

Level design for Stage 2-1 including adding the old woman dialog

Day 16

Added Trevor’s dialog to fight sequence and a lot more detail on it

Day 17

Details, Details, Details… and release!