Saturday 14 December 2013

Asciilands is a game

So far, creating Asciilands hasn't required a lot of creativity in terms of the nature of the content. We haven't started on the story or anything like that and there are recurring game elements that are more or less expected to be included in games of a certain type. This is where most of this early-stage development work as gone. Some may say that simply complying with expectations is to stifle the creative process but I see it differently: it cuts down on the time and frustration required to learn the game's mechanics.

When a player is interacting with a game, they have certain expectations surrounding how various things will work. Creativity should come into the process of combining these elements rather than creating new ones from scratch (unless the whole point of your game is to introduce and explore a handful of interesting and new mechanics).

I read an article once about the game Bulletstorm and how when it first went to beta testing, the explosive barrels were green. Because of this, NONE of the play-testers used the exploding barrels to their full effect. The dev team on Bulletstorm decided that instead of putting in some kind of contrived lesson to demonstrate how to use the explosive barrels, they'd just make them red. As soon as they did, everybody knew how to use them. They expected them to explode when shot, they shot them and the barrels exploded. Lacking in creativity or just cleverly tapping into a frequently reinforced paradigm? I don't think it matters. Don't frustrate your players and they won't think it matters either.

On that note, here are a bunch of features that cement, in my own mind, Asciilands as a game beside other games I've enjoyed.

Pictured with Duke Nukem by Apogee Software

Health bars! This is a fairly recent addition but obvious a crucial and long-time-coming one. There was no point adding it in until it could display useful information so combat needed to be implemented first.
So yeah, health goes up, health goes down, health runs out, death. More or less like you'd expect.

Pictured with Binding of Isaac by  Edmund McMillen and Florian Himsl

Opening and closing doors are a must. How else can you strategically manage the location of enemies trying to chase you? Should have left that one closed.

Pictured with Pokemon by Game Freak

Push blocks make for great puzzling. By "great" I mean "ok for the first few seconds but rapidly turning awful". For me, the formula for enjoying push-block puzzles is this: if I can't work it out in my head just by looking at it or I get myself stuck and have to retry more than three times, I don't want to do it. The exception, of course, being a a push-block puzzle in a dedicated push-block puzzle game. We'll be careful to keep the push-block puzzles to a minimum in terms of frequency, magnitude and difficulty.

Pictured with Diablo 3 by Blizzard Software

You can't just make people explore large areas of terrain without whacking in a few bridges. Something about them just...I dunno. They're needed so they'll be included.

Pictured with Borderlands 2 by Gearbox Entertainment

Diverse damage types with equally diverse visual representation has always been something I've liked in a game. It's good, satisfying and instant feedback to a successful hit in a way that stays fresh; a successful hit with this weapon looks different to a successful hit from my last weapon.

Pictured with Titan Quest by Ironlore Entertainment

NPCs with nothing interesting to say who just wander around are a MUST. I'm not even kidding. They are the perfect example of something being greater than the sum of its parts; an NPC who says "goodness, what a horrible thing to befall our farms" is boring and pointless but if you have a town that you want to make feel safe or a character that you want to make feel powerful, you add a bunch of weak, useless people and you can achieve both those feelings. Just like a pretty girl who only wants ugly friends, you feel like you want to save the towns people for no reason other than that they are there. Also, if you accidentally let the zombies out, the towns-people aren't so benign anymore.

Pictured with Prince of Persia by Brøderbund Software

Health potions: the obvious next step after health bars. Added them just today so I could test the health bar multiple times without resetting the game-world. Cool.

Pictured with Diablo 2 by Blizzard North

Nobody wants to get lost in an RPG world. Not knowing what to do, where to go or how to do something are the most frustrating things in an RPG. The minimap fixes ~33.3% of those issues!

Pictured with Path of Exile by Grinding Gear Games

Can't have a loot game without lootable chests. As expected, randomly generated loot with appear in random quantities in randomly placed chests.

That's it for now. As you can probably imagine, Asciilands is becoming quite playable in a way that is more an more resembling a game and less and less like a tech-demo or proof of concept.

Be sure to contact me (Jared) if you're interested in testing some time.

Also get over here and like the Asciilands facebook page! https://www.facebook.com/asciilands

Wednesday 4 December 2013

Damage types

Just a quick update to show you what's been the recent focus of development; also it's a very visual area of development so I get to make screenshots!

