TankUp: Describing the environment

Concerning: The way the AI Tanks describe their environment.

I just put in place the class that will be used by the tanks to note down the specifics of their environment. An instance of that class, filled in with a couple of GameObject lists (one for other combatants, another for pickups), a simple int for the current stack size of the tank and (very important) a fingerprint of the entire content of the environment object instance.

That last part is there to avoid unnecessary shuffling of data. The tank will always keep the object up to date in order to pass it to the State Selector static class and get back a verdict on whether state change is needed. However, I’d like to do that only if necessary. So at regular intervals the tank will refresh its environment object, get the fingerprint and will bother the state selector only if the new fingerprint differs from the latest one. This seems to be a reasonable way to do it.

Also, about the state selector – a static class seemed fine. No state of it’s own (how ironic 🙂 ), something like ‘WWJD’ – what state would you choose if you were me and this was your immediate context 🙂

P.S. Something is wrong with the whole thingy – wether the IDE or Unity is behaving. I updated Unity to 3.0f6, then VS said – what is this ‘TextMeshPro’ you speak of? I expected a whole metric ton of .csproj files to have already been loaded for this project. Therefore you have 200+ errors. The game project is running, though, so I don’t know… I dialed it back to 3.0f5 and the problem remains. We’ll see when I try it at the PC at home.

TankUp: What I have so far (Part II)

The Tank Data:

The whole spiel of the game comes from the stack of layers that the tank in question has at any moment.

The most fun part was the size. Each tank has a default size (logically) and they are all the same. And, as per the initial idea, accumulating layers had to make the tank less effective, to negate the positives of this accumulation.

The damage factor is easily calculated (even though I am still not committed to a final formula), but I wanted also to give some visual reference for that stack size.

The most obvious choice was to increase the size of the tank itself. This has two advantages – first, the player can infer some stack sizes by the size of a tank (either your own or of another combatant unit); second – larger tank should be easier to hit, which directly influences performance.

The most obvious issue is that, of course, linear relation between stack size and tank size does not work. A simple quadratic relation (check (x^2)/20 for example) would stunt the tank growth in the lower stack sizes. However this leads to a blown-up tank size the more layers you accumulate. Luckily, I remembered that the function form I need is called ‘histogram’.

Basically I wanted to allow the tanks to differ little in the lower range (up to 3-4 layers), then they should be allowed more noticeable growth, and finally (very important) – reduce the growth factor after some level. Diminishing returns after a certain number of layers would guarantee that there will be a soft cap on the size.

The most important effect of the histogram? – You can easily discern three groups of tanks – small, medium, large. Additionally, if the final equation allows it, a player may be even able to tell the difference between different sizes on the steepest slope of the curve – the lowest sizes are more or less indistinguishable, the highest – too. But in the middle you have noticeable jumps up and down when you add/remove layers.

So how do you find exactly what you need?

First – wikipedia, for list of example histograms

