Σελίδες

Τρίτη 5 Ιουνίου 2018

C.L.A.S. A flexible design pattern for video game AI.

AI for video games can become a complex and frustrating thing to make. It is something that can become overwhelming relatively fast enough for the developer that is tasked to implement it. Back when I was working on my cancelled RPG project I had to deal with the problem of creating a complex AI myself. I had to drop the work I had done and redesign the AI system from scratch a number of times, because as I added more and more features, complexity would grow so big it would become chaotic to work on it. Eventually I ended up with a design that kind of work best from everything I've tried. Although I gave up on making a huge RPG all by myself and decided to work on a smaller, more manageable project (a FPS), I decided to use the general design I had used for the RPG, on the FPS, because I knew that this particular design scales well, even though the AI complexity of the FPS I'm currently working on won't reach the levels of the RPG. So I noticed that I was using a pattern, a design pattern specifically for video game AI but I didn't gave a lot of attention, until today. Today I read a thread on r/gamedev where someone shared his personal adventures of trying to work on AI. I realized that other people might not come up with a system like my own or perhaps something different that it suits them anyway, so I thought that it might be a good idea to share the design pattern I came up with, because it might help some people.

The goals of CLAS:
So here I will talk about C.L.A.S. (Character, Logic, Actions, State), the flexible design pattern for video game AI that I came up with and use. The main goal of this pattern is to make developing and maintaining complex AI for video games an easier, simpler, and faster, thing to do. It achieves that by applying two popular design principles:

1) By applying the design principle of Separation of Concerns, to divide the AI system to individual components in a way so the system is modular and makes sense.
2) To further reduce complexity by applying the KISS principle. This is done by minimizing the use of individual classes and inheritance. 

The architecture of CLAS:
CLAS applies the software design principle of SoC, by dividing the AI system to four distinct components:




1) Character: This component contains all the data that shape who the particular AI agent is, and what's his/her status. Things like the maximum movement speed, the current and max health points, specific behavior patterns etc that shape up the character's well... character, are set on this component. Imagine typical Character Sheets of pen and paper RPGs, in a digital form. In fact, this is how I came up with it, as I was developing an RPG and I was looking at the old traditional non-digital RPG games to start from scratch.

2) State: This component's job is to let the AI agent know some things about the state of the world. It deals with triggers, raycasting, and such stuff to let the AI agent know things such as "Am I in an area with toxic gas ?", "Do I have a direct line of sight with the player ?", "Am I on fire ?" etc.

3) Logic: This component has a method running each frame. I personally implemented in it a kind of Behavior Tree, by having a method that runs each frame with a bunch of if/else/elif statements, that call even more methods with if/else/elif statements that also lie on the same component. But you can go on a more GOAP style approach and use weights if you want. The purpose of this component is to decide what the individual AI Agent should do given the current state of the world provided by the State component, and the specific character of the AI agent, provided by the Character component. So each AI agent decides how it should respond dynamically given who it is, and what's the situation it's on.

4) Actions: This is a pool where all the individual methods of actions are. Methods like "ApproachTarget", "ShootTarget", "LookForAmmo" etc. The Logic component calls methods from this component. Not all AI agents are going to use all the actions in the Actions component, but it is good to have all different actions an AI agent can take in a single place.


Summary:
Each AI agent carries the exact same versions of the State, Logic, and Action components. You customize the agent by changing values on the Character component, and the rest of the components do the rest of the job. If you want to create new actions or variables that will let AIs know more of what's happening, you do it in on the corresponding components, so it's easy for all different AIs to access the new stuff. You also skip inheritance in the process. Since you customize each agent on the Character component, and the world state data, and actions are available individually to all actors, you can get away by changing values in the Character component, and then make prefabs of agents with different values instead of building a new class for each different character type.


The practical benefits of using CLAS:
So with this design pattern each AI agent has a copy of each of these 4 components. Here are some of the benefits you will get by implementing this pattern:


1) Debugging will become a lot easier, because if there's a problem you will know where to look for it. You can track down bugs easier. If there is a problem with collisions or raycasts, you know you have to look on State. If the AI does an action it shouldn't do given the circumstances, it's a problem you have to fix on the Logic component, and so on.
2) Adding or changing actions, logic, or things you want the AI to know about its surroundings will be easier. Because everything is nicely organized and separated.
3) Editing and creating new variations of enemy types / characters, also becomes easier. Instead of having numerous different classes you have to maintain, you only have a limited number of them, no matter the amount of different character / enemy types you want in your game. In many cases you will only have to change some values in the Character component if you want to add a new enemy type.

Τρίτη 1 Μαΐου 2018

4 weeks later: Results

