This document is about: FUSION 2
SWITCH TO

Food Fusion

Level 4

Overview

Food Fusion is a sample of a cooperative party cooking game using Fusion Shared mode. Players are presented with a series of orders to be made and served before they expire. They will chop, cook, and plate ingredients to put together the orders. The sample demonstrates character customization, persistent scene objects, object instantiation, authority transfer, usage of TRSPs, non-destructive player disconnects, and a robust interaction and crafting implementation.

Before You Start

To run the sample, first create a Fusion AppId in the PhotonEngine Dashboard and paste it into the App Id Fusion field in Photon App Settings (Tools/Fusion/Realtime Settings). Launch the game from the Preloader scene to play.

Download

Version Release Date Download
2.0.2 Sep 04, 2024 Food Fusion 2.0.2 Build 643

Highlights

  • Shared state authority of objects
  • Drop in, drop out gameplay
  • Player nicknames/colour selection
  • Extendable generic interaction system
  • Extendable ingredients and recipes structure

Objects

The cooking system utilizes scriptable objects to describe the relationships between objects and actions. The object types central to this system have a ScriptableObject component as well as a NetworkObject. All NetworkObjects will reference their ScriptableObject counterpart, if they have one, in a field named Data. Likewise, ScriptableObjects reference an associated prefab which has the corresponding NetworkObject.

Ingredients

Ingredients are the basis of the system, and may represent a raw or processed form, and may or may not be part of a recipe. Notably, a raw tomato is an ingredient, but needs to be processed to be useful. Similarly, burned food is also an ingredient, but has been over-processed and is no longer useful.

IngredientData : ScriptableObject references an icon (Sprite) with which to be represented by in the UI referenced by: FoodProcess, Recipe

Ingredient : NetworkObject The Ingredient has one networked property, ProcessedAmount. Not all ingredients make use of this, but it is used in processes such as chopping and cooking to track how far along the process is.

Food Processors

Food processors are a requisite for ingredient transformation. They are used in one of two ways; either by a Character, or by an Appliance. How food processors may be used is defined by FoodProcess assets. Whether they are associated with an appliance is dictated by the ApplianceData asset.

FoodProcessorData : ScriptableObject referenced by: ApplianceData, FoodProcess

FoodProcessor : NetworkObject

Appliances

Appliances are autonomous interactors which process ingredients in a corresponding food processor. They will attempt to interact each tick with a food processor placed on them. Appliances are necessarily associated with exactly one type of food processor.

ApplianceData : ScriptableObject references a FoodProcessorData which is valid for use with the appliance

Appliance : NetworkObject

Food Processes

Food Processes (FoodProcess.cs) are scriptable objects describing any transformation of one ingredient to another. A food process is defined as an input ingredient, an output ingredient, a food processor to be used, and an amount of ticks until the process is finished. The associated system is the ProcessGraph.

Recipes

Recipes consist of required ingredients and optional ingredients. They determine which ingredients are valid to mix together. Recipes are also used when generating orders. The associated systems are the IngredientGraph as well as the OrderMenu.

Interactions

Nearly everything that changes the game state stems from an interaction or a chain of interactions. This includes picking up and placing objects, processing ingredients, submitting orders, etc. These interactions are placed on the various prefabs and referenced by an Interactable component, which has two groups for the types of interactions the player can provide, "Grab" and "Use". The order in these lists determines priority. Only one interaction will be triggered at a time, so priority is important. There are special "delegation" interactions which have no specific behavior of their own, but instead send the interaction signal to another object.

Systems

A few different systems underpin the operations of the game loop.

AssemblyMap

The AssemblyMap aggregates the AssemblyVisuals and provides composition objects and sprites for certain sets of ingredients. Used by: FoodContainer, FoodOrderItemUI

IngredientGraph

The IngredientGraph evaluates all Recipes and provides methods for determining whether a given ingredient is part of any recipes, and whether a given ingredient is compatible with a set of ingredients. Used by: FoodContainer

ProcessGraph

The ProcessGraph consumes FoodProcesses and supplies information about whether a FoodProcessor and Ingredient are compatible, and what the resulting Ingredient will be and how many ticks it takes to process. Used by: FoodProcessor, ProcessFoodInteraction

ResourceBank

ResourceBanks form a set of complimentary key-to-value and value-to-key dictionaries whose keys are used to identify ScriptableObjects over the network. A ResourceBank is implemented in the project via an Ingredient Bank, which holds reference to all IngredientData ScriptableObjects in the project.

OrderMenu

The OrderMenu is initialized with a collection of available Recipes, and provides a valid set of Ingredients which comprise an order, using a random selection of optional ingredients from the Recipe.

Authority Management

State authority of objects in this sample is all routed through instances of the custom behaviour AuthorityHandler. The public entrypoint is the method RequestAuthority which takes two optional parameters, an Action to be invoked in the case of a successful transfer, and an Action to be invoked in the case of a failure.

Targeted RPCs are utilized both for requesting authority as well as signalling the outcome of requests. When a request is made, a Guid is sent as part of the RPC, representing the expected state of the hierarchy for the object in question. When the RPC is received, this state is compared against the state observed by the recipient. In the case of a discrepancy, the request will be rejected. The request will also be rejected if a transfer for that object is already in progress, or if the client does not possess the state authority.

Debugging

Included is a utility to view which player has authority over what objects. This can be toggled on the Main Camera GameObject in the Game scene by enabling the ViewAuthority component. Objects whose state authority is a valid player will be outlined in the player's selected color. Objects which have a state authority of a disconnected player will be outlined gray.

Note that ViewAuthority relies on another component, Glint, which is responsible for drawing commands to the screen. Glint must be present on the camera object for ViewAuthority to function.

Back to top