2012-11-27

Weekly update MS04x03

I didn't do anything. And I am a little bit too tired to be ashamed ;)

At the moment, after coming back home, I am working as support service for our application which after around 10 hours a day makes me just want to walk the dog and go to sleep. And talk to my wife for a while.

I was thinking a lot about tasks for this Milestone. How to approach everything. What works for me, is to outline big picture and fill it with smaller things. And if something doesn't fit, I am not affraid to modify work already done, if it makes sense.

For this Milestone I planned three things:
  1. Proper rendering/display system.
  2. Different regions of world.
  3. Travel system.
I want to focus first on rendering system but while this task seem to be obvious, I will give more details on how system will work while I will be working on it.

Different regions of world will be just barely touched, as I plan to develop this idea during MS6. While I have code to handle different regions, I don't have anything to describe them, so that's what will be done now. And some little code to generate random maps.

Travel system (and map) is something that I want to give more time, but now I'd like to focus on just creating stub that I will develop later. This stub will be just some mini-game (as I am working on Dragontorc remake, this will be probably something very similar to original Dragontorc game). When I will start working on UI, I will add map, so if game designer desires, locations may be accessed in random order by player (with some limitations), as opposed to travel from one point to other through different locations. Or it can be used for cities.

2012-11-21

Weekly update MS04x02

I dislike working with poorly designed and written code. Bigger it grows towards hate, the longer I work with it. And it is going on now more than a year. When we were shipping our previous game, I didn't mind working 12+ hours a day, 10+ hours on Saturday and sometimes on Sunday. I was tired, but I didn't have problems with that. Now I work mostly around 10 hours a day from Monday to Friday and I am just fed up. and tired even more than two years ago. Having other things to do after work gives me a relief. Same thing happens when I do some coding for Dragontorc but especially after few hours of coding Dragontorc during weekend, going back to work was really painful. And I didn't code last weekend, but working with code on Monday was as joyful as any other time.

Because of what I did on last Saturday I was exhausted and wanted to do something mindless on weekend. That's why my last week's work are just few minor things and didn't even test them:
  • anchors are used for held objects
  • added assistance when entering doors
  • added global options mostly to try different scales
  • for state machine decision rules when dealing if current/requested dir, it takes into account current appearance dir, not actual dir (it looks better)
What's wrong with scale?

I knew that there is something not right but I only understood it when I saw video I did for MS3. All characters are extremely small comparing to original games. In them, characters were jsut a little bit smaller than doors and in mine remake, they are half size of doors. That's also reason why I added assistance when entering doors, because even now it might be problematic to enter doors (you bounce off frame too often).

2012-11-16

AI (AI BASIC)

As you could notice with AI behaviours, I like to keep things modular and hierarchical or in straight flow. I don't have now anything really high-level for AI (on second thought: some behaviour setups can make it work), but you can still divide AI logic into to separate layers. AI behaviour tree that manages behaviours and interior of every single behaviour.

I decided that I want something simple to write, read and run. Behaviours may run in parallel and I wanted to have system of messages (more on that later) and this can bring enough complexity into system, that having some strange setup of behaviour itself, would make whole thing useless.

All I needed were just commands "what to do" and some basic flow operations (if, goto is completely enough). I talked to my colleagues and they of course told me, that there is LUA, that there are other scripting languages. While I would like to have whole logic run on LUA in future, I wanted to experiment with modular design and after looking for a while after some nice scripting language, I decided that it might be much better to create my own one.

This decision let me create syntax that suits writing AI. Adding commands such as "move there", "wait until you get there", "find all enemies around" with just single line and as similar to normal english as possible was my top priority. At some point I considered creating something simplier, that would look like assembler but I dropped that idea. BASIC was the best choice. And  I am talking about normal, old school BASIC, not objective-based language with BASIC keywords. Just plan BASIC. If, goto, gosub, let and so on (sidenote: I don't have "for" nor "while" at the moment and I don't have need to add this, at least not yet).

I needed to write parser that translates code into p-code and something that will run that p-code. P-code resembles assembled code. These are just numbers and that works pretty well. Of course I had problems with parsing as some of keywords might be problematic in some cases. For example I have "to" operator that works as random operator. "2.0 to 3.0" translates into "a random number between 2.0 and 3.0" but it is used also in other places, such as writing recipent of message "to $someone". Yes, I have "$" in front of variables and only because it makes it easier to parse them...