At the 3rd of April I wrote a post regarding my decision to stop working on a RPG I had been working for a whole year, because I realized it was a project too large for me to do on my own in a reasonable span of time. I decided to start working instead on a simple single-player FPS, as FPS games tend to be generally a lot simpler than RPGs. A week after I had started working on the FPS, seeing how much faster the game was progressing I estimated that it would take me about a month to have all main systems of the game functional. I'm talking about gameplay mechanics such as shooting and jumping, and systems like saving and loading the player's progress, etc. Although a year had passed, I still hadn't reached that milestone for the RPG game. So I came up with the conclusion that a RPG requires at least 12 times more time than a FPS. Again, I'm referring to single-player only. So what's the state of my FPS game 4 weeks since I started working on it ? 

Early version of the Shotgun's 3D model.
First of all let me start by saying that I did get the basic systems on a functional state. Here is how my development progressed week per week: 

Week #1
  • Player movement (walk, sprint, jump,crouch)
  • A functional "gun" with bullet physics
  • Working simple Enemy AI that shoots the player if it sees him.
  • Working medkits and ammo pickups.
  • Minimal gameplay GUI that reports stuff such as health points and ammo.

Week #2:
  • A slot for an active weapon, and ability for the player to cycle his weapons
  • Working doors and keys. 
  • Secret Area Triggers
  • Collectible Items
  • Enemies dropping their guns on death.
  • Four new functional weapons.
  • Body Armor
  • Bullet Spread
  • Effect that makes the screen red when player takes damage.

Week #3:
  •  Weapon Inertia, that animates weapons as player moves.
  • The screen that shows when the player dies.
  • A timer that counts the time the player spends in each level.
  • Bullet holes
  • A Pause Menu
  • A Main Menu
  • Saving & Loading System
  • Preparation of the Audio Mixer, creation of Mixer channels, addition of some sound effects.

Week #4:
  • Options Menu
  • Screen that allows the player to choose which save file to load.
  • Post processing effects added and tuned.
  • Difficulty settings that change a number of things.
  • A trigger-spawn point system, so when the player gets in a certain area, something is spawned somewhere else. (e.g. an enemy, a power-up)
  • Static Analysis, Code Cleaning, AI Stress Testing, various optimizations
  • 3d-Models of 3 weapons and a few animations for them.
I've got the main and absolutely necessary systems working. Not only that, but I moved on to the next step, preparing for a First Playable. From what I gather through articles on the internet, "First Playable" is a state between prototyping and an Alpha, where all the main systems of the game work (although more might be added later on, and some might change), and there are assets representing the final product, but still unpolished. So I'm currently making some assets. I started from making the 3D models of the weapons, and then I'll add  animations to them, sounds etc. After the weapons are made, I will work on the enemy to give it an actual humanoid body instead of the egg-shaped whole-white mesh it currently has. Then I'll build a testing level to test out gameplay, to help me fine-tune various mechanics and perhaps give me ideas for new ones, and then I'll focus entirely on content creation.
 
A version of the Shotgun for the "1st Playable" phase.
So I won the bet I placed with myself. I did in less than 30 days of work for an FPS what I didn't do in a year of work for an RPG. Lesson learned. I now feel confident that I managed to do it.

Τρίτη 24 Απριλίου 2018

DevBlog Update: 3rd week of FPS development.

As I promised, I'll be posting an update each week on the progress of my FPS development for the first month, to see if my initial estimation was right. So the 3rd week closes today, and I'm here to share my progress.

What occupied most of my time this week was the ability to allow the player to save his progress any time, even mid-level. That is kind of trickier than saving progress every level, because the state of the entire level, from the position and health of the enemies, to which doors are left opened or closed, have to be saved. It took me 4 days of work to get saving and loading work right.
I've also made the first steps to build the audio system, and I added some sound effects for the most basic stuff like when the player jumps, lands, footsteps, etc. Plus I made the bullets leave bullet holes on various surfaces. These two made the game feel much more "alive" than it did prior.

Bullet holes, yay!
I made several other small stuff like enabling gravity on pickups, having the weapon the player is holding move a bit as he walks around, a timer that counts the time the player spends in each level, the screen that appears when the player dies, and a new weapon.
Furthermore I implemented an Options menu, but I haven't tested / debugged it yet completely, plus early versions of the Main and Pause menus.

A boring Options menu awaits to be debugged.
I feel like I've already done the bulkiest amount of work needed for this particular first phase of development, where I get all the basic and required systems / mechanics functional. There are of course some more steps required, like the screens that the player will use to select between different save files, some scripting for dynamic music, and difficulty settings. And I think a week is more than enough for these, so hopefully in 7 days by now I'll have them working, and thus the bet I placed with my own self, completing the first phase in a month, will be a win. Come back next week to see if I won the bet!

Τρίτη 17 Απριλίου 2018

Second Week on new FPS Development: Progress continues.

