Crafting system NOT like minecraft

Hello everbody, I am working on a Simulator in which you can combine diffrent cars to get other cars. Now my problem is that I want to craft car1 and car2 together to get car3, but it should also be possible to craft car1 and car3 together, and so on. I am planning on having (final) around 50-500 combinations so I am not really sure how to handle this.


My first approach was to just give all the cars a two letter string (aa,ab,ac…zz), then add the strings of the two cars which the player wants to combine together e.g. (aaab,abac,aaac…) and then check via a switch statement what car he would get.
But if the player now combines car2 with car1 instead of car1 with car2, the string changes and I would have to do another switch statement trough all combinations again.

If you have an idea or hint I would appreciate it very much if you leave a comment.
With google I always end up with minecraft crafting systems so just simple keywords would help me alot.
Thank you in advance and greetings from Switzerland
snow2405

You’ll likely want to separate out your concept of car identities from the crafting system- they’re related but trying to do everything all in one place is over-complicating this. For the following example, I’ll use ScriptableObjects, since support for them is built-in and they’re really easy to use, but you can use literally any persistent data storage method instead (XML, JSON, YAML, etc…).

So, what I would do is create a unique car identity for every car type that you want. The identity is the data that cannot change between multiple instances of the same car type in the game- ie: if you can change the colour of the body work, add or remove decals, change the tires, etc, and still have the same car identity, then those are all runtime data- what I’m talking about is the stuff that cannot change between instances, the core stuff that makes that type of car. The identity should have an ID number (randomly or sequentially generated to be unique), an ID name (“Toyota Corolla”), description, and any internal parts that aren’t changable, as well as starting parts for the things that ARE changable, if that type of car should always start with the same parts, etc…

Then, in a separate system for crafting (this can also be ScriptableObjects), you make “recipes” that allow you to put together two different car identities to instantiate a third, something like “Input 1: Car ID# 162134, Input 2: Car ID# 612456, Output: Car ID# 323567”- you can add the base cost of that operation, multiple outputs with percentages if you just want it to be a chance to receive a specific result, etc… You may also want to have specific criteria included with each recipe for unlocking that recipe in the game, like a progress level of some kind, or having previously owned a given car type, whatever. This is also data that cannot change at runtime, the same as the car identities.

In the game itself you can have a manager which stores the references to those ScriptableObjects- the car identities, as well as all recipes you’ve made. When queried by the rest of the game objects, it can return the specific car identities or recipes that the caller wants. Cars that are actually instantiated into the game world can hold a reference to the car identity they represent, and this can be used to check the static data about that car type, find out what recipes it can be used in, find out what kinds of modifications it supports, etc…

The car would also have an object for “instance data”, which is the stuff that’s only for that specific instance of the object, like colours. If it were my game, I’d store the identity reference within the instance data itself, so it would look something like:

public class CarData
{
    public CarIdentity identity;

    public Color hoodColour = Color.Black;
    public Color bodyColour = Color.Black;
    public BodyType bodyType = BodyType.B;
    public WheelType wheelType = WheelType.A;

    private CarData() { }
    public CarData(CarIdentity identity)
    {
        this.identity = identity;
    }
}

This means that all CarData requires an identity to be set when instantiated, and the rest of the CarData class is just stuff that only applies to that specific instance of the car, and not all of the cars with that identity. That specific identity might only support WheelTypes A and B, while others support more, or different wheels. When combining cars with a recipe, you’re saying “this identity and this other identity make this third identity” and just assign the third identity to the new car. You can do whatever you like with the instance data- blending together the colours from the first and second cars, randomly carrying over values from either, or disregarding them completely- up to you.

Anyways, not trying to make the system for you here, just giving some ideas. This is only one possible way of doing what you want, but it’s a pretty common and easy-to-implement approach. The fact is, most crafting systems are very very similar, logicially- all “items” need an objective identity so they can be used in recipes, and in games like Minecraft that means everything but the specific durability left and quantity, which are part of the instance data. Combining cars isn’t any different than combining ingredients in games like that, so don’t dismiss Minecraft-clone tutorials out of hand- there’s still a lot you might be able to learn there, and just apply it a little differently to get the result you want.