Pagina's

Showing posts with label refactoring. Show all posts
Showing posts with label refactoring. Show all posts

Sunday, 8 September 2019

It's got to be idle

It's been a couple of days since I got to writing a blog post, because I wanted to finish what I was doing before sharing it.

I was refactoring the state machine to make the state transitions easier  to implement without bugs. Like it always happens,  when you try to make something to prevent bugs, it'll have a major bug. And when you finally find and fix the bug, you wonder how on earth that could ever take that long! Well, that's what happened.

In short, when the worker was sent to a goat to collect the food, he immediately started harvesting and it was not until I right clicked the goat again that he went there. This was because of a couple of things:

Firstly, the mechanism for deciding if the unit arrived at the destination,  that was faulty. I have this method to give a arrived-signal when the distance between unit and target is smaller than the radius of the unit plus that of the target. This is to avoid units fighting for position. Problem was that the target was a spot on the edge of the target. This means that the unit would only walk to a certain distance from the edge of the target and that was too far away.  I moved the target point to the center of the target object.

Secondly - and this is that major bug - the unit started in the walking state with the destination at its own position. It would just walk to its own position and wait for instructions. I don't really see what went wrong exactly,  but the unit should start in the idle state. Once I did that,  it all worked again.

Other things I did were to implement a new sub class of building: storage. Every storage thing can contain a certain amount of any resource type a d it'll become a resource with some of its resources when destroyed.

I also got the amphora to look alright from the inside and not be see-through. Last, I got the UI for resources working. Next will be the UI for the selection panel to show selected objects.  After that, I'll start with either building or melee fighting.

Sunday, 18 August 2019

Selecting Objects Again

Good morning, people. I'm back from a weekend with quite some game development time and half a season of Casa de Papel. It was raining, but now I need to go to the office again,  so it stopped raining.  Time to tell what I've been up to this weekend.

First, there were two issues related to the world not being flat. I kind of solved them, but I'll revisit them when I feel like it. The camera is flying over the terrain and it avoids high hills like the plague, which is nice. It does not do that very smoothly. I need to find out why.

Same goes with the rotation of my models when moving uphill or downhill. It seems the navmesh agent does not care about the y-axis, so I had to do the rotation myself. After tinkering (and cursing) the rotation is now correct, but it flashes to that rotation in an instance. But hey, quaternions are evil. I'll get them good one day.

Now to the meat. As I told you, with the hilly terrain, I decided to refactor majorly, so I  am not porting all of my old stuff to the new Unity project. First thing to remake is the mouse control. The control script always knows what object the mouse is pointing to. That will make it easier to interact.

First thing is selecting objects. Like in the old project,  that happens by left clicking. Holding shift will add an object to the list, but only if we're having your own units. You can only group select units you own. All other kinds of objects are only selectable on their own.

This works partly and I expect to finish it soon, but it was late yesterday, so being tired, I probably put some bugs in there. I'll revisit this tonight if I have time. After that, I'll see if I can get box selection to work. That'd be an entirely new feature. Hopefully I can start with that today or tomorrow.

Thursday, 15 August 2019

The ground is not flat

Just a small update, because time is an illusion. What have I been up to yesterday? Well, bits and pieces.  First of all, I have been working on the camera system.  Next, I'm reimplementing the features I already had.

You might have noticed I am working on a different Unity project since starting the procedural level generation. This is because I found out that much of what I made was dependent on the ground being flat. That, and when you're learning,  sometimes you want major refactoring and it's often better to do that early.

The camera then. Because the ground is not flat, I cannot just clamp its position to a certain height on the y-axis. I need to find out how high the ground below is and then clamp in to a certain height above the ground.

Typing this, I now know what to do tonight. I need to send out a raycast and see how far away it collides. Then I have this point. Add some minimum value to the y-value of the camera position and we are done. I just need to make sure the camera doesn't go beyond the level, looking to the void that we all fear.

Next, this guy.


You know the goat. It's our first agent walki g around on the navmesh. It works, although I need to tweak some parameters. That's nice, because I am implementing a new AI state machine. With the floor not being flat, rotation will be changed, but I didn't have time for that yet.