It's been a week since my last post in which I announced that I suspended development on the RPG project I was working on for a whole year, to start working on a simpler, shorter game. When I wrote that post I had already been working for a week in the FPS. And judging by the speed with which development was progressing in the new project, I made an early estimation on how much time it would take me to make the basic minimum systems and mechanics work for this game. Again I'll repeat I'm not referring to media like graphics, animations, sounds, etc, but just functionality, provided with code. Also remember that I'm making a FPS like the good old ones, Doom, Wolfenstein, Duke Nukem, and Serious Sam. I guessed a month. So here is in this blog post I'll write down what my progress was on the second week of development.

Some obstacles to test out the jumping mechanic.
So I made doors work, with key functionality included. So some doors will be locked and the player will have to find a key to unlock them and open them. I've also written the code for collectible items that the player will have the chance of discovering while exploring the levels, the triggers of secret areas, and of course the code that records how many secrets, collectibles, and enemies are in each level, and how many the player found or killed. I also made a functional Body Armor pickup, and I coded in 5 more weapons. I don't want to spoil so I will only tell you about the two of them. One is a shotgun with enough spread to hit multiple enemies on the right distance, and the other is a rocket launcher. The rocket launcher is my favorite. When the rocket hits somewhere, the enemies that are in the blast radius loose health, as also the player. Plus if there are physics-enabled objects, explosion force is applied to them, and they fly around! Hehe. It was so much fun, I've spent a good time just shooting away rockets at enemies, boxes with physics, etc. Aside from these I also made several smaller stuff improving stuff that was already there. I also let someone play the game for the first time. There's not much to play yet, I just did some fast terrain editing to raise hills to create a bunch of "rooms", and placed some simple enemies in them. Although the person that played the game is a gamer inexperienced with game testing, and thus most of his feedback was about content (graphics, enemy creatures,etc) and I'm not focused on such stuff currently, there was a single piece of feedback that I found useful. It was about the angle that the 1st person camera is allowed to be rotated vertically with the use of the mouse. The player wanted the ability for the character to be able to look further upwards. To speak the truth, the angle was something I had some doubts already. The initial angle I was using was 45 degrees. I actually just googled it, and found a website saying that it's been considered normal for a person to be able to tilt the head backwards from 45 to 70 degrees.
So I was in the short end of the spectrum, at the minimum limit for a healthy person. But you know what ? Video game heroes, and especially old-school FPS heroes, are more healthy than average, and often have super human abilities if you think about it. So I decided to change the angle limit, and make it 70 degrees. So now it is still within the amount a healthy person can rotate its head, which is required for the game to feel believable, but it's on the higher end, so the player can feel that the character's condition is flawless. I'll try to keep letting people play my game, and I want to have that take place once a week. Even from that early on, the second week.

So that's how the past week passed for me and my game. For the next 2 weeks I'm going to make a few more weapons, and add in stuff like an options menu, saving and loading functionality, etc. My goal is to have the standard game mechanics and systems functional in the first month of development.Then I'll start considering different enemy types, making 3D models for stuff that I have already working functionally (guns, pickups), and testing more to fix any bugs that might come up, and fine tune gameplay to make it more enjoyable.

Come back next week to read my report on what I did in it. If anything urgent happens in the mid-time, I'll make a blog post in between.






Πέμπτη 12 Απριλίου 2018

RPG Project Development Suspended: I should have listened the most popular advice.

If you are a newbie independent video game developer and decide to take a look at what other developers have to recommend for newcomers on reddit, youtube, or various forums, you will almost certainly hear or read most frequently this tip: Start small.


Which is a simple, two word sentence, but it also has some ambiguity. How much exactly is "small" ? What most devs on the internet seem to mean by that, is "Start with a 2D game for mobiles". But at the same time at other threads, blogs, or videos you will find out that the majority of devs giving advice online also give a piece of advice contradicting this: "The mobile market is over-saturated with simplistic 2D games, and the chances of success are very low". So it you combine these two, the message you are getting seems to be: "Start your development career by making a game that will most probably fail". Interesting right ?

I will tell you what. Initially, I was thinking about making a 2D game myself too. I had started doing some programming on a 2D side-scroller, a mix of platforming and beat 'em up, set in a fantasy world. But I realized that at least for me, personally, it was harder to make good enough 2D art than passable 3D art. I made some sprites but getting shading / shadows right was too hard for me, plus painting each different frame for an animation was a tedious repetitive operation that involved considerable trial and error. But making a 3D model animate with bones and a timeline seems more intuitive to me. And as for the shadows, these are done automatically on a 3D environment by the lighting / rendering system. I'll be honest with you and say that I suck in pixel art. And considering how a 2D game must have a unique art-style to catch the attention nowdays, because otherwise it will get lost in the over-crowded 2D market, making a 2D game for me personally seemed like a lost cause. As for 3D art, well I can't have my 3D models look like those of modern AAA games. The amount of detail I can put ranges from PS2 / Xbox level up to PS3 / Xbox360. Which makes them look dated in comparison to modern AAA games, but I think can still be acceptable for an indie game. With these in mind I decided early on that the games I'll be making will have 3D graphics.

 A sprite I made a few years ago for an abandoned 2D 
