Posts Tagged ‘entity system’

Offspring Post-Mortem: So You Want to Make a God Game?

Posted by
Tuesday, August 27th, 2013 1:43 pm

Offspring is a game about guiding a new planet. It starts out inhospitable to life, but through your mad clicking you’ll make it habitable, create life, evolve that life into sentient humans, and encourage those humans into starting the space program. I admit proudly that this game has been called overwhelming, tedious, and complicated!  However it’s also been called interesting, a lot of fun, and a great idea! So I got that going for me.

17811-shot3    17811-shot1  17811-shot0-1  17811-shot2

What Went Right

Reusing a (Semi) Tested Framework

I built a framework using Haxe (language), OpenFL (graphics API), HaxePunk (game API) and Haxe-Ash (entity component framework), and used this framework during the LD26. Since then I’ve used it to make two other games, expanding it along the way. Being familiar and comfortable with your tools is so important. I felt much more comfortable with the time limit this time, and although I did code right up to the wire, the finished product was more fleshed out and polished in a few areas.

Built a Rules Parser/Evaluator

I built a rules parser. I started by defining two types of rules, what happens when you click on a thing, and what happens when certain neighboring conditions are met. I then drew up an XML structure like this:

<object type="steam" audio="steam.wav">
   <click result="clear" message="Cooling some water"/>
   <trigger neighbor="lava" min="0" max="2" result="clear" message="Some steam cools into water"/>
</object>

The object tag defines an object, which has a corresponding image in the sprite file. When any such object is created in the world, the associated audio file is played.  When an object is clicked upon, a message is given, and usually the object is transformed into something else. And at regular intervals the trigger lines are evaluated. The neighbor attribute defines what neighbor is required for the trigger to go off, in this case lava. The min/max default to 1-8 (orthogonal and diagonal neighbors are checked), but in this case anything up to two lava neighbors will trigger the result. It’s also possible to put a chance=”###” attribute on there,  which applies a randomness to the trigger, once all the other conditions are met.

Although I can now certainly think of numerous ways this format could be improved, coming up with the format quickly and committing to it meant I got a rules parser working quickly and (eventually) correctly. It also meant I could add new objects and rules to the xml file at any time to get new behavior, which was very helpful in testing.

The idea

I freely admit the idea of this game — the promise of it — is better than what I built. :) Correctly balanced, with proper achievements and discovery aids, this could be an awesomely fun game for fans of exploration and god games. Forget the fact that the game I built itself lacks these things (balance, proper achievements, discovery aids, etc), I can see a future game in here. And this game — with all its flaws — came out way better than my expectations for a 48 hour time limit. It’s still fun to play! Sure, it can be inscrutable at times and press your patience, but this is just as much a game for Ludum Dare as it is a possible prototype for a future (and better) game.

What Went Meh

The Theme

I got mixed reviews on the association of the 10 Seconds theme. I felt that everyone and their mother would be making McPixel and WarioWare clones, and everyone else would be implementing 10 second game timers, so I wanted to do something where the connection was more abstract. I figured here you are, Father Time, and you give birth to some time children, each of these ten seconds in duration. Then you send the time children out to the world, and they cause eons of change, growth, and evolution but take in real time 10 seconds. Sounded good to me, I started working on a god game.

One reviewer said the theme was “loosely fit.” I don’t know if I agree with that, but it’s definitely abstract. I mean, if we have to implement a 10 second time-pressure mechanic, then that’s not a theme, that’s a mechanic. I voted down any “theme” that sounded more like a mechanic, including this one, but hey it’s all good. If you don’t work out of your comfort zone you don’t improve.

The Triggering Implementation

The TriggerSystem is responsible for evaluating all triggers. I arbitrarily decided on the following implementation:

1. Read all triggers from all objects and store them in defined order in an array.

2. Every update loop, maintain an accumulator so that it only ran once every 50ms.

3. Execute the current trigger.

4. If the trigger passed the condition, execute the result and keep this the current trigger.

5. Otherwise skip to the next trigger, looping back to the top of the trigger list if needed.

I was concerned about bottlenecking the game so I put in this throttling mechanism that I don’t even know was necessary. It worked more or less, so I can’t complain about that. But it had some consequences.

First, the amount of time in between a trigger executing after its last failed trigger was variable. Different terrain conditions could lead to a trigger running repeatedly while the other triggers stall. This problem was made more acute with the introduction of the chance attribute. How do I put this — I’m a programmer not a mathematician, so I may be using this term wrong, but the standard deviation felt like it was pretty high.

Second, the randomization element was not scaled to time. If a trigger missed it’s 5% chance, it would execute again the next time the trigger came around, which was — when? It depended on the other triggers, whether they triggered or not, leading to an extra degree of uncertainty as to when that rodent was going to finally eat that damn plant. Plus any time I added a new trigger to check, all trigger rates went down because another trigger meant more time until the next eval. Now that I’m thinking about it, I guess I could have stored the last check time of each trigger, and then the chance variable could have some specific per second kind of meaning, like 5% chance of triggering any given second. Ah well.

