Introduction

Me and a team of 5 other students created Chefline's Journey for our internship. This was really special because we had full creative freedom over the project and we designed it from the ground up. It also was the first time I ever got to make a game that was outside of a school project. And I learned so much making it from programming to planning to teamwork and gamedesign!

Chefline's Journey is still in development and where planning on making a big demo of our game that we want finished at the end of our internship. If you're interested you can our progress here:

The Making of Chefline's: Journey

Inventory System

I made an inventory system for this game that I am really happy with because it works with every type of item we want to hold. In the following video you can see everything the inventory does.


public class Inventory : MonoBehaviour
{
	public List Items = new List();

	[SerializeField] private List _itemSlots = new List();

	public void AddItems(IInventoryItem item)
	{
		Items.Add(item);

		//Find the first available item slot without a recipe or with the same recipe
		ItemHolder selectedHolder = FindAvailableRecipeHolder(item);

		if (selectedHolder != null)
		{
			selectedHolder.HoldingItems.Add(item);
		}
	}

	private ItemHolder FindAvailableRecipeHolder(IInventoryItem item)
	{
		for (int i = 0; i < _itemSlots.Count; i++)
		{
			ItemHolder holder = _itemSlots[i].GetComponent();

			// Check if the holder is empty or if it holds the same recipe
			if (holder.HoldingItems.Count == 0 || (holder.HoldingItems.Count > 0 && holder.HoldingItems[0] == item))
			{
				return holder;
			}
		}
		return null;
	}

	public void RemoveItem(string name)
	{
		IInventoryItem itemToRemove = Items.Find((x) => x.GetName() == name);

		if (itemToRemove != null)
		{
			RemoveItemFromHolder(itemToRemove);
			Items.Remove(itemToRemove);
		}
	}

	public void RemoveItem(ItemType type)
	{
		IInventoryItem itemToRemove = Items.Find((x) => x.GetItemType() == type);

		if (itemToRemove != null)
		{
			RemoveItemFromHolder(itemToRemove);
			Items.Remove(itemToRemove);
		}
	}

	public void RemoveAllItems()
	{
		foreach (IInventoryItem item in Items)
		{
			RemoveItemFromHolder(item);
		}
		Items.Clear();
	}

	private void RemoveItemFromHolder(IInventoryItem item)
	{
		for (int i = 0; i < _itemSlots.Count; i++)
		{
			ItemHolder holder = _itemSlots[i].GetComponent();
			if (holder.HoldingItems.Contains(item))
			{
				holder.HoldingItems.Remove(item);
				break;
			}
		}
	}
}
							  

As you can see in the inventory you can add and remove items. It has a list of itemslots which it can fill when an item is added. And this system is perfect for how we want to save items in our game.

Now on to how the abilities are setup. As you could see from the video there are lots of different abilities in our game. So I made an easy way to add new abilities.

Quest System

In this project I really wanted to learn to program more SOLID code and I think I did really well with the quest system for our game.

In this video you can see a quick overview on how the quest work in our game. You have two visual elements displaying quest information. One is in the players book (pause menu) with a lot of information and the other is in the HUD with more minimalist information.

So on to how this system works. I have a scriptable object for quests and the objectives so you can easily add objectives to the quest and change the information. When an objective is completed it broadcasts an event to all the quest and objectives and if the objective EventContexts name equals the objective it changes the progression and sets the objective to completed. In the code you can see the objective ScriptableObject code.


[CreateAssetMenu(fileName = "ObjectiveData", menuName = "ScriptableObjects/ObjectivesData")]
public class Objective : ScriptableObject
{
	[SerializeField] protected List _eventNames = new();

	public string Name;
	public string Description;
	public Sprite Icon;

	public float Progress;
	public bool IsComplete => Progress >= 1;

	public override string ToString()
	{
		return "";
	}

	public bool IsValid(EventContext arg0)
	{
		return _eventNames.Contains(arg0.Name);
	}

	public void OnEvent(EventContext arg0)
	{
		if (IsValid(arg0))
		{
			Process(arg0);
		}
	}

	protected virtual void Process(EventContext arg0) { }
}

public class DestinationCheckObj : Objective
{
	[SerializeField] private string DestinationName;

	[SerializeField] private DestinationCheckRuntimeSet _destinationChecks;

	public override string ToString()
	{
		DestinationCheck destinationCheck = _destinationChecks.Items.Find((x) => x.DestinationName == DestinationName);

		return destinationCheck.Distance().ToString("0") + "m";
	}

	protected override void Process(EventContext arg0)
	{
		if (((DestinationReached)arg0).Destination == DestinationName)
		{
			Progress = 1;
		}
	}
}
				
									

In the Destination Objective I also want to display the progression that is why I override the ToString() function so I can show the progression in the HUD.