side scroller, and a 3D model of a rat I made for my RPG.

Initially I dreamed of making a huge open-world, Western, Action RPG. It's my most favorite genre as I love fantasy settings. But after some time I realized that my first game couldn't possibly be the RPG that would redefine the genre as I envisioned it. Something like that would be too much for me, a solo dev. So I decided to cut down stuff and still make an RPG, but with a number of features cut off. I thought I could do that in a timely manner. So, following some advice I read online, I decided to code the gameplay systems first, and move on to creating content such as graphics, quests, and environments later. The advice said that to make levels good you have to have a clear idea of knowing the game's mechanics, how the gameplay plays, so the levels can take advantage of them. So my first phase of game development would be coding all the systems first, and then build content around them. Back when I started the development of the 3D RPG project I estimated it would take me about 6 months to complete this phase, and about 18 more months to build the necessary content around it. So I estimated a total of 2 years development time required. Time passed, and I completed a whole year working on this game, and I still had not completed this phase. I was out of schedule considerably. I had already spent double the time of my initial estimation on this phase, and I still had not completed it. Realizing how far off my initial estimation for the first phase was, I re-estimated the amount of time for the content creation phase, and I added a conservative +50% of time required at that phase. So with the new estimations, the game would take me at least 4 years of work, if not more. That was too much. Almost immediately I also had another thought: "I've spent a year of heavy work only to make the minimum required mechanics for the genre work as they should, but if I had just picked a more simple video game genre, perhaps I could be applying the finishing touches on my first game by now". And that would be awesome. Because it would boost my confidence, and hopefully it would bring in some money so I can live with less worries, and have some budget for the next, larger, game.

 The empty, flat world of the RPG I've been working on
 for a whole year...

I took a radical decision at that point. To suspend the development of the RPG project for later, and start working from scratch in a new game, this time one that falls in a way less complicated genre. The RPG game won't be canceled. I have already invested so much time in making all these RPG game mechanics work, that it would be foolish to throw them away. But I just put the RPG aside, and focus on making a simpler kind of game now. So I decided to make a FPS, as FPSs are my second favorite genre after RPGs. And more specifically to an "old school" fps, with fast movement, medkits, etc. like the original Wolfenstein 3D, Duke Nukem 3D, and Serious Sam. I've been working on the FPS game for 8 days, and I'm surprised by how fast I'm progressing. In the first week of developing my first FPS game, I've already written the necessary code so:
  1. The player can move around and walk, sprint, crouch and jump.
  2. There is a functional gun that shoots bullets, reloads, etc.
  3. There is basic enemy AI that attacks the player if it sees him or hears his gunshots.
  4. There are functional medkits, ammo and gun pickups.
  5. There is functional but unpolished GUI reporting player health, stamina, ammo.
And in the 8th day I've also written the code necessary for the player to cycle through weapons with the mouse wheel, and to open and close doors, including locked doors that require a key. The most important and core mechanics of the game are already functional and just need some fine tuning. I could make a game just with these, but I'll be adding some extra stuff like secret areas and hidden collectibles, to encourage exploration as the 90s FPSs did. Given how fast the development of the FPS game is progressing, I'm now estimating that in a month since I started its development I will have all the gameplay mechanics, but also systems like saving, options menus etc, done. In fact it might take even less than this, because I've already written functional code for similar systems for my RPG game, that with some small changes I can transfer to the FPS game and have them working in less time than it would take to recode them from scratch.

 Early prototype screenshot of the FPS game, using 
placeholder graphics to test out game mechanics.
The cylinder on the left is a shotgun pickup, the small
rectangular box on its right a pistol, the two next boxes
ammo and medkit pickups, and on the far right a door.
Behind the mountains is also an enemy. All these are
functional in the first week.

Compare the time necessary to code the basic systems of a 3D Action RPG with the time necessary to do the same for a FPS. The difference is almost 1/12. And that is only for making the mechanics themselves work, not the content. So for the RPG project you would also have to code in each different quest, and if you want quests with multiple dialogue choices that affect the story outcome, then the amount of coding needed is several orders of magnitude higher than just making quests that always end in a single way. But FPS games don't have quests. At least most of them, the standard FPSs. Sure there are hybrids like the Far Cry series, but these are exceptions that diverge from the main FPS experience. That's not bad, I enjoy series like this quite much myself, but I also enjoy the traditional fast-paced action FPSs like those from the 90s. In fact the very reason that old-school FPSs are coming out less frequently than the other FPSs, have made me enjoy each release of old-school FPSs more than modern FPSs. I don't know if its the gameplay formula itself, nostalgia, or simply the fact that this kind of games come out less frequently that make me feel something special when I play them, but I do. It certainly is a good idea for me, a person who wants to make his first game to start with a simpler kind of game, but what I just explained previously about how I feel for old school FPSs further solidifies my decision to make this kind of game.

