Thursday 4 September 2014

Out on the tiles

There has been an obvious need for a particular feature in Asciilands for some time now and just recently, in my third attempt to add it in, did I manage to actually get it working. The feature is this: objects that occupy more than a single tile.

Needless to say it'd add heaps to the game: enemies of different sizes and shapes, interesting projectile types etc. It's a strongly set gaming paradigm: you're trawling through a dungeon killing spider monsters then you enter the wrong room and a HUGE spider runs at you. You immediately associate the increased size with greatly increased threat and you either slam a potion or run off.

We needed multi-tile objects in Asciilands but I was surprised at how tricky the problem was to solve in a satisfactory way. By "satisfactory" I mean "works efficiently and is easy to implement over and over again as Uli and I build up the amount of content in the game". A working solution that ends up being a paint to apply to the content isn't a satisfactory solution.

So why was it so tricky? What could be so hard about moving two things instead of just one? Why can't you just stick another sprite on the side? Let's revisit exactly what is happening when something moves in the Asciilands grid:
Go experimental comic-style-diagrams!

 This has all been explained before but it'll help to have it in your mind if you want to understand the more complex interactions between multi-tile objects and the environment.

And, of course, collisions between objects:

This was how everything worked until recently. To make bigger objects work, there has to be something in each of the tiles that the big object occupies. These things also have to be "connected". They have to move as one, they have to collide with other objects as one, something that collides with one part of the object must, effectively, collide with all parts of the object. Also if only part of the object collides with something impassable, the other parts of the object have to forego their movements. It was tricky and here's how the successful attempt went:

So then the concept of "object constituents" was born! Constituents are very light-weight objects that aren't capable of the complex interactions that go on between other objects. They can't move, they can't collide, they can't be collided with. All they can do is appear, disappear and refer events to their "owner".
If you collide with a constituent, the constituent acts like a receptionist who then forwards the event to the "owner". The fact that the moving object and the owner object aren't adjacent doesn't matter; the constituent creates the connection and collision can take place in code.
Here's how an object with constituents moves:
Yeah? See how the constituents don't move? They get destroyed and remade. You see, the constituents are stored inside the object and filed away based on the grid co-ordinate offset that the constituent should have in relation to the object. This means that the object can always know where to place a constituent and where to look when it's trying to clean the up before a move. It's also how the object gathers the information on which tiles to collide with when it's doing a collision check for each and every constituent.
If it's not making sense, don't worry. It's hardly making sense to me and I'm writing this thing.
What happens when you collide with a constituent? I'm glad you [didn't] ask!
See this is that referring behaviour I was talking about. The constituent is just a bridge.
All of this happens seamlessly with there being no way to know which part of an object is the actual object or which part is the constituent*.

* Not entirely true; if a large enemy is chasing you, you might notice that it prefers to align one side of its body with you over the other. This is a bit of a giveaway since it will always try to align the owner object with you.

So yeah! That's how it ended up working. The possibilities for enemies has really opened up and it's nice to have a bigger canvas than 2*3 characters to draw a sprite.

If you've actually finished this post, you've done well and deserve a reward. All I have for you is this screenshot of a big object in action and a first look at the now-fully-functional Asciilands quest system!


The quest system is actually far more exciting and easy to understand than all this object collision nonsense. It will also take a lot less explaining. Maybe another post on that soon.

As ever, thanks for reading!

No comments:

Post a Comment