We still aren’t simulating anything yet, but we’re getting there, slowly but surely.
When I started this project, I knew simulating life forms would be an essential part of it–not just the intelligent ones that would give rise to civilizations, but the plants and animals that form the critical ecosystems and food chains to support those civilizations. I got suck for quite a while on exactly how to accomplish it. Early on, I decided I would want to use some kind of DNA-like system, in which a string of data represented everything SagaSim needed to know about the species. It took me a long time to figure out how best to implement this, but ultimately I ended up devising a rather simple system for it.
I decided to use a string of bits–1s and 0s–to define my species’ DNA. Then I needed to figure out how many to use. I ended up going with 24, since it provides over 16 million possibilities but is not so many bits as to be unmanageable. Then, I had to determine the best way to describe the bits themselves. I created what is, for lack of a better term, a “DNA specification.” Through the use of a rather simple text file, I can create all the DNA bits and describe what specific patterns mean. The file format is rather simple:
[bit number],[bit type] [0 value,1 value] OR [plain text description, if bit patterns are defined] [bit pattern],[implied trait] [bit pattern],[implied trait] ...
So, the first line is the bit number (literally, the position of that bit in the DNA string), followed by a comma, then the “bit type.” There are two bit types:
* Generalization -- A bit that will assign a particular class/type to this species. * Association -- A bit that will assign a particular attribute/property to this species.
The second line can be formatted one of two ways: it can specify the meaning of the 0 value and the 1 value, separated by a comma; or, it can be a plain text description of this bit’s purpose, if we’re going to use bit masks. After the second line, there can be any number of lines of bit masks. Each bit mask is a sequence of 0s, 1s, and question marks, followed by a comma, then the generalization/association implied by that pattern. Any 1s and 0s in the mask must match exactly in order to apply, question marks indicate that that bit isn’t important for the purposes of the given trait.
Examples are helpful, so here are a few:
1,generalization plant,animal 2,generalization generalist,specialist 3,generalization spore/seed,vertebrate/invertebrate 0?0,spore-bearing 0?1,seed-bearing 1?0,invertebrate 1?1,vertebrate ???,[none] 4,generalization thornless/thorny,endothermic/ectothermic,small/large 0??1,thorny 1?11,endothermic 1?10,ectothermic 1?00,small bodied 1?01,large bodied ????,[none]
Pretty simple, right? They go all the way up to bit 24:
24,generalization non-sapient/sapient 101?1???1?0????????11111,sapient ????????????????????????,[none]
You’ll notice that at the end of each list of patterns is an all-wildcard pattern followed by [none]. This is just our “catch-all” pattern to indicate that, if no other matching pattern is found, this bit serves no purpose for this species.
One thing I like about my implementation of the DNA system is that the specification is kept in a text file, and then imported into game at runtime, so it is inherently customizable and easy to update. I considered using XML or some other established, structured format, but I opted against adding such complexity and overhead. I may implement an intermediate XML format for SagaSim’s data files at some point in the future, though, for compatibility with other tools as well as general ease-of-use.
Once a species has been created, all of its traits are kept as part of a species object. This is really just a placeholder until the full species object is created, which will contain all the actions and attributes endowed to that species. What it can do at this point is spit out a description of itself. Here is one for a randomly-generated species:
Species sagasimus testus Generalizations: animal generalist vertebrate endothermic aquatic carnivore egg-laying scavenger diurnal domesticable omnivore non-migratory venomous schooling Associations: fur
The DNA string for it is:
And while I admit this is a feature that’s probably not worth much except the amusement factor, I also wrote a mechanism to render a given DNA string as a graphic. Here is the (greatly enlarged) sprite of the DNA string above:
The algorithm for this is actually really simple. I create an 8x8 image (64 pixels), use the 24 bit DNA string to generate the color (8 bits for red, 8 for green, 8 for blue), then start on the second row and draw four pixels per line, starting from the left. After four pixels are drawn, I go to the next line and keep going, until I have rendered all 24 bits/pixels. I also “mirror” the pixels on the right side of the image, so the sprite is symmetrical. This is very, very simplistic (even silly) but it provides a unique sprite for every species in SagaSim. I plan to use them, or more likely a modified version of them, in the actual simulation.
Just for fun, here’s a 600x600 randomized set of species:
I still have a couple of issues left to iron out, such as resource contention over the DNA database, but what I have so far seems adequate enough to proceed.
It may be a while until the next update, as I need to write the actual class/type system to go along with the DNA system. The good news is, this means I will actually have some simulation code in place! I will most likely break the coding of the species simulation into multiple blog entries, as I expect it to be somewhat complicated and I’d like to talk about each ability and attribute of the species.