So these are my latest news and thoughts regarding my game development adventures. I've suspended the development of the game I wanted to make initially to work on another simpler, smaller game. But I'm not sad about this. Of course I didn't liked the fact that I had to leave a project aside, but I'm also trying to be pragmatic. Seeing how the FPS project moves faster than the RPG, I hope that I'll manage to have a FPS game made in a timely manner, in less time than it would take me to finish the RPG I have already spend a year working on. And perhaps it might sell well, and offer me the funds so I can then invest on higher production values for the RPG game, and maybe hire a few people to deal with the colossal amount work a RPG needs. Wish me good luck!

Δευτέρα 2 Απριλίου 2018

Outsourcing assets: The last thing you want to happen when you build a large game.

Being an indie is a tough job. Especially if you are going against the advice everyone keeps giving on the internet, about making something small. So you might be tempted to take the decision and use an asset created by someone else in your project, to save some time. In this blog post I'm going to give you a warning though, my personal advice that might save you time and frustration.

First of all let me tell you that I'm not against using ready made assets in general. In fact I do use a number of stuff made by others, and I'm happy about it. Secondly, this blog post is not going to touch the subject of "asset flipping" that people like the famous youtuber Jim Sterling is often commenting on. I'm not going to touch the subject of using art such as 3D graphics models made by others on this post, but using the code of others. Seeing how the use of publicly available graphics asset has gathered a bad reputation, you might think that because source code is not visible to players, that it will be OK to use someone else's code on your game. But there's a danger in doing this. Especially if you aren't one of those that know nothing about programming and use ready made "complete projects" for their games, and you actually do some original content yourself.

So one of the last things that you want to happen if you're a programmer and build your game yourself, is to not only have to care and test, and debug, your own code, but also someone else's code. Working on my game, I decided earlier on two times to use some assets that I discovered on the internet. Both were involved with the GUI somehow, because for me personally dealing with the GUI is one of the least enjoyable experiences of programming. The first asset that I decided to use, early on when I started working on this game, was one that would help me deal with the Inventory System of my game. At some point there were errors coming from the code of this asset, which was annoying because when I use someone's tools, I want to have the confidence that they work as documented, and that they always work. Anyway, I decided to have a look on the asset's code, and what I encountered scared me. The code was needlessly over-complicated, the parts of the system over-bloated. Seems the writer of this code never read Uncle Ben's "Clean Code". I started trying to decipher the code, and after a bunch of hours with no progress, I realized that I was spending too much time trying to fix someone else's code, and that it would be just easier and faster to create a similar sub-system of components myself from zero. So I said "screw this", and I started designing the code for my own inventory system. Once I got it working and tested, I felt so good, as if a weight I was carrying on my shoulders had been removed. In the end, doing all the work to understand how a system made by someone else works and then debug it, just doesn't worth it. Because the code you wrote yourself is always going to be easier to read (provided you follow and apply a coding style with specific rules) and thus debug, and even if a long time passes, it will be more intuitive for you to move around the scripts and find the part you have to change.
But I didn't learn my lesson the first time. I'm a slow learner you see. So some time after that, I decided to use another ready-made system made by someone else, this time a dialogue system. A system with which the player can have a conversation with other characters in the game. This system looked much more professional, it had its own website, video tutorials on Youtube... I gave it a chance and it looked fine early on. But later on problems came up. As I was getting rid of bugs one by one following the exceptions list, I eventually saw a null reference exception coming from the code of the dialogue system asset. I checked the objects related with the exceptions, and I found out that the objects representing individual dialogues had disappeared. They weren't anywhere in the scene, WTF ? I googled the problem and I landed on a page on the official support forum of the asset, where someone else had the same problem as I. The person responsible answered to the user that the user has to expect that if for any reason Unity hangs or crashes, all the prefab gameObjects coming from this asset are going to delete themselves without notice. Why is this happening ? Unity has crashed on me a few times, and none of the gameObjects running my code ever deleted themselves. What's worse is that the most frequently used objects of this asset holds data. Data you have to manually enter in each object, such as the actual texts that will be displayed on the screen for each dialogue the player has with a NPC. And thus whenever the objects delete themselves not only you will have to place new ones on the scene, but also to manually enter all the data again. Now, you can understand how much of a liability it is to use such an asset in a large RPG game, where you have to have several hundreds of thousands, if not millions lines of text, for all the different NPCs and the different dialogue choices, right ? The risk of using this asset in such a big game is so big that using this asset is just not worth it. Some might say "Hey, do some backups", but that doesn't solve the problem. I do commit to source control every day, but imagine this scenario: You are using the prefabs of the asset in one scene. Then you start working on another scene for an X amount of time. As long as you are working on a scene different than the one you have used the asset's prefabs, you are not going to know if the asset deleted the prefabs. You will only find out when you load the old scene again. And if you want to restore your project to a previous state where the gameobjects hadn't been deleted yet, you will lose the work you've done that X amount of time in the other scene. You might argue that the source control system allows you to only bring back certain files and not the whole project. But guess what, the files that hold the data you enter in this asset's objects is saved automatically on .meta files named with random strings, and the same format is also used by the game engine for a large number of other stuff, meaning that you would have to try out each randomly named .meta file one by one. But what if there are hundreds, thousands of such files in each commit ? With this happening to me, I gave up on using this asset, and I decided to create my own dialogue system from zero. The liability, the risk of using this asset is too high. At least with my code, I know that whenever Unity hangs or crashes, the gameobjects that use my code won't remove themselves without a notice in a way that just closing and reopening the project won't bring them back.


