home about the studio about the team luxe game engine join the discord

You've successfully subscribed to Studio Any Percent!

Subscribe to Studio Any Percent

Stay up to date! Get all the latest & greatest posts delivered straight to your inbox

mossfield origins - dev #3

tasks and stock piles



Stock Revisited

As mentioned yesterday in #2, the way the stock system works was revised but it didn't affect building costs and wasn't physical as it should be. Today those issues are resolved. Worth noting: making stuff in my engine, for me, is really fluid. I tend to work quickly, even with little time available!

Now when a construction begins, it queues up some tasks to fetch the resources, and only begins when they're all ready.

Moving stock around

This works by creating a task entity and attaching a Fetch modifier + a Stock modifier.

note; when I say modifier, the term means "modifier system", i.e a system which runs logic on entities that it's attached to. see here

The fetch system tries to find sources to pull from (by asking the Stock system). If found, it moves there and transfers the resources from the source onto the task stock itself. Since the task is attached to the unit doing the work, and the stock pile is attached to the task, the stock follows them around as expected.

When the fetch destination is reached, the stock is transferred and the task completed (destroyed). If the destination doesn't have a stock pile (like a construction site atm), the amount is technically lost, but is how spending works for construction at this time.

This covers the mechanics for moving stock around between stock piles too.
Here I bound a key to move some stock to the consumer (again hacked onto the Residential Foundation).

Stock Priority

There are a few kinds of stock now, inputs (consumers), outputs ( producers), the research center (fallback stockpile) and literal stock pile buildings, where resources are stored closer to construction to save time.

I spent a while thinking over how stock should work priority wise, and decided on the following based on reasonable expectations:

  • If there's stock that was left on the ground, use that
  • If there's a literal stock pile building, use that
  • If there's a producer instead, use that
  • If neither of those, try the research center stash
  • And if that fails, take from the input of any consumer

This means that unless it's absolutely necessary, they won't take resources already allocated to a consumer. My expectations are that building might be the priority in low resource situations, in order to gain more resources to get out of that state.

There's still considerations like pathing + distance, but that'll come later.

Tasks

Previously, I made a really quick system to manage tasks which was bare minimum. That includes being a bit messy cos I work fast. The main idea is simple: keep a list of free units that can do work, and keep a list of work to do. The work was populated e.g by a construction saying "do this work" (which really just amounted to moving over there).

If there's work, and there's people, move to the work location, wait a specified time, then call a function. Add the unit back to the free list, and move back to the rest position. That's all that was needed to get going, but not enough to move forward.

Revised tasks

In my engine the unit of work is an entity, they're cheap and they're flexible so when I thought about what a task is or should be, I start with an entity. An entity is given the ability to behave differently based on modifiers, as mentioned above.

One of the mechanics in the game is work hours vs sleep hours. What happens when someone is busy with a task, and they need to sleep? We could let them finish, but the task could be blocked (there are no resources to fetch).

So instead, a task is created in the world as an entity, and it's spatial, it has a position (Transform modifier attached). This means the task can move around with other entities as shown above, which is interesting. If a unit is moving some resources from A to B, and sleep time hits, they can actually just drop the task right there, and it'll get added back to the available work queue. In the morning, someone can come pick it up and continue.

This is something the task modifiers (like Fetch) have to be aware of, e.g a fetch modifier needs to pay attention to when it gets dropped, and only revise the details once continued. This isn't a problem though, as they also need to be aware of being cancelled, or the destination no longer existing, and all sorts. It works out well, because the stock pile that is left on the ground is still a valid stock pile, and would be considered for other uses as well when marked that way.

Tasks now

This is the broad picture now. Something worth noting here, is that the same task is being used for a Fetch followed by a Visit. That means that the task is still assigned to the same unit, and the same unit carries out the Visit task. This is just cos I wanted to test that being feasible, but also because I don't have any idle behaviours yet. That'll come soon though.

This is just creating random Visit tasks which get queued up, and completed by free units.

next...

Carried resources still show up as values on the hud (since they're still in the stock system). I don't think they should be, since it's confusing when you're unable to build due to lack of resources but it says you have those...

Now that tasks are well defined, I'll probably implement pathfinding next.
That's all for today!