But while I have just very basic subset of BASIC commands, I added much more to handle AI. I will give you an example now:

local distance
local circlingDir
; setup values
go sub ChooseDistance
go sub ChooseCirclingDir
Start:
movement clear
movement move to $MyEnemy at range $distance and keep
movement circle around $MyEnemy by $circlingDir and keep
movement face $MyEnemy
wait 1.0 to 3.0
if 25% chance
go sub ChooseDistance
endif
if 15% chance
go sub ChooseCirclingDir
endif
go to Start
; subs
ChooseDistance:
$distance = (1.0 to 2.0)
return
ChooseCirclingDir:
$circlingDir = (-90 or 90)
return 
What does it do? Circles around MyEnemy in random direction ("movement cirlce around") at random distance ("movement move to ... at range"). Both those values change from time to time (each chance happens at 1 to 3 seconds interval) with random chance of happening.

Simple, isn't it? I already used something similar with project I worked on. Although I just created functions that had some of functionality visible above. Syntax was a little bit more complicated and less flexible, due to limitations of language I worked with.

There are also priorities for behaviours, ending behaviours only at some priority level with some time allowance. You can even execute code in other behaviour or from other part of code (such as message handler).

And on messages I will focus next time.

2012-11-15

AI (behaviour tree)

When I started to work on Dragontorc's remake, I wanted to do just a remake. Make it small and quickly. After first milestone I was driven off by animation system but then I realised, that I can do something great in that field in my current work, so why not go back to work on Dragontorc? And why not to make it bigger? To allow people modifying, adding new content.

That's why during MS2 I decided to extend events and items. And while I had plan for whole game created and didn't want to change it (because it doesn't affect anything but me), I decided to extend other things. And to make systems that I could use for other kind of games. It might be even possible to adapt system for space simulator (it will require implementing different movement, etc. although it is possible to keep whole AI code the same! Although spaceships may behave inappropriate as instead of being on enemy's six, they would be circling around, getting closer to fire and move back, but for TTP action game it will be just fine). This is also reason why I wanted to keep things modular. In future it might be possible just to change renderer, animations and interface and turn Dragontorc into 3D FPP, TTP or isometric adventure game.

So here is the background and reason behind my choice to spend so much time working on AI. And now the details, what's inside and why.

As I already mentioned, AI is behaviour based system with messages. What does it mean?

AIs mind currently is tree composed of behaviours - every leaf is a behaviour. Whole thing is set up in such way, that any leaf can be replaced, so it is really easy to reuse behaviours for different characters.

Main node might be a behaviour that decides what AI wants to do. Currently all AI characters choose between three actions:
  1. Attack enemy (if there is enemy in current room)
  2. Go to door (enemy could leave room and we go after it)
  3. Idle (just wait patiently)
Main behaviour switches between children behaviours. If it notices an enemy, it chooses attack behaviour to be current one. It ends all other behaviours by doing so, but remains active (to notice if anything else happens).

And all children behaviours can be separate trees. For example Attack behaviour could have two children:
  1. Attack enemy
  2. Observe enemy
It may look at current situation or communicate with it's allies to decide wheter it should attack now or just observe and give way to anyone who would like to attack.

All behaviours may run in parallel. There can be even two (or more) instances of behaviour on same leaf node (although I would strongly advice against doing so).

Such behaviour system is quite modular and separating how creatures moves and attack from it, makes it even easier to have classes of characters. It might be even two basic ones: melee, ranged. Or it can have more variants - melee aggressive, defensive, cooperating, ranged that just shoots from time to time or tries to get to best location and shoot from there. But actual creatures may look very different, move different and have different attacks.