The lesson I've learned is this: Be extremely careful and conservative when you are about to decide to use someone else's code in your project, to minimize your dependencies as a programmer. Do so only if you absolutely have no other option, it's a core feature of your game, and can't create the functionality yourself. At least try to write your own code before considering using someone other's code. In most cases using someone else's publicly available / ready made code won't worth it, because it will be code harder to read, understand, and debug, bloated with features you probably won't ever need. In the end it will be much more efficient to create, use and debug your own code than someone other's.

 P.S. So if you are wondering what I'm currently working on, is getting my own dialogue system up and running.

Πέμπτη 29 Μαρτίου 2018

AI Optimization Results.

At the last post I wrote about how I was going to try out to use threads for the first time, to offload the work needed to be done by AIs on a different thread. It turns out things didn't go as I imagined initially. You see, a thread can run a single Method, and it only runs it once. If it finishes it, you have to re-tell the thread what to run, and initiate its execution again. And that also means that instead of having a thread running all the AI routines, you have to have a separate thread for each routine of each AI instance. And you know what ? Threads are expensive! It takes considerable time to get a thread running in parallel to the main thread. So can you guess the result for my test scenario ? Where 16 AIs are simultaneously active on screen ? The whole engine hanged and became unresponsive. Failure. Apparently the time it requires to start a thread is much more than the time the code of the routine takes to be executed. That means that using threads to offload the AI routine that updates each frame, is out of the question.

So what's next ? I ran the profiler again and found out that the Garbage Collector was eating most of the processor's power, whenever the AI routine ran. So I did some smart caching, and I got a marginally better frame rate. I kept checking for small improvements, removing some methods that are called by the main routine that runs each frame from it, and calling them at the start, plus some smart bool checking so some operations don't run every frame even when they don't have too, and with each small change, the frame rate would raise up a bit. With all these little changes I managed to raise the number of simultaneous AIs from 16 that I reported yesterday, to 24, and keeping a fair frame rate between 35 and 48.

Then I tried something else. In each frame the routine will be checking what the distance from the player is. And if the distance is greater than a certain amount, (yet to be decided) most of the code that used to run every frame won't. The idea is that if the AIs are far enough from the player, maybe behind some physical objects and thus not visible, there is no need to check for everything. But instead to be updating only basic stuff like if the AI is alive, and its position. This change lead to a frame rate that when the AIs are further than the certain distance I mentioned earlier, gets up to small 80s. Much better.

 
With 22 out of 24 AIs being far away, the frame rate went from 30s to 80s.



So now I can have up to 24 AIs fully active, with even better frame rates if they are X distance away from the player. That's 50% more AIs than what I could have yesterday. Cool!

Τρίτη 27 Μαρτίου 2018

Finalizing the features list, and testing the code.

It's been a while since my last post on this blog. All this time I've been hard at work on my game, and I had to tackle various problems that got me really focused on solving them, so I didn't wrote a post here all that long. As I was working on implementing and trying out new features, I came to the realization that the current phase of game development had lasted too long. Without realizing it early enough, I let myself get in to feature creep. I had gone beyond what's necessary, to a seemingly endless addition of stuff, having a large list of "Todos". What's worse was that seemingly simple nice little features can result to a ton of work if you take in to consideration all the ways that you have to change the rest of the game's systems to accommodate for it.

