Rustlang Up Some Grub at The Ten Top

“The Ten Top” is the working title of a game that I’m writing in Rust using the Amethyst game development framework. My goals with the project are to make a fun casual simulation game in the vein of Game Dev Story and Overcooked.
The object of the game is to make enough money to:
- Cover operating costs of the restaurant every month
- Pay the worker(s)
- Eventually sell the restaurant and retire
A core mechanic of the game is taking orders from customers (e.g “one hot dog, please”) and asking workers to prepare the given dish, then give it back to the customer.
To deliver a hot dog, a specific set of conditions need to be met:
- A hot dog bun needs to exist
- A hot dog link needs to exist
- A hot dog link needs to be cooked to create a cooked hot dog link
- A cooked hot dog link needs to be combined with a hotdog bun on a plate to create a servable hot dog
These steps result in a (bland) hot dog. A first attempt to code this logic might might include a lot of hotdog-specific code (“Does a hot dog bun exist”, “Does a hot dog link exist?”, etc).
If a hot dog bun and a cooked hot dog exist already, a hot dog can be made. An issue is that “The Ten Top”
sells other kinds of food! Modelling all those cases could get tedious very quickly. Modelling this data with a dependency graph
helps to make the logic more managable. In the Rust ecosystem, petgraph
is a popular tool for working
with dependency graphs.
To model this problem, dishes, ingredients, and actions can be treated as nodes in a directed graph:
When run, this code prints:
The graph can be represented visually:
Now that information about making hot dogs is in the graph, we can use the graph to find requirements for a given item.
Once a vector of nodes exists, we can walk through each step.
For example, if a cooked hot dog link exists, it can be used to make a hot dog. If not, we need to tell a worker to cook a hot dog.
Looking at neighbor nodes of a cooked hot dog link, we can get a sense of what goes into a cooked hotdog.
To make this a little easier to use in the context of the game, I wrapped this behavior in a struct and added instance methods:
The cookbook would be used like this:
With all this, it becomes easier to help workers figure out what order of steps to take to make a hot dog and deliver it to the patron.