How? Well, behaviours just use references of different objects and those references are translated into proper objects using creatures look-up/translator/dictionary/library. At the moment wisp moves in zig-zags and appears to be floating, velocity changes over time, while skeleton seems to stand strongly on ground, velocity changes quicker. There might be an orc that moves slower than skeleton, has more powerful attack, but may decide on actions to make in the same way as skeleton (although it is tempting to make it possible for orc to disrupt skeletons' attacks with loud roar and charge into enemy instead of behaving just like skeleton, but with such system, it is easy).

What are other things that I gained by implementing such system? I don't need to recompile whole thing. I plan to make it possible to reload things while game is running to make it even quicker and easier to test. And of course people may alter behaviours and add new ones quite easily.

What are the problems? It is slower than AI driven purely by code and it took some time to create it.

I've seen quite few implementations of AI in my life and when I compare mine approach to others I have to say that while it isn't the most robust, it is probably the easiest to extend and few other approaches may be implemented with it (if not with behaviours, then with just AI BASIC code that is inside of them). One thing that is not possible for sure is stack of behaviours. I could do it and it could run in parallel and maybe, if I will have a need for that, I will do so, but from my experience, I know that this may end up with AI that constantly changes its mind or AI code is just huge mess of conditions, checks, etc. It is much easier to have separate layers representing different needs and switching between their children believing that each one of them will do their own role properly.

2012-11-14

Queries

Queries are not mine idea. I "stole" it from my colleagues at work who got it from other places (that's how I learn about AI most of the times, via other people or recently at conferences).

Queries can be used to find any object or group of objects that match some predefined conditions. For example there can be query to list all doors in room we're currently in and sort them from closet to furthest. There can be query to find all enemies in front of us. There can be query to find anything that scaries us, so we could run away from it.

Query tests all given objects (it can be done for list of objects provided by other system or gather all objects in room, requester is, or do something else) by processing query elements on them.

Query elements can be broken into two categories:
  1. Conditions - if condition is failed, object is no longer considered.
  2. Weights - they do not throw away object, but just add "weight" value that tells how important is given object. It is used to find most interesting of few or sort many of them.
There are also passes. If in first pass no object is found, second pass (with different elements) is done and so on. As many passes as there were created.

I am still extending functionality of queries and more options are coming, but basics are there. It checks type of object, distance to it and wheter it is alive or not and if it is thinking object or not (AI or item basically). And there is two extra elements. Rating and Rating Rules. They work with Tagging and Rating systems and can be used to determine if we're scared of an object, if it is enemy or how much we like something or dislike.

Where querries are used? At the moment just for AI but not only by AI behaviours but also for actions/attacks. Attacks need to have enemy and if it would not be provided by AI, it would be found with query. And due to telegraph and possible enemy movement, target might be no longer valid when actual strike happens. That's why in moment of strike, query is used to verify if enemy is still valid.

2012-11-13

Animations of Dragontorc (2)

I described some bits of animation system in Dragontorc already. That's why I will just focus on new things that were added since then. I might miss some things and I am starting to consider creating a wiki page to keep all details there. It will also work as a documentation for modders. But now, I will just shortly describe bits that I remember, in random order.

First I want to settle between 2D, 3D etc. I probably already did that but I this is also good place to mention in. I want Dragontorc to be done in 2D without any 3D stuff and actually without anything fancy - as far as I want to go with effects are alpha blends. This limits me a little but also focuses on particular things.

Anchors
Anchors are named points for any object. These points may have different functionality. "Point of attachment for held objects", "Point from where projectiles fly", "Point at which particular particle effect is played". At the moment they are used (in code, I had no need to do that for current characters) only for projectiles' starting position, but I want to add "held" anchor.

Animation moods
Mood is used to determine which custom animation should be played. Currently different parts of animation tree may force their own mood and when custom animation is requested, it will be chosen from few. Similary death animation might be chosen basing on particular mood.

Events
I try to keep things clean and to work with flow that AI orders gameplay systems to do something, for example action handler, action handler orders animation system to play animation, animation triggers event that goes up to action handler, that does stuff that affects other entities in the world. That's why I try to avoid AI doing anything that could be considered as physical activity. And that's why I like animations to do some physical stuff or at least to be physical instigator to it. What do I mean by that? Well, I don't want to adjust timing in AI when I want to do damage at particular time in animation. I don't even want to know what animation will be played. I just want to order animation to be played, other system will choose right animation and animation will know when to trigger something. And how it will trigger it? With events.

Limiting movement
Another thing I like to keep clean. Movement. It is up to animation to decide if it is appropriate or even possible to move at given time and what is possible. Movement module may order to move in any particular direction but animations may limit movement to be possible only forward or not possible at all. Or character should not rotate or should rotate at constant rate.

Movement styles
This is related more to movement itself but might be considered as part of Animation. With movement styles it is easy to affect path and speed of movement. Character may then look as it is drunk or is walking not on straight line.

Playback rate adjustment
Depending on current speed playback rate of animations changes, so if character moves faster, it will move its legs quicker.

State machine decision rules
I added also some new decision rules for state machines. They check movement styles, requested direction (in relation to current direction or movement or requested direction of movement) and few others.

This is short and not definite list of changes for animations. And it turned out when I was adding items, that it is in alphabetical order (with one exception, I decided to add Movement styles after I finished the list).

And now I am sure that I will have to create wiki page for all of this, as this is just mentioning of features but they will require clarification and examples of use (and someone to correct all my grammar and vocabular errors, and to be honest, my grammar isn't much better in my mother tongue, even my wife sometimes makes fun of me because of that).

2012-11-12

Weekly update MS04x01

As you can see, MS3 is finished. I haven't started anything for MS4 and I will describe plans for it in a separate post, as well as different subsystems that were created, what went good and what went wrong with them.

First, quick list of things done during last week:
  • fixed some AI BASIC bugs:
    • behaviour related functions not working properly
    • incorrect loading of message command which treated reciepent as parameter of random operator
  • fixed stats stack not being setup (which resulted in not affecting damage done by or to wizard)
  • fixed regional checks for projectiles shot by player (to have same behaviour as in original game)
  • fixed missing relative dir in relateive direction state machine rule
  • added error message when loaded type is not recognised (I spent some minutes on looking for a bug in code that wasn't there because I named few objects incorrectly in xml file)
  • projectiles deal damage to objects just one time and should not hit someone who fired them
  • fixed default height
  • added "vanish" animation (used by wisp and wrath now)
  • simplified some AI behaviours code
I noticed one thing when I created video for MS3. I haven't paid much attention to it, while I was working on that. I just had a feeling that something is wrong. Scale. All characters are too small (or rooms are too big). So one of the things for this week is work out better scale. This problem reminds me of one Jet Set Willy remake which was way off with movement and jumping. And everything seemed to look very small. And while I think that movement that I've done for characters in game has feeling of Dragontorc, scale is definetly wrong. Fixing scale will also introduce with other issues - it will be much harder to enter door, so I will have to do something now, although I planned to do it later - some little code that will assist characters while entering door (for player, when they're approaching door, for AI when they want to go through door).

And game is now... ugly? It has original graphics for some objects, but you can notice many problems with displaying them correctly. I want to create proper rendering system during MS4 - and again, I will share some thoughts on that as well. I should start working on it during this week.

One more thing - I want to track how many weeks have passed since beginning of MS. As I have more than 10 MS planned (but they should be shorter than MS3 :) ), MS number has two digits. And I expect that some MS may take less than 10 weeks but some will be longer, that's why week number has also two digits.

2012-11-08

Dragontorc MS3

Finally, MS3 is here.

What has been done in this time:
  • Basic graphics with animations and animation tree (part 1, part 2)
  • AIs (hierarchical behaviours with message system) (behaviours, AI BASIC)
  • Tagging and rating systems (link)
  • Queries (link)
I will describe each of the systems in following days/weeks (and provide link here, and I see that I already described some bits). But for now, just watch video


What do we have here? Bugs with displaying graphics, but as MS4 brings proper display system, I didn't want to spend much time on that.

Enemies. All enemies have same main behaviour (attack, idle, go to door). Attack behaviour differs.
Wisp only goes through enemy giving damage while touching it.
Wrath circles around enemy and shoots fireballs.
Skeletons cooperate with each other, circling around enemy and one of them at a time attacks. After attack skeleton moves back and lets other skeleton to attack.

I will describe how it is done when I will be writing about AI.

At the moment I use original graphics with few changes and one new animation (skeleton attack).

I also want to change weekly updates to provide more info than just bare facts. So stay tuned.

2012-11-06

Weekly update

This should be last weekly update for this Milestone.

I am almost there, few things to fix and tweak. I could show what I have now, as it looks ok and meets requirements I had for this MS but I really would like to fix and polish things as this will reduce amount of work in future.

And just as formality and to keep current shape of weekly updates (well, I am still going to do this in future, but focus also on other things):

  • AI behaviours can no longer be chained (so child becomes parent of its own parent)
  • added logging to file (I need to create utility to filter log file and to display objects)
  • extended functionality of projectiles
    • they can be fired exactly on spot or in general dir
    • they can harm only objects with given rating (for example: enemies)
  • more logging and minor tweaks and fixes
I plan to finish everything and post information about MS during this week.