A dive into feature creep.
An example of that was a small detail I thought would be nice, regarding the torch item. So I thought of making the torch more useful than just lighting up dark places, I said to myself "What if the player could put different things on fire by waving the torch towards them ?" I thought that this would be a simple thing that would make the game's world more interactive, and thus more immersive, and through that make the game more fun. Furthermore, it would make sense since the torch can light up things in fire to be able to be used as a weapon. It would feel absurd if the player could light up anything on fire with it but not his or her enemies. So I added the necessary code so that when a AI character is hit with a torch, there is a chance that this character will catch on fire. But that little detail brought the next one: now I also had to change the AI code for characters to accommodate, so they react in a believable way. And since there's going to be water in this world - (rivers, lakes, pools, etc) it would feel stupid if an intelligent enough being on fire wouldn't use the could-be nearby pond to turn off the fire it has on itself. So I went ahead and added the necessary code for AIs to have additional knowledge of their surroundings, to know if there is a water source nearby, and coded the necessary behavior so if an AI is smart enough, is on fire, and there is water nearby, to abandon whatever it was doing and go straight to the water. And it worked fine at that time, and I was satisfied. After that I started working on other features, implementing them and testing them individually, and eventually I got to the point of general testing, where I have a testing area with all the gameplay features to simulate how they would work in the actual game all together. And at that point I realized I had missed something very important. The AIs on fire would get in the water source (like a river), and they would walk on the river floor as if it was dry ground until they drown. So at that point I realized that for this little cool feature to work, I had to make huge changes elsewhere. I would have to design and implement a custom complex NavMesh system from zero, that not only does pathfinding in 2 dimensions (forward-backward, right-left), but also on the altitude axis, and code in AI swimming. And I realized I'd have to do all that on top of the rest of features in my Todo list, and I had already been out of schedule, with the current phase having already lasted way more than I initially thought and planned it would do. At that point I realized how I had left myself divert from the plan and I had got myself deep in feature creep. This phase had lasted so long I had started becoming tired and burned out by it, it had lasted already about double the time I initially thought it would. So I came up to the point where I had to make a tough decision, to decide to cut off stuff from my game. And so I did. One of the features I cut off was having the AIs run to a water source once they catch up fire. Now, they will just run away screaming to a random direction. Sure it would be cool to see them going for the pond, but the highly disproportionate amount of work needed to be done as a result of this little cool thing, meant that it just not worth it.

Stress testing and optimizing code.
So after deciding what features to cut off and which of them to keep, I worked on implementing the most necessary ones, and then I moved on to the general testing phase. Let me tell you a thing about my development process. I thought early on that it would be a good idea to first code all the different gameplay mechanics and sub-systems, and after I have everything in place to move on to creating content that uses these systems. I haven't got myself deep into creating graphics and level design yet. Because I want to base my level design around the mechanics. And I want to make sure that these mechanics work as best as they can, and as bug-free as possible before I start to create content around them. So I started doing various kinds of tests. The first thing I did was to re-visit every script I've written, and clean it up. Remove deprecated code, organize the code in them in a more readable, orderly fashion, simplifying algorithms etc. Then I decided to make some stress tests with what I already had. One of those stress tests was to see how many AI characters I can have οn the screen simultaneously before the frame rate dives to unacceptable levels. Note that I want to have areas like towns where it is necessary to have a bunch of NPCs in them, to make them feel like actual living and breathing towns. So I moved copies of a particular AI character that holds a torch in a certain area, and the first test only allowed me to have 10 AIs simultaneously. I found out that if I remove the torches from the enemies, I could have 16 AIs simultaneously. The torches, given that each is a realtime light source that creates dynamic shadows, were bringing the fps count down. 16 is surely better than 10, but I want to have a higher limit. I don't know if at any given point there will be more than 16 AIs simultaneously on screen at the final game yet, but still, I want to have enough room available to feel safe, because in a dynamic, responsive world of an open world game, who knows what might happen ? I figured out that the most costly part that was dropping the frame rate, was the method that runs each frame for each AI to let it know of its surroundings. Given that, I decided to try out offloading this job to a different thread, but I'm not sure about it because I haven't really worked with threads before. All the software I've made up to this point has been pretty light on the CPU, so I didn't had to do multi-threading up to this point. But hay, that's how developing a new large project is, isn't it ? You learn a lot by working on it and you gain experience. So now that I'll finish writing this blog post, I'm going to take a quick re-look on how threading works, and I'll attempt to make my game multi-threaded by offloading heavy AI work on a different thread. Wish me good luck!











Τρίτη 27 Φεβρουαρίου 2018

What I've been working on in the past fews days: Leveling-Up System, In-Game Calendar.

It's been a few days since I posted here. These days (as with the rest) I've been hard at work, working on even more features of my video game (an Action RPG), fixing bugs, and testing things out.

The first I tackled with was the system that enables the player to Level Up. The player will be getting XP points in various occasions such  as winning battles against enemies, completing quests, solving puzzles etc. And there is a set of milestones, and each time the player's XP points reach a milestone, the player's character is leveled up. But how does someone decide at how many XP the character will level up ? I took a look on the milestones some games have, and the numbers of XP points needed to progress to the next level seemed random. At that point I decided to do something that I do quite often when there is something I have doubts about in designing my RPG. I've opened the DnD Dungeon Master's Guide I have lying on my bookshelf. I bought the rule books of DnD years ago, without even having the slightest idea that one day I'd be creating a RPG video game myself. We were saying with some pals back then about starting playing DnD so I rushed to buy the books and other stuff such as dices etc. Unfortunately we only got to play... once, as they weren't that much determined actually. So for years I had these books lying around, and lately I found them actually to be useful for something. I often take looks at these books for inspiration when it comes to brainstorming for the video game I'm making, and they've helped me come up with many ideas. Regarding the leveling system in particular, I took the note that it's generally a good idea to level up a character when he (or she) has faced about 13.33 events of the same level as he is. So I decided on a base XP that each creature will have depending on its level, and then made a chart with the XP points required for each level, and I tried it out by fighting some enemies.