Basically all the code required to apply visual effects to weapons and enemies is in place as well as the the logic behind choosing the right modification based on the damage type (e.g., fire damage will put "flames" on the weapon's sprite and on enemies who are set on fire by the weapon).

With all my lovely effects finished, I didn't really have a good place to test them out so I made some skeletons and chucked them in the bluff cave. I'm sure the hermit won't mind.

Enough talk, show some stuff:



Here we have a bunch of randomly generated swords with elemental effects attached (left to right: poison, cold, water, fire, lightning, trauma).

For the most part, at the moment at least, different damage types mostly determine how attack damage is reduced by defence. You can be resistant or immune to the various damage types and reductions are made accordingly. You can also be resistant to what's called the "damage delivery" which is kind of a "blanket resistance" that will make you resistant to an entire attack made with that delivery method.

What did I just say? Hold on, this example should clear things up: A sword might do 20 trauma damage and 10 poison damage and the delivery method would be "cutting". If you had 50% trauma resistance you'd take 20 damage:

(20 * 50%) + 10 = 20

If, however, you had 50% cutting resistance, the damage would not be selectively reduced and you would take 15 damage:

(20 + 10) * 50% = 15

A combination of the two would leave you with 10 damage:

((20 * 50%) + 10) * 50% = 10

Clearer? Perhaps!

The main thinking behind this scheme is to make it possible to include new, different attack types without requiring people to plan for all kinds of things. Delivery resistances will see you in good stead but those who want to micromanage will still have a bit of an edge, especially if they know what's lurking in the area they're going into.

Ah! Got a bit side-tracked there. So we have our lovely weapon effects! Grab those swords, run into the bluff cave and find those skeletons so we can watch them die in all kinds of ways!

I recommend playing this song while you read over the next part:


*Sound of skeletons being hit by magical weapons of all kinds*


When you attack a dude with a weapon that leaves a lingering damage-over-time effect (e.g., 20 poison damage over 6 seconds), they will show this status with the corresponding damage type's effect!


Stay dead this time, skeletons.

Saturday 23 November 2013

The day the Bluff Cave became the Bug Cave

An obscure reference to an obscure reference

One thing that makes Asciilands so different to any other software I've worked on is how the bugs manifest. This comes from the fact that Asciilands is creating a "world" of sorts to reflect the real world. This means, like in any other game, that you interact with it bringing with you certain ideas of how certain things should work, e.g., you expect to be able to walk on sand but not on water, you expect to be able to open a treasure chest and if you can't, you expect that once you find the key you will be able to. This effect, however, is not limited to the player. I, as the developer, bring with me expectations of how things will happen when things go wrong and like the player, when the disparity between my expectations and what happens becomes too great, it feels weird.

The software I've worked on for my paid jobs have had bugs to be fixed but these bugs are generally things like "Oh dear, this column is not sorted correctly!" or "This thing stops happening after about 20 cycles or if you click in this region." or something equally benign. The bugs are equally simple / complex but that jolt that you get from something unexpected happening is greatly exaggerated when it happens in a piece of software that's supposed to be reflecting some kind of other reality, not just displaying some stuff.

For instance, a stray reference making something incorrectly identify another object as its parent would maybe cause a piece of data to render on the wrong tab in normal software. In Asciilands, it meant that when I tried to equip my silver axe, nothing happened...it just disappeared. "That's weird" I thought but then when I went into the cave, I saw that the torch in the cave was holding my silver axe.

This is obviously a ridiculous situation but the only thing that makes it weird is that it makes you visualise that event in a more human way. You see a little dude pulling an axe off his belt only to have it turn into a puff of smoke then you can imagine his confusion as he sees it being wielded by some other inanimate object in a cave somewhere.

This unique way that a game can give interesting, and sometimes entertaining, kinda "narrative" life to basic reference error bugs is what makes Asciilands fun to continue working on where other projects might just be frustrating.


The simple change

There has been an annoying little oddity in Asciilands from the very start and that oddity is this: when you change maps (e.g., go through a door or get teleported to a new place), the browser refreshes itself automatically. This is because when you log onto Asciilands, the map that you start in loads itself on the server then sends all the information required to display the map to the browser as JavaScript objects. These objects make up all the tiles and scenery and monsters and items etc. That way, when we update the frame, we only need to send back single letter codes for each asset instead of about 170 letters for all the html required. That's 99.52% more efficient than just sending the raw html but it comes at that cost; that annoying browser refresh whenever you go anywhere. Or at least, it did.

After thinking about how I was going to do it for a while, I sat down and started making a few of the changes required to get it happening.

I made the changes and it didn't work at all. This is my life.

The bugs I encountered while trying to make this fix were sometimes a little creepy but mostly just amusing so I thought I'd capture a bunch of them to share for those who might be interested.

First thing was to make the new starting position near a place conducive to testing: the entrance of the Bluff Cave. Here we are:


Lovely! Now let's head into the Bluff Cave and see if my modification works as seamlessly as I'm hoping!




Hm...I guess not.

Ok! Learning experience right? We can see that it at least made an effort: We have that darkened square that makes the cave dark so it kinda knows it's supposed to be dark, it pushed the view down and tot he right so that it would be centered if it were smaller (like it should be in the cave) and the thought event was triggered ("The air is cold" seen on the right hand panel).

What do we have? It seems to know we went into the cave but it's not letting us stay there...or something?

Ok, let's try this:


So far so good...


Ah. Ok, that's not right. Last time I was in here I was being chased towards the ladder by a zombie; not being chased towards the pile of presents by the poisonous sword.
At least it knew we were in the cave, though right?

What could have done this? The tiles are ok but the sprites still seem to be from the old map. I don't really get it but maybe if we head back out, the old map will have the cave sprites? It's not impossible...


It's...oh god what? Ok so everything is either on fire or made out of gold and banner items. Also did the door to the cave turn into a red present? What's with presents appearing in all the bugs?

Refresh!


Strange: refreshing fixed it without having to do any kind of data reset. This means it's a javaScript issue! Things not being sent properly or sent late or sent sideways or sent in the wrong order or something? There's a miscommunication; time to try a few more things...


Ok, this is new and much closer to what we wanted! We have the cave and the zombie...but the cave is blue. Why are you blue, cave? Are you hinting that you want some kind of underwater cave section?

Wait a minute...the wall is blue...like the water. 'W' makes sense as a tile key for both Wall and Water! Wait, why does that even...AH!

This should be it:


...aaaaaaand...


Hurrah! Everything's exactly how it was five hours ago except that the page doesn't refresh [almost] unnoticeably when you enter the cave!

Still more exciting than fixing sort order or grid alignment, right?

Thursday 31 October 2013

We interrupt our regular coverage for a terrifying announcement

Rogue Jack-O-Lanterns have been spotted on testIsland...


 ... and an eerie skull-like architecture is reported to have appeared in the Dreamscape - or should I say the NIGHTMARESCAPE?! [Probably not - Ed.]


Happy Halloween from the Asciilands Dev Team!

Saturday 26 October 2013

Behaviour!

This post is dedicated to behaviours. Object behaviours. Behaviours of objects within Asciilands. All objects in Asciilands have behaviours and there are many types of behaviours which do many different things. They control how objects behave when they interact with each other or when left alone or in response to some other situation.

Complex simplicity vs simple complexity

I'd like to start with a link to an article written about a game that I love and kept in mind whilst writing the behaviour code.
The game is Spelunky and the article is this.



If you couldn't be bothered reading, it basically details the way various non-player characters in the game happen to trigger a complex series of behaviours leading to a hilarious, unexpected and rich experience for the player.

This is what I love about Spelunky; the complex things that can happen from seeming simple, single-purpose enemies and in-game actors. I think the thing that makes it so satisfying is that when you play, you feel like a participant in the game world instead of the sole driving force behind the game's events. This is the feeling I wanted to emulate but it seemed utterly insurmountable. What kind of insane attention to detail was required to create all these complicated events possible? How could I hope to emulate that? As the game content grew, how much back-tracking would I have to do to make sure everything can interact in interesting ways with other objects?

The amount of work seemed mind-boggling. The amount of new interaction code would grow geometrically with the creation of new content.

Or so it would seem.

When I first started working in behaviours, I quickly discovered this strange truth: the most simple behaviours instigate the most complex interactions.

Notice this: the separation of the idea of "behaviours" and "interactions". Let's look at that article again with that in mind: The tribesman DID have simple behaviours; throw boomerang, seek boomerang, pick up boomerang, find player. The shop-keeper only has to ensure "his" objects don't leave the boundaries of his shop before turning on the rage behaviour and the player only has to trigger one of those.

It then becomes apparent that simple behaviours are a requirement of complex interactions.
Consider this: The tribesman has a simple behaviour that makes his seek and pick up a boomerang. If his behaviour was a little more complex, if he had to pick up his boomerang, suddenly this scenario can't happen. Similarly, if the shop-keeper waited for the player to remove his items from his shop, it couldn't have happened. Simple behaviours are easier to trigger allowing "accidents" to happen. Importantly, they can happen without the player's intention or instigation.

Once I figured that out, the future seemed much brighter. Rather than coding complex behaviours, I only had to focus on two things:

  • Keep the behaviours simple
  • Don't give the player special status when it comes to behaviour execution
I haven't mentioned that second point so I'll give a quick Asciilands example and then get into the methods used to create the behaviours.
When play testing, I created a bunch of NPCs to walk around and a bunch of items to collect. Since I wanted to follow the second rule, the NPCs could pick up the items just the same as the character. They have an inventory using all the same code as the player. In fact, they share most of their code except that the player is controlled by a human and the NPCs speak to you when you bump into them.

Anyway, I was getting tired of them picking up the items that I wanted to test so I wrote another behaviour and attached it to the NPC that causes them to surrender a random item in their inventory when you bump into them.

Thanks, Flinos!

That out to make testing the items easier...however, strangely it only seemed to be working some of the time. I put a bit of debug tracing code in the giving-item behaviour and found that this was because I was following the second rule without knowing and the items were being passed from NPC to NPC as they fumbled about with their random-number based wandering.

I left the trace code in so I could find the items I was after but this accident made me very happy! The obvious next step is to add a behaviour called say, "psycho" which causes an NPC to attack others if they happen to come into contact with a weapon. This would mean that once in a blue moon, an item would get handed around and find its way into the inventory of the wrong guy and a new kind of enemy would emerge creating a new experience for the player. Who knows, as behaviours evolve and guard NPCs emerge who react to nearby attacks start being implemented, fights could begin and end without the player even knowing.

The possibilities are endless but not because the behaviours are complex but because the interactions between simple behavious become complex if the scope for their triggering is left broad enough!

The best method to create madness

Writing object code: easy. Writing behaviour code: easy. Attaching behaviour code to object code: hmm.
The most difficult thing about making the object code work with the behaviour code was that I never thought it was difficult. This caused me to write it:
  • Strangely
  • Poorly 
  • In ways difficult / annoying / tedious to implement repeatedly
  • All of the above
In this section, I'll run through the methods used (including the one I wrote that other post about explaining collisions) and explain what did and didn't work.

Attempt 1: Traits!

For those who know PHP: I wrote each of the behaviours inside a trait.
For those who know code but not PHP: traits are sort of like interfaces but you actually implement what's inside them. It's to prevent needing to rewrite common code for different objects.
For those who don't know code or PHP: this was silly.

I like diagrams so I'm going to explain this using diagrams.
Here we have an object and a behaviour:


Since the object is a trait, when we combine them, they become attached rather like this:


How nice. Programatically they're now one entity and can be coded as such. The behaviour code and the object code are all coming from the same object. Wait, this is too abstract. This object is a person and he is...walking.


So what's good about this arrangement? Well the person's code can say "I am a person and a person can walk so I'm going to walk" and the person will walk. Simple. The walking code says "I'm going to move my person to the next square because that's what walking is!". Brilliant, look at those little guys walking around down there! Hey! Let's make them talk! Ding!


We now have walking, talking people. They know how to walk and they know how to talk because they were literally made to do it. How does this interaction look inside the object? Sort of like this:


So the Person tells its walking and talking behaviours what to do and how to do them and they do them (rather like your brain telling your legs to walk and your moth to speak).
The way the behaviours get attached rather than actually being part of the object is important for creating different objects with common behaviours.
We might have an NPC who can talk but not move. We might have an animal who can walk but not talk. We might give an attack behaviour to the animal instead. We might replace the walking behaviour with a chase behaviour etc.
It's modular and it works nicely to maximise difference in objects just be creating combinations of behaviours.

What's the problem with this then? Notice how the person prompts the behaviour to start and the behaviour then carries out its purpose with person? Well what if we did make that non-moving person. We'd have a situation that looks like this:


Not cool. The person still wants to move because that's part of what makes the person code part of the person code. Sure, the obvious way around this is to simply perform a check to see if the person has this ability or to turn it off and on but then we're losing that simplicity AND we're losing the portability. We have to code all those checks into every object that may or may not have whatever behaviour.

To further complicate the problem, suppose we wanted the NPC to stand still while we talk to them. Now the behaviours have to be aware of each other and make similar check both against the object they're attached to AND the other behaviours attached to that object. What should be done about that? Some kind of behaviour register array? A bunch of booleans? Eh, messy. No thankyou.

So what did we learn about traits and trait-based behaviour code?

The good:
  • Modular
  • Linked directly to the host object
The bad:
  • Not very good at being aware of each other
  • Linked directly to the object
  • Can't add or remove behaviours on the fly, can only activate or deactivate.
  • Messy
The ugly:
  • The only way to sort out the problems of linking behaviours to other behaviours that may or may not exist is to have all the combinations accounted for and checks made to see what we have to work with. This defeats the purpose of the entire system.
Ok, let's try something else.

Attempt 2: Objects!

What if behaviours were now objects in their own right? We'd have this:


Ok, now let's get our talking, walking person back in this new form...

Right. What are the main advantages of this? Firstly, since the behaviours are independent to the object itself, they can have self-awareness. This wasn't possible with traits since walking doesn't have a "self" independent of the person.
This probably makes more sense to those of you who are developers but it's very important.
What's in these behaviour objects? This is what the behaviours "know":


Now let's see what happens when the behaviours are made to activate!:


Again, I'm not sure how easy this is to make sense of for people with no development experience but this is one of the more technical posts.
The key difference here is that the object doesn't tell the behaviours what to do like it does with the traits. All it does is till the behaviours what's going on and the behaviours activate when the call is relevant to them.

This prevents that problem that we ran into when our person wanted to walk without the walking behaviour. With this new system, the person just says "I'm idle, what should I do?" and if he has walking behaviour, the walking behaviour will kick in and say "walk!", otherwise nothing will happen. That's better! It also means that we can add and remove behaviours without having to write extra code in the person to handle all the new things it can do. As long as the person knows when to make announcements and the behaviours know which announcements to listen for, everything will go smoothly.

Out non-walking man might suddenly need a "flee" behaviour because we attacked him or something. With this new model, instead of needing the flee behaviour all along and having to turn it on when we attack him, we GIVE him the flee behaviour and it activates by itself. The person doesn't need to know why or how because the behaviour is in control and doesn't need his help.

Hold on though, what happens if we have a walking person who then gets a flee behaviour? Won't they walk half-randomly and half quickly-away as the behaviours compete?

Well they would, yes...but there's a simple solution for that: every behaviour knows its "type" and each object can only have one of each type behavior. Since walking and fleeing are both movement types, the fleeing will REPLACE the walking.

I'll explain diagrammatically:
If we have a person who can walk and we want to add the ability to talk, no problem. We can just add that behaviour since they don't conflict:


The complication is introduced when we want to add another kind of movement since they are not compatible. They will conflict. It's important to note that having multiple behaviours respond to the same event is not a problem, it's necessary. The problem is only if the behaviours are clearly in conflict (like two kinds of movement or different speech behaviours or multiple attack types).
Anyway, we can't be wandering and fleeing:


A check is made and if it is found that that behaviour type "slot" has been filled, a replace needs to happen.


We now have our talking fleeing object!
Those with a keen eye may have noticed another problem that existed with trait behaviours that has not yet been resolved: behaviours not being able to talk to each other.
The behaviour type slot is also the solution to that problem and solves it in a way that helps uphold an extension of that old second rule: don't give anything more special status than it needs in order to function correctly.
A behaviour doesn't need to talk to another behaviour, it only needs to talk to another behaviour type.
For example, when talking to an NPC, they stop moving. This can be achieved by having the talking behaviour tell the movement behaviour (walking or fleeing depending on what is in the moment slot at the time) to pause for a short time.

This killed two birds with one stone and I hadn't even seen the second bird coming!

Ok, so what did we learn about object behaviours?:

The good:
  • More modular
  • Cleaner to work with
  • More independent
The bad:
  • So far they're working fine but I thought that about traits, too, for a while
The ugly:
  • Once the event triggers and listeners are understood, it isn't too ugly but it can seem rather tangled when it isn't fully understood
Object based behaviours it is! They have yet to let me down and they're very versatile for use with all sorts of objects and items with all different kind of event triggers and behaviour types.

Thanks for reading!

EDIT: One more thing! The editor from the last post has been the main focus of my recent efforts and it's more or less finished now. Below is a screen-shot of about half and hour's work. Oh, the efficiency!


I'm curious to know whether or not the 3D form of the castle is apparent or if it kinda take a while to "get your eye in" to be able to see what's being attempted using the tiles.

Let me know!

Thursday 17 October 2013

Editor!

Today I am pleased to announce an early alpha of the Asciilands editor! It allows much easier creation and editing of the maps and shows how it will look in real time.
Creation of good dev-tools was always part of the plan with Asciilands and so far, this feels like the most triumphant example.

Enough talk, you probably want to see it. Maybe. Here it is!


You can't christen a map editor with anything other than some horrible in-game text so that's exactly what I did.

The interface is fairly self-explanatory; choose from the world tiles on the left and the scenery objects on the right and add them to where the cross-hair is.

Editing text files like we've always done is fine but there are distinct advantages to this kind of interface:

  • It's much faster to make a change.
  • It can be transitioned to instantly from test play.
    • This means, for example, that play testers could not only tell us about map annoyances or oddities but they can immediately cross over and change it to what they might have expected.
  • It's prettier and nicer and doesn't suffer from the distortion that non-square characters impose on text-based maps.
  • My eyes will hurt way less when I'm trying to do the dual-tone walls of cave interiors, trying to distinguish between lower-case and capital Ws in huge blocks.
Other development developments are as follows:
  • New behavior system complete and original behaviors transitioned to new system
    • I will be doing a blog comparing and discussing the two systems soon.
  • Added a few extra features and areas to testIsland to test new improvements (e.g. BluffCave now has a second, deeper, and much larger area to test the various way to enhance in-game visibility).

Development continues!
As ever, anyone interested in testing Asciilands (or the new editor) remotely in invited to let me know!

Behaviour system blog will be coming soon.

Saturday 28 September 2013

Get it right the first time, that's the main thing

I've been quiet around here recently for this reason: I've had not much to report. Not much of interest anyway. As ever, I've been re-writing my old mistakes for the sake of future ease of continued development. Here's the thing I was redoing: ALL BEHAVIOURS.

It's been a pain since every interaction between every object is handled with a variety of behaviours. This is the third re-writing and the most comprehensive. It doesn't just work better than it did before, it works a whole different way.

The obviousness of the need to go from the old trait system to the new behaviour object system made itself apparent when I started writing the code for combat. Combat between two objects using weapons. The weapons are procedurally generated meaning that their properties are chosen at random (but kind of "channeled random" so that they kinda make sense e.g. no fire AND ice damage) and then these properties need to be read from the weapon and "applied" to the victim of the attack. This was a tricky thing to do but then the more the method for doing it cleanly evolved, the more it resembled a better way to handle every interaction in the whole engine!

Consider this: how is an interaction between two combatants any different to the interaction between any other two objects? Only that in combat, an object is kind of surrogating the interaction on behalf of its owner.

Wait, I think I've reached the point of this not being at all interesting.

I'll tell you this and leave: The re-writing of behaviour is nearly finished which means the behaviour of complex, procedurally generated weapons is almost finished which means combat is about to be actually interesting!

Oh hold on, need a screenshot...just let me grab something...


This is kind of interesting and new. Sort of. The weapons along that wall are all procedurally generated. There are separate algorithms for creating swords or axes / hammers and within that they have a bunch of rules (e.g. if the sword has a guard over the hilt like the sword second from the left, a small defence bonus will be added). More on these algorithms as they evolve!

Wednesday 11 September 2013

Losing Perspective

While Jared has been busy refining and building up the Asciilands engine (now with rudimentary combat!) I've been starting to flesh out our palette of sprites and tilesets beyond the basicTerrain.ts of testIsland. Before too long, we'll have all the video game staples: grassland, forest, desert, jungle, snow world, swamp. The challenge will be to create and use them in a way that doesn't just feel inspired by the forestworlds, desertworlds and iceworlds of video games past.

I think part of the solution involves getting a better sense of what these places actually are like outside of, say, Minecraft. So today I decided to learn about swamps, and bogs, and muskeg, and bog mats.

The swamp land will probably be closer to the beautiful alien landscapes muskeg creates than traditional video game swamps. With swamp monsters.

With apologies to National Geographic


Bog mats probably won't feature in Asciilands, but they are incredible:

From Written in Stone; the lake is 20 feet deep


In any case, I've finished work on a very videogame-y test area that swaps to two dimensions. Even though everything works exactly the same as anywhere else in the game, abandoning the isometric perspective makes everything feel like a Super Nintendo era platformer. I'm not sure if it's a good fit for Asciilands, but the effect is interesting. Have a look:


Saturday 31 August 2013

Little by little the big jobs get done

I catch the train for two hours every working day and this time is dedicated solely to development of Asciilands. That's at least ten hours a week plus extra bits of time that I find for the project. This means that the rate of improvement and refinement is very constant and satisfying.

Sometimes, however, there will be a major change that requires more than a one hour block and needs to be done all in one hit so I'll have to save it for the weekend. The last one was to completely rebuild the way the map was rendered from scratch; the one I just completed was re-writing the way the javaScript handles the directional input so that the controls feel more like the RPG games I grew up (better handling of multiple key-presses / releases in various combinations). I've always felt that the feel of the controls of a game can make or break it and I don't want Asciilands to feel in any way sub-par. It's feeling good at the moment so I am, too!

In other, more visible news; the interface has been completely re-imagined! No more nastily placed windows, no more top-left aligned map! It looks like a game now!


The map feels much better in the middle, especially when the light radius is shrinking and growing. Having the player right in the middle always rather than jumping around because of different draw-distances is much more user-friendly.

The other panels of information work much like they did previously except for the Text panel which is part of a new method for making the server-side code interact with the user interface. The new method allows for more interesting interactions than just displaying text. The example shown is a book that allows the user to turn the pages.

Oh the possibilities!

I feel I must apologise, or at the very least acknowledge that it's hard to get much out of these posts when so few of you have used it hands on but some of my more technically inclined friends might be interested in some of the methods and lessons being learned behind the process.

Tuesday 27 August 2013

Welcome to Test Island (27/08/2013)


Today I made some cacti. They are static props made for desert areas. If you want to see them in inaction, you now can - on the Asciilands Test Island video tour.

It's a beautiful place, even if Jared did, for reasons unknown, remove my cow. 


In other news, this blog is now the top search result when looking up 'Asciilands' in google! Bing and Yahoo haven't worked out that we exist yet, while duckduckgo links here.


Thursday 22 August 2013

Quick update

Just thought I'd give a quick update on what's been going on with Asciilands.
List format!

  • Further optimisations
    • Literally halved the number of AJAX queries and reduced the total amount of transmitted data by about 30% (with 0 compromise on any user-end aspect)
  • Entirely rewrote how interface updates are sent and received. It is now much less grueling to set up a point of communication between the interface and the update system and we can send more interesting updates to the interface:
    • Updates used to be restricted to text and the text would appear in the various panels. Setting up the targeting and deployment of these messages was a pain the bottom so it's has been thrown out, simplified and re-written.
    • We can send other stuff now, too! One example is view dimensions; you can walk into a dark cave and the view shrinks so you can only see three squares in any given direction but then when you pick up some kind of light emitting item, the draw distance is increased to eight squares or something like that. Previously this would have required a refresh.
  • Objects used to behave in an "out of sight, out of mind" kind of way. By that I mean if you're being chased and you manage to out run them to the point that you can't see them anymore, they would no longer move. It also meant that if you were standing in a spot where you couldn't see any other objects, you can be sure that no objects would enter the screen. The system would only action visible objects. Obviously this needed to change or else having a really tight view range in a dark cave would actually be advantageous. There is now a much larger, fixed "action area". this is obvious and it probably should have been like this the whole time but hey, I'm still feeling this stuff out.
  • Other little things have been added like other experimental NPC behavior and pushing blocks now slows you down so you really need to push.
    • NPC behaviors now include an NPC that will follow you when spoken to and stand still when spoken to again (much like the NPCs in the Half Life franchise).
    • Objects with chasing behavior no longer track the player but instead track a "target" object which may or may not be the player. This is another step in the direction of complex interactions happening between NPCs without player involvement.
  • Other stuff, I can't remember it all. It probably doesn't make a whole lot of sense to people who have never interacted with the engine in the first place. Just letting you know that things are moving forwards! 
  • Soon to come: Major change to the way the interface is laid out. Floating panels get the job done but ultimately suck. As the information on the UI gets more complex and varied, the panels are less and less able to communicate the game state effectively.
I'm not on either of my Asciilands dev machines so I can't give you a screenshot however I will share this:
I have the best girlfriend in the world and she made me these pancakes:
This is the first ever Asciilands fan art AND the first ever Asciilands food-via-social-media post!

Tuesday 13 August 2013

2,000!

2,000 lines of [functional] code in Asciilands!*
Well, a few more but close enough.
Turns out those lines didn't go as far as I had predicted and while it is largely playable, most of those lines just went into optimisation. This is exciting nonetheless; the size of the rendered view can now be quadrupled with no noticeable impact on performance, even on my sub-par laptop!
Any optimisation means that we can push the limits of what is possible. A larger view can mean many things. Already we were using a tiny view for dark areas but a significantly larger view? Who knows! Maybe climbing up cliffs will give you a good vantage point! Maybe some items will allow for greatly improved visibility. The average screensize is now a factor in the size of the view more so that the lag created by the old method of rendering the view.


There's really not a lot to report apart from the whole 2,000 lines thing and that the engine is progressing nicely. All previous capability has been restored and new capability added. It feels good to be ahead again with things running so much more smoothly after a do-over.

There are a few more systems to re-write in ways that make more sense when used in combination with the re-written systems but that stuff should be done within the week then onward to the combat engine!

Also thanks to those few who have helped test Asciilands! If you are interested in testing, just let me know via any means available to you. All testers are appreciated and will be mentioned in credits / as NPCs / recognised in some way in the finished product. All contributions however big or small will be remembered and credited.

Arbitrary screenshot of something new:

*Line count calculated by searching for line terminations ( ; ).

Tuesday 6 August 2013

Blog now open!

The blog is now open to the public!

I haven't done an update for a while and this is mostly because I've been revising a lot of old code and only added a tiny bit of new functionality. I'm trying to get the engine to a point where we can just churn out content and flesh the game out into a good, playable experience.

To ensure content is kept fresh and diverse, the engine needs to support the creation of complex characters and behaviors and allow for the easy creation of additional behaviors as well as ensuring the parts of the world can interact with each other, not just the other players. This is what will make the world feel much richer and engaging.

Dev tools are being developed alongside as ever to make contribution easier for the keen.

As far has having something releasable goes, Asciilands is at least 90% there. It currently stands at 1,833 logical lines of code and I believe it will be something rather playable by 2,000.

Can't make a blog post without a screen shot, right?
Here's something you haven't seen yet:

Tuesday 23 July 2013

...forget everything I just said.

Objects no longer work like that. The current system is similar to the one described but the previous post's version had too many limitations that were not obvious until I started trying to do unobvious things.

Welcome to rapid application development!

Ok, in fairness, it's mostly the same. The six-phase collision is out and a new three part behavior system is in. Collisions now happen in two phases and automated behavior in another separate phase allowing complex behaviors to be coded, combined and then triggered for different reasons.

I'll post about the changes before too long and hopefully I'll have some video to share.

Thanks to the people who helped test Asciilands recently! Also, if you want to help test the alpha / beta versions or just see it in action, let me know by any means available to you.

Saturday 6 July 2013

Behind the Curtain

I thought I'd make a slightly more technical post about some of the behind-the-scenes goings-on with Asciilands. After all, most of the people invited onto this blog are fellow developers or coders of one sort or another. First up, a look at how the map is rendered and how we keep the lightweight stuff lightweight and the heavyweight stuff to a minimum. After that we'll touch on the interactions between objects and why they are so crucial to pretty much everything.

Asciilands is like...onions.

First up, a bit of nomenclature:
Map - The entire cached area (e.g., all of testIsland). When the player moves from testIsland into bluffCave, they are in a different map. A map can be any size. TestIsland is 139 * 71.
View- This is the 21 * 21 grid shown to the player in the panel. The view is just the visible part of the map. The view is [at this point] always 21*21.
Tile - A tile is an arrangement of six characters which form a [almost] square. The only player interaction it is capable of is either allowing or disallowing a player to move onto its square in the grid.
Scenery - A sprite which appears on a tile. It is merely decorative and, like the tile, can only permit or deny entry to its square in the grid.
Objects - Objects are representations of interactive items. I'll come back to this.

I'm a visual learner so I came here armed with diagrams. First is a screenshot of a view with indications of which parts of the grid are occupied by elements from which layers. Babble.


The red markers are from the tile layer, the yellow markers are from the scenery layer and the purple markers are from the object layer. The lowest yellow marker is highlighting the cracking on the wall; this is subtle so I thought I'd better mention it.

The two purple markers are on a sign (which can be read) and a block (which can be pushed). These are interactions too complex for scenery.

Tile objects are the most basic; all they have is a background colour, a foreground colour and a bunch of characters used to make them up (either static [like the bricks] or randomly allocated [like the grass, sand and water]).

The view is composed like this:


The view is like a cookie-cutter that cuts down through all layers; objects on top, scenery below that and tiles on the bottom. Objects from lower layers show through in the gaps of the layers above and tiles set the default characters and colours to be shown in the spots for characters which aren't occupied by the sprites above them.

Now why did I say that thing about objects being a representation of an interactive item? Well it's sort of complicated. Basically, the object only exists within the context of the map. For example, the player cannot collect an object. Previously seen coin and weapon objects which can be collected work like this:

The coin object has a sprite, a location and an item. It also has instructions on what to do if various things interact with it.
Confused? I'll keep explaining and maybe it'll make sense. Maybe it won't. Not sure.
The player collides with the money object (this happens when the player attempts to move into the same grid-location as the object) the object then disappears and places the money item it was storing into the player's wallet. If say, a push block collides with the money object, it crushes it so the money object, along with the item it was holding, just disappears.

Wait, this is moving into explanation-of-collisions territory, time for a change of sub-heading.

When objects collide!

A collision takes place when one objects attempts to occupy the grid-location of another.

There are two important things which come out of a collision. The first is the behaviors and interactions between the two objects and the other is whether or not the object attempting to move will indeed be able to enter that grid-location.
The collision itself is made of of six parts; the pre collision, the collision, the post collision, the pre reaction, the reaction and the post reaction. Each different object type has a different combination and range of behaviors that are triggered in the various parts of the collision.

First I'll show a diagram of which of these behaviors are triggered and in what order. That way you can picture what's going on as I explain it:


The diagram shows two objects; the instigator is the object attempting to move to a new location in the grid and the receiver is the object which is already occupying that location.

For the sake of demonstration, let's look at the interactions taking place when a player attempts to push a block into a sign.
There are two collisions taking place here; one between the player and the block and another between the block and the sign.
Firstly, the player's collision behaviors would be imposed on the block then the block would react.
In this instance, at this time the player has no collision behaviors; the player only makes requests to move and other objects react so let's look at the block's reaction:
The block recognises that the player is trying to enter its location so it attempts to move along one tile in the same direction as the player. In the absence of the sign (or any other obstructing entity), the block would make this move and then return true. Why? Because it is now true that the player is allowed to enter the space into which it attempted to move.
The block's calculation of direction, attempt to move and response as to whether or not it DID move are all done inside the reaction phase. This is because the block reacted to the player's collision with it.
The plot thickens, however, because as port of the block's reaction, it attempted a move of its own into another occupied grid-location.
The sign has a reaction behavior which tells it to display text to the player when the player collides with it however since it is a block, this behavior is ignored and instead it simply returns false. False meaning "you can't come in here, I was here first" and so the block's attempt to move is unsuccessful and it stays where it is. Since it hasn't been able to move out of the way of the  player, it too sends the "false" message back to the player so that the player is, similarly, blocked (no pun intended) from entering that location.

In this example, the final order of operations is this:

  1. Player pre collision (nothing)
  2. Player collision (nothing)
  3. Player post collision (nothing)
  4. Block pre reaction (nothing)
  5. Block reaction (See what's trying to move it, attempt to move on account of instigator being a "player")
    1. Block pre collision (nothing)
    2. Block collision (See what I'm being pushed into and update thought  panel with hint as to why I am or am not moving)
    3. Block post collision (nothing)
    4. Sign pre reaction (nothing)
    5. Sign reaction (See what's instigating this collision, do nothing since it's not a player, return "false" to forbid entry)
    6. Sign post reaction (nothing)
  6. Since the block was unable to move, the false bubbles upward to the collision with the player.
  7. Block post reaction (nothing)
And so nobody moves!

It's a difficult thing to explain and I'm sure an even harder thing to understand but hopefully you have at least some insight into what's going on when you're moving around in Asciilands eventually!

One thing some of you might have noticed is that there seems to be a lot of waste. The pre and post behaviors all did nothing. This is because those interactions happened between vanilla objects. The pre and post behaviors will be utilised by custom objects with special behaviors.
Take the light wand for example:


The light wand is a custom object based on the collectObject code. It has a special post reaction behavior which makes it light up the room when it is picked up.
I recently did another test of custom object capability and created a zombie. The zombie code is exactly the same as the human code except that the zombie has a pre collision behavior which makes it turn the receiver into a clone of itself if the receiver is a moving object. This means that a single zombie can infect every person in the map and they can infect each other and the only change required to create this whole dynamic was the addition of one behavior.

It's all about leaving room to fill with custom behaviors to create exciting and diverse custom objects.

I think that's enough from me today. I'm experimenting with some screen capture stuff to record some videos but Blogger doesn't like the size of my files so I might try to make them shorter. Feel free to shoot me any questions or ask me to better explain anything I may have just glossed over.

Until next time!