Now, the bus is almost at the station,  so you know what that means...




Sunday, 28 July 2019

Mondays after the holiday

Mondays and most particularly this Monday...

Holiday is over and I'm in the bus to the office again. Santorini was great and back home we had record heat with temperatures over 40 degrees in the shade, so that was tough and I did not work on Holocene as much as I would have liked. Now it'll be evenings and weekends anyway, but that's just the way it is.

In my sweaty state, I did make progress in the unit mechanics. There was some refactoring in the way we deal with targets for the units, making is unnecessary to have different targets for resources, units, incomplete buildings and the like. This should make further progress easier.

The main thing is that I started the skeleton of a combat system.  When I have a unit selected and I click on some attackable object, the unit will move there and start dealing damage until the object dies. Then, depending on the type of object it's attacking, it might start gathering resources or find other objects to attack.  That works fine now.

I think I'll have to switch some of the mechanics to another class once I start implementing enemy AI and behaviour that does not depend on user input. I have some ideas about that, but not fleshed out yet. For now, I'm pretty pleased how it's all going and it's not been as difficult as I might have expected... YET.

Wednesday, 24 July 2019

Cutting the trees, blacksmithies and trebuchets

Right, today was the hottest day ever in the Netherlands and tomorrow, they expect another record, so what did I do? I only worked on Holocene in the morning and now, in the middle of the night, right before going to bed, here's what I made.

Most of the stuff I've been working on is work in progress, except for turning trees into animals, like I announced yesterday. Turning trees into animals allows easier implementation of changing states. Trees will yield wood as resources, but only after cutting them. So first we're looking at a stationary unit and when it dies, it'll change into a resource object that has an animation and all the stuff we expect from resources. This is how it now looks.


The other thing I've been working on is trying to have the guy to the left have any say in the fall of the tree. The aim is to allow the unit to interact with the tree and then cut it. There are some different kinds of objects to interact with which will all need slightly different ways to do so. for instance, there's the ground and if you right click there with a unit selected, you order the unit to go there. If you right click on a building you own, you move the guy to the edge of the building and see if the building has any interaction of its own, like healing the unit or fortifying the building. If you right click on an enemy unit, you run to it and attack it. And if you right click an tree, you go towards it and start dealing damage.

In theory, this all works fine, but somehow I experience problems having the BigBookBasic script  find out what kind of object it is. Apart from the ground, all clickable objects derive from a WorldObject class, for now in this way:
  • Building
  • IncompleteBuildings
  • Units
  • Resources
All of these could have different members. A Barracks and a Wall are both buildings, A Worker and a Warrior are units and Rocks and Berry Bushes are resources. Further, Units could be animals too. BigBookBasic will need to find out what kind of object we're looking at a a certain moment. Well, that does not yet work. I'm sure I'll figure it our, but not today and I'm also sure that I need to figure it out soon, because it's central to give units the information they need to decide what to do with an order. In other words, I think this part of the program is what will turn it into a game. 

When I get this to work, there'll be some refactoring needed, because I have some scripts, like the gather script, that do work, but it a roundabout way and I have different variables to track target unit, building, resource and "object" for units. I want them in one variable. For that I made a small class to store both the object itself and some information on it. This class will be the main focus in interactions between objects.

In short, the trees do fall and turn into resources. I cheated, because you see the health bar decrease, but that's just because I added some testing code. Sneak preview perhaps, or will I delete it later?


    protected override void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            DamageHealth(10);
        }
        base.Update();
    }

Tuesday, 23 July 2019

G.O.A.T. of goats

Ha! Did you get the pun? The goat. Greatest Of All Time. I just needed to make that joke. It's not Lionel Messi or Cristiano Ronaldo or even Kanye West or whatever he needs to be called nowadays.  The goat is either Peter Sagan or my goat objects.

Last post I told you that I wanted my goat script to have an overhaul and I did do that this morning while my wife was still asleep. I made a new class, an Animal class. Animals are objects that start as some sort of unit and turn into a resource once they die. Probably, I'll turn trees into animals too, because you first need to cut them before they bring resources. Biologists, don't worry, because I know that trees are plants and not animals.