What Went Wrong

The Rule Set Needed an Overhaul

I did lots of minor rule tweaking, but I never got around to an overhaul of the rules. Essentially whatever “promotion path” I came up at the onset of design is the path that stuck. Rodents and Humans multiplied on their own and all other creatures did not. Humans, trees, herbivores, carnivores, and meteorites decayed and died if clicked on, where others promoted or did nothing. Algae required minerals or would starve and rodents could be eaten by reptiles, but almost everything else survived statically.

The inconsistencies of design contributed a good deal to the frustration of the players. The goal was for them to explore the ruleset by trying different things, but they were not consistently rewarded, and oftentimes punished, so the joy of exploration is dimished. I had two hours left at the end of the day and opted to work on other things, like implementing a “child timespan” control and testing.

I don’t disagree with that decision — I was afraid if I started rewriting the ruleset at that juncture I would have too many errors crop up without enough time to fix them. But I should have started that rewrite on Saturday night instead of putting it off. If I did so, I probably would have adopted some patterns:

• Clicking always promotes and never kills.

• All things have kill conditions. So if  a promotion is too soon you can de-volve to some degree, making it so the user is not punished heavily for trying.

• All lifeforms have favorable conditions for multiplying.

Minor Shit

Everything else that went wrong was minor shit not worth bitching about. Overall, I’m happy with what I built.

Some Water Evaporates Into Steam

For those who’d like to try the game, here’s the entry page:

http://www.ludumdare.com/compo/ludum-dare-27/?action=preview&uid=17811

Be forewarned, you will probably need to read the spoilers and have some patience, or just have lots of patience. :)

For those who want to look at the source or modify the rules set and compile it yourself, it’s all available on GitHub here:

https://github.com/scriptorum/LD27

 

Offspring’s application of theme considered harmful

Posted by
Saturday, August 24th, 2013 3:01 pm

In Offspring you’re playing father time, or more specifically, father minute. You have six children, each spanning ten seconds. Although the text at times makes it seem like you’re the children and not the father, but uh ah don’t worry about that right now. Look behind you, a bear. Anyhow you can use any one of the six children to make “massive change” in any space of the map, and this change will only take 10 seconds of real time because, you know, you’re time itself and that’s how long everything takes for you.

The game is a sort of planetary evolution simulator. You’re trying to as quickly as possible bring about intelligent life on the planet and get them to launch something into space. You can use one of the six children to, for example, force meteors to crash into the planet so that minerals land upon the ocean surface, or force cells to evolve into algae. It takes about 20+ steps to turn a space of molten lava into something like a spacecraft launching facility, and many changes will only happen due to neighboring spaces. For example, if there is too much lava next to water it will turn into steam, or vice versa.

Your journey is timed, so you’re goal is to reach space as fast as you can. First time out, though, it should feel more like exploration, as you discover the ruleset through trial and error. This all sounds like an interesting idea to me, but we’re approaching the halfway mark! I still have to complete the rules xml file and draw another 17 objects or so, and then after that there’s music, sfx, fx, and remaining bits of polish. So what am I doing still talking to you? What the hell, man?

Offspring

Posted by
Friday, August 23rd, 2013 11:15 pm

The game is called Offspring. All I’ve got to show for five hours is an idea document, a description of screens and required assets, and this rules.xml file. I have a pretty good notion of the kinds of interactions I want to happen in this game, but I know the actual rules will need lots of tweaking. So my hope here is by putting all my rules and triggers inside an xml file I can spend Saturday putting in the framework and art, and tweak the hell out of all the rules on Sunday. This is a bit of a game of exploration, especially for the first time player, until you discover all the rules — well, presuming I finish in time. :)

Screen Shot 2013-08-24 at 2.07.03 AM

The XML file driving a rules based system

A week has passed since LD48 and it’s a good time to take a deep breath and reflect. Rub our sore muscles. Think about what’s next. Weep uncontrollably. Whatever you need. In my case, Mass Splitter went out the door without a hitch! Well, rather, it was well under the maximum number of allowed hitches. It was within hitch tolerance. In truth, there were three hitches: I didn’t get in a main menu, I didn’t get in a tutorial or at least an instruction page, and there was only one level. But all these hitches pretty much have the same cause, that of running out of time, so how comes I haz runs out?

What Went Wrong

Architect hat mostly unworn

I spent a bunch of time trying to get some view components working with HaxePunk. HaxePunk handles origin a little differently than I would think it should work, so I spent a few hours on my View class, getting the Scale, Origin, and Position components to all work together. Great, they now work together.

