Creating Life - A study into HTML5 Canvas, Webworkers, and Life Simulation - Part 1

Written by Kevin on July 21, 2013

Let me start off, I am no pro in any of the following you are about to see. I have spent the past few weeks trying to learn about HTML5 and some of the cool new things its brings. First off, you can see a demo of all my work on I should tell you right now, I think it will only function on chrome. I know there are some styling issues on Firefox and the last time I tried running it in firefox it didn’t run at all.

All of the source code can be viewed an GitHub. Please feel free to clone the project and see what you can figure out on your own.

So what is it? Well, its a pond with 4 map types. Empty (dark dark blue), resources (dark blues and purples), materials (lighter blues and purples), and organisms (green and red). The organisms can either be producers (green), or consumers (red). Producers convert resources to materials. Consumers eat the materials. There are 3 type of each resource, and 3 types of each material. Each resource converts to exactly 1 corresponding material, and each organism will only desire 1 type. Producers are designed to work together, sharing resources and materials in a simple attempt to keep the entire pack alive. Consumers are greedy, not caring at all about the heard in general. Each mitosis that occurs has a chance of mutation. Mutations change color as well as a variety of attributes about that organism. Some configurable options include goal resources on board as well as organism spawn rates.

The application which runs the simulation is separated into three primary pieces. The UI, the worker, and the drawer. The UI is the master controller. It start, stops, and communicates with the webworker. It asks for data from the worker, and when it receives a reply, it renders it to the screen as well as passes it along to the drawer. The Webworker does all the heaving lifting. This includes processing the flow of the pond, the spawning of resources, and the life and death of organisms. Anything pertaining directly to the pond other than the rendering is done in the webworker. The drawer does the canvas drawing. This includes the pre and post filtering.

The first technical aspect I want talk about is how I figured out how to quickly send >25000 datapoints from a Webworker to the UI Thread. In order to do this, we can not use any of the classic javascript types. Objects, arrays, strings, ints, and floats all are copied (duplicated) on each message. This is fine for small bits of data, but for a huge dataset, this can add significant overhead, especially since we want to send this data as many possible times per second as our renderer can handle (On my PC, this is about 12-13 FPS). In order to not have a full copy occur we must use one of the transferable object types. One of these types happen to be a type compatible with ImageData. The following snippet of code shows both how a large array of data could be converted to a transferable datatype, transferred from the webworker to the UI, and then quickly applied to the canvas. For sake of simplicity, I am only showing relevant code to this idea, without any of the other application logic and organization.

Next Time I will talk about in depth the different flow algorithms that are implemented so far, as well as a couple that are up and coming.