Anyway goats are now animals.  It's official.  They run around randomly,  being just a bit slower than the humans. I have a piece of code that I'll delete later. When I press M, all goats get 10 damage. Biologists should know that goats has 50 hit points, so after 5 times,  it's gone.

Once the goat has gone where we can't follow, it's replaced by a  "dead goat" object, just like we all will have that happen to us.  A dead goat is a resources for food.

Workers will be able to gather that, but be quick,  because I added a rot timer to resources.  A rock will not quickly deplete on its own, but the weather is great here, so animals will. Every 5 seconds,  one piece of food will vanish from the dead goat.

Well, that works. I'm now sitting in the back yard again, soaking up the sun. I'll be working on the game again soon, probably turning trees into animals. I think I'll have the combat system soon.

Sunday, 23 June 2019

Don't mix up

I thought I had it all figured out. It all seemed to work. Yet now I can't see how I could be this stupid. There's a reason why in a tutorial they always implore me not to get behaviour classes and display classes mixed up. So what did I do?

My work, last week, was mostly about creating actions, linking them to an object, triggering them by clicking, a timer with some GUI and the result of the action being there. I put all of that in a display class.

Part of it makes sense, because the button to trigger the action is pressed on the display.  The rest does not. What happened was that it all worked smoothly as long as the object doing the action was selected. You know, selecting an object removes the display of the current selection, including all the unfinished tasks.  That's the problem here.

What I'm now working on is a progress class. The progress class tracks if an action is running, how long it will have to keep doing that, if the action will be done once or multiple times (as in creating 4 of the same  type of unit). And it will finally perform the action in the end. All the display does now is "I'll have one more RecruitWarrior please."

What did this teach me? Not so much. I honestly believed the way I had it was the right way. Testing was mostly to watch the GUI doing its thing, so I never deselected the object until I wanted to check if, when I run a science type action in one barracks, it should not be available in the other.  It was. And in the one one, research stopped.

Well, getting back to the beginning: don't mix up data, behaviour and display.

Thursday, 20 June 2019

Reading the Big Book of Basic Stuff

So, this is kind of a technical devlog. The fun thing about working on Holocene is to combine my creative spirit, being a historian and learning a partially new craft. I work for a software company and I program business applications with databases and interfaces to influence whatever is in there. It's programming and it helps develop the way of thinking that I can't explain to my mother. On the other hand, while Java, Python, Javascript, Lua, C# etc are kind of alike, I'm working with a different kind of framework, much more high level than those others, even when Unity is actually doing much of the high level stuff for me. Learning to work with Unity and C# is an interesting journey for me.

I'm getting the basics as we go, but sometimes I have trouble fully getting grip of object oriented programming, I guess. I find myself having to rewrite stuff because I need it again in another context. For instance, I have this snippet for a gatherer to find where the drop-off building is and then where to go, because Navmesh agents can't walk into objects that it would walk around. I thought I needed that just for this purpose or at least for strongly related ones. I was wrong.

With the recruitment of units working, I needed a way to place them around the barracks. So what I did yesterday was kind of weird. I put the unit on top of the rally point, made it find out where the object of the barracks is and where is the nearest edge of that collider is, move the position directly to that position and then have the unit walk to the rally point. Because it worked and I just wanted it to work, I called it a day, but today is another day.

I am finding out how to use methods in a context where they do not have to have any specific kind of object involved. For that I have found out that static classes are useful. They can hold methods and global variables that you might need in any context. For now, they hold stuff about the size of the screen and other such things. From today on, I will populate it with methods that are generic. For instance, enter a position and the method returns whatever object is there (if there is one). Enter an object and the method will find out what are the edges of it.

My aim is to have this all grouped in a well-arranged way so that I always know where to find those information-gatherers. I'm sure that I will end up with a long script, but it's a script specifically designed for that purpose. I'll probably have it be a special script to distinguist from the screen size stuff. Tomorrow, I'll rerun all my scripts to find if there are such generic methods and variables that I need anywhere and then I'll put that in the script. I don't want every unit to have its own (identical) way of finding the entrance of a building. I just want to tell the unit to look for it in the Big Book of Basic Stuff (BBBS for short).