So, last weekend was fun. I did not have much time for game development as we went to stay in a 3x3x3 glass cube in the woods for the night. We did. Next day was the prehistoric museum so that was fun too.
I did spend some time on the game yesterday. Still the UI. What I want to make is the panel at the bottom of the screen where information on the selected unit(s) is shown. It'll be a panel with different parts that show or don't show, depending on the type of object that is selected. There'll also be a panel with icons for actions the selected object can perform. That needs some work and that's what I am doing this week, probably.
Showing posts with label RTS. Show all posts
Showing posts with label RTS. Show all posts
Sunday, 15 September 2019
Tuesday, 10 September 2019
Showing information
Alright, a short one, because I don't have much time now. Yesterday and the day before, I was working on the UI gor Holocene. For now, as always, everything is placeholder, but we'll have a resource panel and a selection panel to show information on the game. The resource panel is already working. It reads all the storage objects the player has and shows totals per resource type.
The selection panel is going to be a bit more complex. I had my plan for this written out before, but it needs some finetuning because the code is a bit different. It'll be fine though, because I like what it was, so this should not take too much time. For now, the UI with the Worker unit selected, will look something like this:
Remember, placeholder is the key word here. I want it all yo work first before making it look pretty.
The selection panel is going to be a bit more complex. I had my plan for this written out before, but it needs some finetuning because the code is a bit different. It'll be fine though, because I like what it was, so this should not take too much time. For now, the UI with the Worker unit selected, will look something like this:
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.
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.
Wednesday, 4 September 2019
Pillaging the amphoras
So, yesterday I was working on a bit of 3D modelling for Holocene. I was frolicking around with Blender and made this amphora.
This amphora tells me I'm pretty happy with my getting better with Blender, because, even though it's not difficult to make an amphora, it does look neat. I also learned that this one was not right and I needed a different way to make it.
The above example is made of a hollow cylinder. This means that it does not have an inside. Now you can't see that in Blender, but once you put it in Unity and you point a camera to it from the top, you can see straight through it. I spent over an hour trying to make an amphora that looked like this one, but found the handles on the side difficult, so I went to bed.
Amphoras also gave me an idea for a new kind of worldobject: storage. Games like Age of Empires have storage buildings, but they don't have a maximum capacity. This means that, with one mill, you can have millions of tons of grain (and deer meat).
Storage objects in Holocene will have a capacity, so there'll be a change in the delivery mechanism. If an amphora is full, workers will need to bring their food somewhere else. If all amphoras are full, you can't get more food in your stockpile.
I'm not sure if I will implement bringing mechanisms like in The Settlers where workers bring wood to a building site and so on, but I will include pillaging. Amphoras can be broken, leaving the food to be gathered. This will bring extra options for warfare.
You see it's not fleshed out yet, but the ideas are there and I'll let them simmer for the day until I get to implementing them in the game.
This amphora tells me I'm pretty happy with my getting better with Blender, because, even though it's not difficult to make an amphora, it does look neat. I also learned that this one was not right and I needed a different way to make it.
The above example is made of a hollow cylinder. This means that it does not have an inside. Now you can't see that in Blender, but once you put it in Unity and you point a camera to it from the top, you can see straight through it. I spent over an hour trying to make an amphora that looked like this one, but found the handles on the side difficult, so I went to bed.
Amphoras also gave me an idea for a new kind of worldobject: storage. Games like Age of Empires have storage buildings, but they don't have a maximum capacity. This means that, with one mill, you can have millions of tons of grain (and deer meat).
Storage objects in Holocene will have a capacity, so there'll be a change in the delivery mechanism. If an amphora is full, workers will need to bring their food somewhere else. If all amphoras are full, you can't get more food in your stockpile.
I'm not sure if I will implement bringing mechanisms like in The Settlers where workers bring wood to a building site and so on, but I will include pillaging. Amphoras can be broken, leaving the food to be gathered. This will bring extra options for warfare.
You see it's not fleshed out yet, but the ideas are there and I'll let them simmer for the day until I get to implementing them in the game.
Labels:
3d-art,
game mechanics,
Holocene,
HoloceneRTS,
RTS
Monday, 2 September 2019
Chasing goats
The gathering mechanics are nearly finished. I have a system to send a worker to a resource. Once it arrives there, he'll start carrying resources from the thing until it is depleted or the worker reaches his carrying capacity. He returns the stuff to a building and goes back to the resource to continue gathering or find another resource of the same kind. If there are no resources available within a certain range, the worker will look for other objects that become resources when they die and will attack that.
Every worldobject has a slot for a prefab to instantiate when its health goes to zero. For instance, our inevitable goat is a unit, much like a worker, but when it dies, it turns into a source for food. While that could be done in many different ways, in Holocene, it's done by destroying the goat object and replacing it by a dead goat one.
Anyway, when the worker has been gathering food and the source is depleted, he may start chasing goats to kill them and get access to the food. For that, I made the chase state in my state machine. Chasing is actually mostly the same as walking, but with two main differences.
Firstly, chasing updates the destination all the time. If you walk to an object and the object moves away, you still walk to the spot where the object used to be. Chasing will update the position of the target and change the direction accordingly.
Secondly, chasing might result in fighting. In fact, that is the aim of it all. When the target gets inside a certain range, the unit might start a range attack. If it gets closer there'll be melee fighting. Of course this needs fine tuning, but this is what it will probably be like.
Every worldobject has a slot for a prefab to instantiate when its health goes to zero. For instance, our inevitable goat is a unit, much like a worker, but when it dies, it turns into a source for food. While that could be done in many different ways, in Holocene, it's done by destroying the goat object and replacing it by a dead goat one.
Anyway, when the worker has been gathering food and the source is depleted, he may start chasing goats to kill them and get access to the food. For that, I made the chase state in my state machine. Chasing is actually mostly the same as walking, but with two main differences.
Firstly, chasing updates the destination all the time. If you walk to an object and the object moves away, you still walk to the spot where the object used to be. Chasing will update the position of the target and change the direction accordingly.
Secondly, chasing might result in fighting. In fact, that is the aim of it all. When the target gets inside a certain range, the unit might start a range attack. If it gets closer there'll be melee fighting. Of course this needs fine tuning, but this is what it will probably be like.
Saturday, 31 August 2019
A little big thing
So, good afternoon. No development today, or at least not until the evening. I do have things to talk about though, as I have been busy working on the movement mechanics in Holocene and there are some problems.
When a unit is selected and the player right clicks somewhere, the unit should go there and that works for parts on the terrain where nothing already is. When there is a unit, it works too and the game knows where to stop to prevent two units to fight for the position to stand on.
The problem is when the unit wants to move to a stationary object like a resource or a building. The navmesh understands that the unit cannot just go there, so we'll have to find a place where it can go. Unity has these methods to find out the edge of a collider and places on the navmesh, but they do not yet give me what I need. When I send a unit to an object, it just stands next to the object on one place, no matter which is closest.
I'm not sure how the game decides that specific spot, but it's not what I want. That is because it does not decide which place is closest to the unit. I was hoping the methode for finding the edge of a collider would fix that, but they don't. I'm confident I will find a way, but I have not yet.
This is one of those "little big points". You might expect it to be a small minor thing to find the point where to go, but after a couple of days, you realise, maybe not so much...
When a unit is selected and the player right clicks somewhere, the unit should go there and that works for parts on the terrain where nothing already is. When there is a unit, it works too and the game knows where to stop to prevent two units to fight for the position to stand on.
The problem is when the unit wants to move to a stationary object like a resource or a building. The navmesh understands that the unit cannot just go there, so we'll have to find a place where it can go. Unity has these methods to find out the edge of a collider and places on the navmesh, but they do not yet give me what I need. When I send a unit to an object, it just stands next to the object on one place, no matter which is closest.
I'm not sure how the game decides that specific spot, but it's not what I want. That is because it does not decide which place is closest to the unit. I was hoping the methode for finding the edge of a collider would fix that, but they don't. I'm confident I will find a way, but I have not yet.
This is one of those "little big points". You might expect it to be a small minor thing to find the point where to go, but after a couple of days, you realise, maybe not so much...
Wednesday, 28 August 2019
Worker is too lazy
Good morning CET. An update on what I've been doing yesterday. I told you there was going to be 3D modelling for the gathering mechanics. We have the rock and the worker that is supposed to mine the rock. We also have the mining mechanics, but once the worker has enough stuff, there's nowhere to go to to deliver it. So insert s simple 3D hut that I made in Blender.
Well, no. That was because there was something wrong with the rock. Somehow I had that specific one yield gold instead of stone. And the hut only accepted stone, so the worker's not going anywhere. Well, fixed that. Still not going. This means there must be something wrong with the AI state picking thing and it is. The worker finishes mining, switches to walking as it's supposed to. Then it goes idle.
Being lazy myself, I get that. Sometimes you just go idle, but not this time. We're talking algorithms and they are supposed to do what I tell them to do. It hurts to say, but I guess I could have made a bug then. Let's fix that. Next!
Monday, 26 August 2019
Transitions are important
Working with and getting used to Unitys Animator, I find that the beef of these state machines is in the transitions between the states. Different states have the agent do different things, but the main thing is to get the agent to go to a specific state when you want it to.
I'm working on the gather mechanics for workers. I put a little rock from Blender in my scene, added a resource script and focussed on the interaction between worker and rock (and explaining to a friend that not all interaction is sexual).
In short, you right click on the rock and the worker will move towards it. When it's there, it'll make a difference if the agent really is a worker and not, say, a catapult. Catapults can't gather resources in Holocene. Workers can. I managed that by adding a task enum to the unit script. That enum contains certain things that only certain units can do, like gather. The worker script will override the unit script for moving to a resource, adding the gather task. Now that is used to trigger gathering. Guys without the task will go idle on arrival. Others will go to the gather state.
Then gathering happens. The worker will get resources over time and the rock will loose some. Then we need to decide what to do next. When the rock is 'empty' or the worker can't hold any more resources, we need to drop it to a building.
I've not finished this yet, but I will save the resource object and location in a separate variable and find a suitable drop off point and object to go there, setting the task to return. The walking behaviour takes the worker to the drop off point and triggers the dropping. Next the resource will be the target again and the worker returns to gathering. When the wotker does not have any resources and the rock is empty too, he's finished and will look for another rock to carve.
This should be the gathering AI. It took my some time to think up, especially since I need to get used to the triggers in animators. I am at a point though where I think I know what to do next.
This is one of those things I love about making games. There's little victories around every corner, much more than in my day job. That's very motivating.
I'm working on the gather mechanics for workers. I put a little rock from Blender in my scene, added a resource script and focussed on the interaction between worker and rock (and explaining to a friend that not all interaction is sexual).
In short, you right click on the rock and the worker will move towards it. When it's there, it'll make a difference if the agent really is a worker and not, say, a catapult. Catapults can't gather resources in Holocene. Workers can. I managed that by adding a task enum to the unit script. That enum contains certain things that only certain units can do, like gather. The worker script will override the unit script for moving to a resource, adding the gather task. Now that is used to trigger gathering. Guys without the task will go idle on arrival. Others will go to the gather state.
Then gathering happens. The worker will get resources over time and the rock will loose some. Then we need to decide what to do next. When the rock is 'empty' or the worker can't hold any more resources, we need to drop it to a building.
I've not finished this yet, but I will save the resource object and location in a separate variable and find a suitable drop off point and object to go there, setting the task to return. The walking behaviour takes the worker to the drop off point and triggers the dropping. Next the resource will be the target again and the worker returns to gathering. When the wotker does not have any resources and the rock is empty too, he's finished and will look for another rock to carve.
This should be the gathering AI. It took my some time to think up, especially since I need to get used to the triggers in animators. I am at a point though where I think I know what to do next.
This is one of those things I love about making games. There's little victories around every corner, much more than in my day job. That's very motivating.
Sunday, 25 August 2019
Fighting for position
Ok. Weekend is over again. I have not been able to get too much work done in Holocene this weekend as I had other things to do (and yesterday night I wasted my time watching The Marathon Man).
What I did do is making a start with moving units. For that, I made another of these primitive shapes based Workers. A capsule for the body, spheres for head and red nose to know which way he's facing and an elongated cube for arms. And a worker script and some needed Unity components.
First thing I set out to do is to implement the walking behaviour that I made for goats. When the unit is selected and the player rightclicks on the ground somewhere, the unit is going there. Quite easy.
When clicking on a friendly unit, the unit should go there and stop right next to it. Well, that gave us this little gif that I shared on Twitter:
What I did do is making a start with moving units. For that, I made another of these primitive shapes based Workers. A capsule for the body, spheres for head and red nose to know which way he's facing and an elongated cube for arms. And a worker script and some needed Unity components.
First thing I set out to do is to implement the walking behaviour that I made for goats. When the unit is selected and the player rightclicks on the ground somewhere, the unit is going there. Quite easy.
When clicking on a friendly unit, the unit should go there and stop right next to it. Well, that gave us this little gif that I shared on Twitter:
Now what happens there? Note that I have not yet implemented any fighting mechanics. These workers are not fighting per se, but yet they actually are. The thing is, the moving one is trying to stand on the spot where the stationary one is already standing. Because two entities can't occupy the same position, there's squeezing going on.
This was actually quite easy to fix. The worker script knows what object it's going to and that object knows its size. All we need to do is tell the walking behaviour script what the size of both objects is. Add them up and we have the stopping distance.
This is actually really all I pulled off this weekend. Hopefully I have more time for my game this week.
Thursday, 22 August 2019
Setting up the interaction
Ok, another update. Yesterday, I wrote about a little issue in the WalkAround state of goats. Well, it somehow took the best part of the evening to fix that. Somehow the trigger for starting to move kept getting hit before the position was picked, having to goat literally go nowhere. Well, done now.
The more interesting thing to talk about is a little groundwork for giving orders. I already had a system to find objects when given a location. I upgraded that with a class of references to everything you need to interact with an object. In the end, orders will all be "interact with this object over there" and the kind of object is central to know what "interact" really means.
When I right click on an object, selected objects will run a method on a base Worldobject class to decide which virtual void to run, with some basic general stuff and possibly overriding methods in a derived class.
Sorry if this is technical. It means that I define basic behaviours for interacting with objects of a certain kind that should apply to anyone. When a certain agent has its own behaviour for some interaction, I'll program that and run that instead. This is how I understand object inheritance in C#.
Well, all I ended up with visually is that Holocene looks exactly like it did the day before yesterday, so I won't bother you with screenshots or the like, but now it should be set up to do things I did not program yet. I like to have it flexible, because I know it is getting more complex quickly now.
The more interesting thing to talk about is a little groundwork for giving orders. I already had a system to find objects when given a location. I upgraded that with a class of references to everything you need to interact with an object. In the end, orders will all be "interact with this object over there" and the kind of object is central to know what "interact" really means.
When I right click on an object, selected objects will run a method on a base Worldobject class to decide which virtual void to run, with some basic general stuff and possibly overriding methods in a derived class.
Sorry if this is technical. It means that I define basic behaviours for interacting with objects of a certain kind that should apply to anyone. When a certain agent has its own behaviour for some interaction, I'll program that and run that instead. This is how I understand object inheritance in C#.
Well, all I ended up with visually is that Holocene looks exactly like it did the day before yesterday, so I won't bother you with screenshots or the like, but now it should be set up to do things I did not program yet. I like to have it flexible, because I know it is getting more complex quickly now.
Wednesday, 21 August 2019
To our goat overlords
So I opened Pandoras jar. Yesterday was quite productive and I am pretty pleased with it. I started working on a new AI system, based on Unitys animator component and the theory I found at the likes of Tommy Thompson who has a compulsory YouTube channel on AI in games. It took a little rewriting, but it looks really workable. Someone on Twitter already greeted our new AI goat overlords when I shared this one.
This one is as complex as it looks really. A goat enters the game in a WalkAround state where after a time a trigger "arrived" is hit. When that happens, the goat will go to the NextTarget state. It then immediately returns to WalkAround. If, after some time, a trigger "died" is hit, the state will transition to Dead.
Now that I'm typing this, I see a flaw. It works, but only for randomly walking around. That is because I use the behaviour scripts for this state machine. NextTarget does not actually anything but having the WalkAround state restart. Picking the destination for walking is done in WalkAround, making it useless for any agent that does not walk around randomly.
What I'm going to do tonight is move that destination deciding thing to NextTarget and rename both states to be used for other agents. The Walk state will deal with a destination in the Unit object and walk there. When it arrives, the next state will decide where to go next or what to do next. A worker might want to collect food after moving to the bushes, a goat will go somewhere else. Both could use the Walk state for walking. The difference is in the transition after that.
Anyway... I also did a little thing to trigger the "died" thing. For that, I added health to objects. When health gets to zero or below, it hits the "died" trigger. Objects then change to other objects. For instance, when a tree dies of cutting, it turns into a horizontal thing that gives wood supplies. It gets different attributes by dying. Technically it's become a different object, but ssssht, don't tell anyone.
Next steps will be to first fix the issue with the states, to add a healthbar and damaging mechanism to test the death thing and then to start Worker AI. With AI here I mean the intelligence to perform orders like "go there" and "harvest that". Giving the orders by enemy players is for much later. I call that Player AI and I did not give that much thought yet. Did I forget to mention anything? Probably, but the bus hits the "arrived" trigger, so I sign out for now.
Monday, 19 August 2019
Big goats unite!
Ok, that went more easily than expected. Yesterday, I had a couple of hours to work on the selection system for Holocene and I think I finished it, which is nice.
I made a script to handle selecting and deselecting objects for the player and made some changes to the script handling input from the mouse. As I said yesterday, the script keeps track of what object is under the mouse cursor. When the user clicks, the following things can happen:
- You click on an object. It gets selected.
- You hold shift and click on an object. It gets added to a list of selected objects. The selection script always knows what kind of objects are selected and uses that information to decide whether the clicked object will be the only object to be selected or the other selection remains. Only units you own can be multi-selected. If the current selection contains other kinds of objects (e.g. buildings or enemy units), or the object to be selected is another kind of unit, the selection is cleared and that one object is selected.
- You click somewhere on the ground and drag a box on the screen. All owned units in the box are selected.
That's it, actually. Because I don't have any GUI yet, I used the inspector to test it and it seems to work fine. In the little gif below, the big goats are owned by the player. The small ones are enemies. I try all the ways to select them. It works.
Next up will be making basic moving units. Select 'm and right click on the ground to have them move there. The goats are not supposed to be controlled. They move around on their own.
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.
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...
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, 11 August 2019
Building the world
Alright, I've been quiet on the blog recently. That's because I mean to have a big change on the game. The change is about level building. Holocene is a Real Time Strategy game and those games should be replayable, but that only works is the playing field is more interesting than just a flat plane and if it's different every time you play the game.
For that reason, I studied procedural level generation for a couple of days. It works by putting a plane in the scene and having vertices inside of it go up and down according to some noise thingy that I do not yet totally understand. The idea is to get the plane to resemble a sort of low poly terrain.
Next, there'll need to be some changes in the different scripts to allow for the third dimension that we have now. In fact, Holocene may look like a 3D game already, but it's the famous thing with the ant that quantum physicists always say when they explain the multidimensional world they think of. An ant is walking on the pavement like its 2D. There is no up or down for it. Well, the objects in Holocene should turn from ant to human.
I'm starting to get the gist of the level creation and I think I might be able to use the same script with some modifications once I build a campaign mode, but right now, I am not yet satisfied with the way the terrain looks. It's too bumpy and not mountainous enough. It's too all-the-same to my taste and I'll need to change that, because we need valleys and mountains, not just one 6 meter high hill following another.
I need to get the noise changed. While there's the Perlin Noise, I need to tweak that. I need lower the frequency so that we don't get hills everywhere we could get. We're trying to run a civilisation there, right? Next, we need higher amplitudes, because we need mountains and valleys. Lastly, I need to add more noise within the noise so that it does not look the same everywhere we look. We need hilly parts, flat parts, sea and mountains. And everything in between.
Looking at the code I have now, that must be feasible.
For that reason, I studied procedural level generation for a couple of days. It works by putting a plane in the scene and having vertices inside of it go up and down according to some noise thingy that I do not yet totally understand. The idea is to get the plane to resemble a sort of low poly terrain.
Next, there'll need to be some changes in the different scripts to allow for the third dimension that we have now. In fact, Holocene may look like a 3D game already, but it's the famous thing with the ant that quantum physicists always say when they explain the multidimensional world they think of. An ant is walking on the pavement like its 2D. There is no up or down for it. Well, the objects in Holocene should turn from ant to human.
I'm starting to get the gist of the level creation and I think I might be able to use the same script with some modifications once I build a campaign mode, but right now, I am not yet satisfied with the way the terrain looks. It's too bumpy and not mountainous enough. It's too all-the-same to my taste and I'll need to change that, because we need valleys and mountains, not just one 6 meter high hill following another.
I need to get the noise changed. While there's the Perlin Noise, I need to tweak that. I need lower the frequency so that we don't get hills everywhere we could get. We're trying to run a civilisation there, right? Next, we need higher amplitudes, because we need mountains and valleys. Lastly, I need to add more noise within the noise so that it does not look the same everywhere we look. We need hilly parts, flat parts, sea and mountains. And everything in between.
Looking at the code I have now, that must be feasible.
Monday, 5 August 2019
Dead, depleted and vanished
Alright, what did I do yesterday? Well, two things from my little list that I made recently. At least, a variant of one.
First, I wanted to make sure that when gathering or returning resources was interrupted, you could order a worker to drop the stuff at a building. When you right click a building that you own, the script will check if the selected unit has resources and whether the building is the kind of building that will accept the resource type that the unit is carrying. If it is, the unit will get the task of returning to that building and dropping the resources. If that is done, he'll go idle.
The second thing is that once a resource is depleted, it is no longer useful and only causes annoyance for the player to find out which of the 17 felled trees have wood left. Now, the object will have its alpha decrease to zero over the course of a couple of seconds. When the alpha is zero, the object is transparent and is destroyed.
I am going to change this later though. Right now, this only works for resources. I'm going to move the functionality to the worldobject script and have it apply to dead units and broken buildings too. Furthermore, I think I will make a dead-and-depleted model for those objects, like a skeleton, a ruin of tree stump. That object could then be removed more slowly. Most importantly, I now know how to make it work.
First, I wanted to make sure that when gathering or returning resources was interrupted, you could order a worker to drop the stuff at a building. When you right click a building that you own, the script will check if the selected unit has resources and whether the building is the kind of building that will accept the resource type that the unit is carrying. If it is, the unit will get the task of returning to that building and dropping the resources. If that is done, he'll go idle.
The second thing is that once a resource is depleted, it is no longer useful and only causes annoyance for the player to find out which of the 17 felled trees have wood left. Now, the object will have its alpha decrease to zero over the course of a couple of seconds. When the alpha is zero, the object is transparent and is destroyed.
I am going to change this later though. Right now, this only works for resources. I'm going to move the functionality to the worldobject script and have it apply to dead units and broken buildings too. Furthermore, I think I will make a dead-and-depleted model for those objects, like a skeleton, a ruin of tree stump. That object could then be removed more slowly. Most importantly, I now know how to make it work.
Sunday, 4 August 2019
Actual goats and improved gathering
Alright, Monday morning. I'm on my way to the office again. What did I do this weekend? Well, mostly modelling the goat in Blender. It's not rigged yet, so there might be some revisions later, but it looks like a goat and that's more than I expected at the outset.
This goat model is now also linked to the goat prefab and the dead goat prefab in Unity. A goat is a unit and a dead goat is a resource. Goats are replaced by dead goats once they die. These are the things one needs to explain a conputer. Visually, right now, a dead goat is a goat flipped to the side. Might revisit this later.
The next thing I made progress in, is the thing where resources cannot be brought to just any building. The little white domed building to the right is a Mill and mills are good for bringing food. Even though it's the closest building to the tree, when the tree is cut, the resources are brought to the Zigurat. Food can be built to the mill. That kind of thing.
The other thing was fixing a bug. When the dead goat is emptied, the workers went looking for living ones to kill instead of the dead one nearby. I fixed that. Then I found that the guy started gathering the goat food a couple of meters away. Had to fix that too.
For now, I'm pleased with how it goes. Some of the core features work now. I have these points that I mentioned the other day and there's the combat system coming up. Next, I'll see how the stuff works on a terrain instead of a flat plane. Next, there'll be the enemy AI to think about, then starting to replace placeholder things with better things to have it look and feel better, as well as review the GUI.
This sounds like it'll take 2 more days. Well it does not.
Wednesday, 31 July 2019
Between dinner and Casa de Papel
So holiday has ended a couple of days ago and I'm writing this blog from the bus again. On my way to that thing we call the office. As I probably said before, I have a full time job as programmer making office applications for customers. And by the fact I write my corpus of blogposts in the bus for a part, I need to travel every day.
This means that I am home quite late and that doesn't afford me much time to work on my game. Holiday is over indeed.
Having said that, I'm glad I was able to lay some groundwork for things I could implement in the hours and half hours of the evening, between dinner and Casa de Papel that me and my wife just started watching.
With the placeholder GUI in placeholder place, the coming time will mostly be about object interaction, about unit AI and the like, but only in following orders. Letting the enemies control their units is for later. For now, I'll be focussing on making sure that when a decision is made, the objects know what to do.
Things I am planning to do soon include:
This means that I am home quite late and that doesn't afford me much time to work on my game. Holiday is over indeed.
Having said that, I'm glad I was able to lay some groundwork for things I could implement in the hours and half hours of the evening, between dinner and Casa de Papel that me and my wife just started watching.
With the placeholder GUI in placeholder place, the coming time will mostly be about object interaction, about unit AI and the like, but only in following orders. Letting the enemies control their units is for later. For now, I'll be focussing on making sure that when a decision is made, the objects know what to do.
Things I am planning to do soon include:
- Changing a dead object or a dead and resourceless object to look and behave differently. For instance, when you kill a goat, it'll fall over and you can harvest the food. When the food is gone, it looks the same, but you can't interact with it anymore. I want this to be clearer. Maybe turn the goat into a skeleton and have it vanish over time.
- Right now, resources can be dropped at any building. I'd like to change that. You shouldn't be able to drop wood at the barracks. I'll probably build granaries, storage buildings and the like for that.
- When you attack a unit and it runs, following it is very simple. Have the unit close in and if it's close enough, continue attacking. I'd like the attacker to have to face the defender before fighting. Besides, I don't want the following to go infinitely. That could be a tricky thing later when players discover luring enemy units.
- If you gather resources, you return to a building. That works. But if gathering or returning is interrupted, there's no way to just drop the stuff at the building and be done with it. To drop something now, you need to first send the unit to the resource to have it return. I'd like to trigger returning directly.
I don't think that these points are very big, so these should be fine for the evenings. Besides, I really like the small successes that such things make. They are really motivating.
Tuesday, 30 July 2019
Just GoThere(place)
Yesterday evening I found and fixed the bug that was haunting me for a couple of days and it was one of those bugs I'll probably see return every now and then, because that's the kind of programmer I am. I overused a method that did more than I intended.
You see, units are supposed to be able to go places and for that, they have a navmesh agent that moves once a destination is set and the destination is not their current position. So far so good. Can't have that fail (well, we can, but I won't bother you with that right now).
The other main part of the unit script is a finite state machine AI system. In short, units have a state and a task. The state says what the unit is doing and the task what its objective is. So when we want to cut a tree over there, clicking the tree will cause the unit to have Cut as task, the tree as target and Moving as state. The moving state will find out if the unit is near enough to the target to change the state to Fighting. Etc.
Now the problem with the bug was that the task was no longer to Cut. The unit went to the tree and that was it. It turned to the Idle state with Nothing on its mind. Actually, that was easy, because I made the mistake of messing with the Moving state. It had a simple statement to set the destination and I, thinking that it would be smart, replaced that by a GoThere method.
And that method set the destination, so the guy did go to the tree. That was good. It also set the state to Moving, which is fine. But is ALSO set the task to Move. That was the problem.
The unit made its way to the tree and stopped near it. That was good. Then the Moving state wondered what to do next, so it asked the script. The script said. If you're moving and the task is to move, then once you reach your destination, you're done and you can run SetIdle(), whatever that may mean. No cutting the tree.
Now, dear rubber duck, this is a clash of principles. We have the DRY-principle (Don't Repeat Yourself) that will stop you from writing the same code multiple times. I try to live by this principle as much as possible.
Then there is this programming thing to keep things small. I wrongly assumed that the GoThere method would just set the destination even though I just added the messing up code for another aim. I wanted to make things consistent, but did not think about it enough. Because some things should be different from other things.
Lesson learned, but by no means expecting not to make the mistake again. I do think it should now be easier to detect.
You see, units are supposed to be able to go places and for that, they have a navmesh agent that moves once a destination is set and the destination is not their current position. So far so good. Can't have that fail (well, we can, but I won't bother you with that right now).
The other main part of the unit script is a finite state machine AI system. In short, units have a state and a task. The state says what the unit is doing and the task what its objective is. So when we want to cut a tree over there, clicking the tree will cause the unit to have Cut as task, the tree as target and Moving as state. The moving state will find out if the unit is near enough to the target to change the state to Fighting. Etc.
Now the problem with the bug was that the task was no longer to Cut. The unit went to the tree and that was it. It turned to the Idle state with Nothing on its mind. Actually, that was easy, because I made the mistake of messing with the Moving state. It had a simple statement to set the destination and I, thinking that it would be smart, replaced that by a GoThere method.
And that method set the destination, so the guy did go to the tree. That was good. It also set the state to Moving, which is fine. But is ALSO set the task to Move. That was the problem.
The unit made its way to the tree and stopped near it. That was good. Then the Moving state wondered what to do next, so it asked the script. The script said. If you're moving and the task is to move, then once you reach your destination, you're done and you can run SetIdle(), whatever that may mean. No cutting the tree.
Now, dear rubber duck, this is a clash of principles. We have the DRY-principle (Don't Repeat Yourself) that will stop you from writing the same code multiple times. I try to live by this principle as much as possible.
Then there is this programming thing to keep things small. I wrongly assumed that the GoThere method would just set the destination even though I just added the messing up code for another aim. I wanted to make things consistent, but did not think about it enough. Because some things should be different from other things.
Lesson learned, but by no means expecting not to make the mistake again. I do think it should now be easier to detect.
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.
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.
Subscribe to:
Posts (Atom)