Second – Desmos.com (https://www. desmos.com/calculator) – you type the formula, then you start fiddling with it to make it behave properly. As the minimum number of layers is 1, I had to move the histogram around to make it cross approximately 1 on the x=1 axis. This, of course, was eyeballing it, so:

Third – place whatever version of the equation you’ve got, replace the constant you’ve been fiddling with ‘y’, take that to WolframAlha and ask ‘what would ‘Y’ be if x is 1. Much obliged!

I tried a few histogram equations and I’ve settled on one for now. I am still not sure it will be the final one. The current one settles at about 2.6 something as an upper bound (I can’t be bothered to check if it really converges, as it seems to be the case). I would much prefer the soft cap to be somewhere about 2, but more important for the final decision would be the position of the steepest slope. And I would know what stack sizes get you there when I can actually test some interaction. So, for now, I am sticking with what I have.

Resources:

Wikipedia – but obviously!

Desmos.com – simply delightful; exactly what I needed for this case (including graphing multiple equations for comparison and proving some export options)

WolframAlpha – for when you put your head in a bucket of math that is above your level

TankUp: What I have so far (Part I)

Construction:

Of course I started with the player tank. I am still not entirely sure if I have structured the game object of the tank in the optimal way. Later in the process I stumbled upon this Jason Weimann video (https://www.youtube.com/watch?v=UWGspLJ-_8U) and I will surely revisit the components structure of the tanks again at some point.

For now, I think the component model is decent – box game objects, which contain the elements in a small hierarchical tree (you gotta keep them separated!). The most important questions were:

– who holds the tank data structures

– how much of a separation do I need for the whole tank model and it’s turret

As this is my first experience with mouse control, the turret was a bit tricky, as it had to be controlled by the mouse, while still being part of the tank itself, which is controlled by the keyboard.

Later on, when I get to add animations, I will probably have to separate the tracks from the chasis in a separate objects, contained in another game object, in order to be able to stick an animation script to that object, which will listen for the current speed of the tank and the motion of turning around. A sync with that would be good, although it will probably be not very visible, given the position of the camera and it’s distance from the model.

Data:

The data structure itself works well and I think there will be no more big changes in that department:

– one class for the layers – each layer has only a weapon type and health.

– one class for the layer stack (TankData) – in addition to the Stack<Layer> structure it has a bunch of methods for extracting stack stats – the size, balance, top layer weapon type, etc.

– a ‘Tank’ class – this one is MonoBehaviour, as it is attacked to the tank game object. This is the main script that communicates with the turret, the mover scripts, behavior scripts, etc.

– the turret has its own scripts – a main ‘Turret’ script that for now only switches the visual model to match the weapon type of the tank; it has also one script that keeps the turret pointed to mouse cursor once I get to tackle shooting, there will be a script (or, more likely, series of scripts) to handle that – each of the weapon types will have distinctive shooting style and that will add some more structure to the data base.

= = =

Problems:

* One problem is the proper game object and component hierarchy. I mentioned that I am not sure the current GO/Component structure of the tank is perfect. I hope I will not find later that I need to make drastic changes, but this seems unlikely. Using game objects to hold collections of other objects is a fine way to approach complex models. I like to think that if you are unsure how to handle a concrete model structure, a good way to think about the model is to imagine it’s all regular C# data classes – so just follow the ‘Single responsibility principle’ from SOLID.

* The movement of the turret was a hell of a ride. And I am afraid it is not over yet. From afar it appears that it faithfully follows the mouse position, but looking closely reveals that the turret does not rotate around the proper point (the center of the turret itself) – instead it rotates around the midpoint of the whole object, which includes the length of the weapon itself. I am yet to research how to approach that. Also… there’s a design problem I haven’t tackled yet – the weapon does not tilt, which means that I can not simply shoot forwards from the respective gun barrel. For the gun and the rocket I can apply ballistic trajectory, but what about the raygun – it should be simply a raycast. If your tank is on an upwards slope (for example) and the target is on a plateau in front of you, you will simply shoot above it. For a game of this type I will obviously have to cheat in some way, but how exactly… uncertain. Should I lower/elevate the vector, depending on the circumstances? If so – should I move the visuals of the turret also? For steep angles that might look bad. If I don’t, it might look bad to have the beam shoot from the raygun ‘barrel’ at an angle. We’ll see.

* One more thing about the rotation of the turret – oh, my! There are (of course) more than one way to rotate object X towards object Y. As most of them use Quaternions and that part of math I do not wield, I had to simply try every solution I found. For the life of me I cannot tell what I used at the end without checking my own code. One of the big problems is that (because that math is not very accessible) when people look for help in StackOverflow, some good soul gives a solution (sometimes as generic code, sometimes more tailored to the specific example), but usually there is no explanation ‘why’ exactly this is a good way to implement the rotation. And inferring that from the example in question and figuring out how to translate that to your own case (if at all applicable) is… an adventure 🙂 Anyways, I’ll get to know that better in time.

Resources:

I’ll have to add a section resources at some point, but for now – here’s the one resource I managed to mention here:

Jason Weimann – “Unity3D Architecture – Where should I put my components? (and a little Weapon Swapping)”

https://www. youtube.com/watch?v=UWGspLJ-_8U

P.S. Let me say in advance that Jason Weimann is one of my primary sources. I cannot recommend his channel highly enough. The same goes for quill18creates.

#SimplyPriceless.

There are others also, but those two are my most common youtube sources and are the absolute go to!