Another feature I worked with, and spend most of today's time on it, is the system that calculates how many days, months, and years have passed in-game since the player started a new game. The game's world is going to feature its own calendar, complete with its own months, and other details. So the player will be able to know the time in the world his or her character is living at. I wanted to add this because it adds some believability and immersion to the game by itself. But I haven't decided yet if it is going to play a bigger role than that. Perhaps some quest might only appear on a specific day of the month, or a certain month ? Or perhaps a NPC might tell the player to "Come back after 10 days for that...", and thus the system will be more useful than just adding a small touch of immersion. We will see.

Aside from these 2 systems, the rest of my work has been the usual: fixing bugs as they come up, testing stuff out, slight improvements here and there... Nothing new or extraordinary.

Τετάρτη 21 Φεβρουαρίου 2018

Defining the Combat System (DevBlog)

For the past 3 days I've been focused on my RPG's combat system.
The most basic and fundamental mechanics were already implemented and are nothing special. You move the melee weapon (such as a sword) and if it lands on someone, that someone looses some health. If it blocks, then that someone won't lose health. Similarly if you throw an arrow to someone with a bow, that someone will loose some health. This can be fun, but alone it's too basic. It needs some more spice to make it more interesting and fun. Thus I decided to do a small research and see what kind of action RPG games players think have good combat systems, and then have a look at the combat systems of these games. Checking out a number of different games that people on the internet seem to agree that they have good combat systems, I've noticed some common elements in all these games. And these elements seemed reasonable and straight-forward once I noticed them. I noted those elements down and made a list. Then I examined the list carefully to see what of these would fit the style and flavor of the game I'm making. Once I had decided on which of these fit well in what I'm planning for my yet unnamed action RPG to become, I started working on these features. Here are some of them:

1) Attack stuns. When someone is being stabbed by a sword or hit by a club, that someone will get stunned for a little while before continuing fighting. It makes sense. Games where characters are stunned for a little while when they get hit and can't attack back until they are OK get praised for having a good combat system. People write on forums about these games that they have "solid combat", also that "weapons have weight", etc, and on the other hand for the few games where characters keep fighting or doing whatever it was they were doing once they get hit, without stopping for a moment, they say that their combat is "floaty" and "weightless". Because it just makes sense if I hit you with a club on your head to be stunned for a moment. So yeah, I decided to add this mechanic on my game, as it makes absolute sense.

2) Damage / Size / Speed Analogy. Another small detail that makes a RPG combat system feel solid and weighted has to do with the analogy of the damage a weapon does with its size and attack speed. So basically leaving the attack speed of every weapon the same, and having the size of the weapon only matter for its effective range, is not the best thing to do. Instead the speed with which you can spam an attack with a certain weapon has to have an analogy with the size of the thing, always taking in to consideration the damage it does. Larger, heavier weapons will take longer to maneuver and thus their attack rates should be slower than those of smaller and lighter weapons. And you have to keep the D/s* ratio of each weapon in mind while deciding on the attack speed of each weapon, to make sure you keep some balance in the game. So I decided to do this, and carefully make it so each weapon has a different attack speed, depending its size and attack damage, to make sure weapons respond the way the player would expect and make sense.

3) Power attacks. This is quite simple to do, and adds enough to the gameplay formula to deserve inclusion. In many games you are given the option to charge your attack for a few moments. So if you hold down the attack key or button for a while and then let it, you do an attack more powerful than the ordinary attack. This gives the player choice. To decide if he prefers a quick attack which deals average damage, or a slow one that deals more damage. There may be occasions that one of the two is more preferable than the other one, so I decided to add power attacks.

4) Critical hits. Critical hits are something that players don't think much about, often they are forgotten or overlooked, but when a critical hit happens it sure brings happy smiles to player's faces! So critical hits are something that won't be noticed if it isn't there, but will bring smiles if it is and makes an appearance. So there is a random chance that one of your attacks will do more damage to the enemy than it usually does, yay! Plus, it's one more reason to rise your Luck attribute, which is often overlooked. Oh, by the way, the game is going to have a Luck attribute! I didn't tell you before, did I ? :) 

These are the mechanics I've been implementing the last 3 days. They are functional right now, but testing is required to fine-tune them, clear out any bugs, and make sure they are kind of balanced. So tomorrow I will do some testing on them, and perhaps clean up my code a bit, something I have postponed for some time now.


* D/s: Damage per second