I did this because my game has orbs in it, and the active orb has a tube spinning around the outside edge of it. You hold the spacebar to shrink the active orb and start growing a new orb on the other side of the tube. After I got the tube spinning at the right radius around the correct center point I then went to add the new orb. This new orb also needs to be placed at spinning radius from the center, so how do I get the true position of the edge of the tube?

Well I can’t. The tube’s actual position is derived inside the view class, so it doesn’t exist at the component level. So now I’d have to either hack into the View objects to get this information (which horrifies my MVC sensibilities), or just calculate the orbital position myself, which I did. Well gosh, that was easy. And now that I’ve done that I can position and rotate the tube using the same logic, so the tube stops scaling along with the size of the active orb, which is a better look I like anyway.

In essence, I looked at just one next thing to do, rather than the broader landscape. Without putting on the architect hat, I spent a few hours going down a rabbit hole I didn’t need or want. On the other hand, I’ve got a cooler View class now.

Failed to take the time to split up complicated classes

I didn’t universally fail this, but I could probably attribute a few hours of wasted energy because of failing to do this early or at all. In particular my firing system is doing several things rather than breaking it up into different systems. See Ash Entity System / What Went Right.

Not putting more of my personality into my game

Friends often tell me I’m funny. Even fine, up-standing strangers — if not calling me that — have in the least called me irreverent. I try not to listen to other categories of people whose job is to be offended by everything. Anyhow – you wouldn’t know these things about me from playing Mass Splitter. Sure, I don’t have to make humor a central aspect of all my games, but a) it’s clearly desirable in a competition where there’s a category for it, b) there are many kinds of humor besides pratfalls and puns that can serve a dramatic cause. Heard of irony? Sarcasm? Deprecation? Pathos? Impudent contempt? Not that Mass Splitter is a deep example of erudition (it’s not), but it’s better for one’s self esteem to believe your personality is a strength. And if it’s not … well, you should work on your personality. Are you trying to tell me I should work on my personality? Stop staring at me like that.

What Went Right

Ash Entity Framework

Richard Lord’s Ash Entity Framework is really good. It’s an entity component system. I used the Haxe port maintained by Dan Korostelev. It was really fun to learn how to use an entity system and put it into practice. For those who don’t know, apparently those folks at AAA game houses have been using these things for years. The idea is to eschew traditional static object hierarchies for a data-driven composition approach. Richard has some great articles about it on his website.

Everyone seems to approach an entity system differently; in Ash the entity is a fairly generic object. You create a new Entity instance, optionally give it a name, add components to it, and add it to the engine. Usually it’s the job of a factory to create the entities with the components you need, but that’s up to you. Components are simply data-holders that you create, with little if no logic in them. Ash components do not need to derive from any base class, any object could be a component. All the behavior for your game goes into the systems you write, derived from the System class and added to the engine instance driving your game. When you call engine.update(time), all your systems execute in the appropriate sequence. Although Ash provides a signaling capability, Richard recommends you use boolean flags or components as markers to indicate when events happen, so that a component event (such as “this changed”) is only responded to by a system when it executes. Using engine.getNodeList(MyNode) a system fetches a list of entities from the engine that are relevant to it. Nodes are classes that contain one or more components; only those entities holding the components you specify will be returned.

I enjoyed using Ash quite a bit and encourage you to look at my source on Github if you’re interested in seeing one possible way of using the library.

Think smaller

Last compo I thought I picked a small idea but apparently it wasn’t small enough because I couldn’t get it done in time. This one was doable — juuuust barely. :)  I tried to get a playable prototype as soon as possible; I would have liked to go to bed on Saturday night with it playable.  Now, that didn’t work.  Pthbth. The prototype wasn’t playable until Sunday afternoon, but imagine if I wasn’t striving for earlier! Suck-sess.

Toolkit practice

I’ve had previous practice with HaxePunk, and I started messing with Ash in a previous game I attempted to complete for the 7-day Roguelike. Even though THAT attempt was a failure, it gave me crucial practice that made this submission possible, and also gave me base code to pick at for Mass Splitter. Of course, more practice would be better, so I shouldn’t wait four months for my next game…

BFXR

This audio tool is available in several forms; the one I used is BFXR. Sooooo convenient. Sure, all your sounds do tend to sound video gamey retro screechy crunchy if you don’t post-process them, but a lot of people go for that, and damn if it isn’t quick to pump out some placeholders.  (… that wind up being the final sounds when you run out of time)

Shut up, good enough, it’s playable

Shut up, I say! It’s good enough. It’s playable. I’m just happy I got out a game. Would I have liked to get those extra things I conceived of? Of course. Over time, with practice, I’ll be able to meet the goals I think I should be capable of. (I’m a damn perfectionist. I’d be faster if I wasn’t always trying some different way of doing things.)

I finished something playable in time that some people actually liked. Next time I’ll do even better.

[cache: storing page]