Advanced Modding

Beyond editing C# code, you can also add new Unity assets.

Limitations of C# Editing

There is a lot you can do with just editing C#, but there are also strong limitations:

  • It’s impossible to add new 3D models.
  • It’s hard or impossible to add new 2D content.
  • It’s very difficult to modify parameters that are encoded in Unity assets rather than in the code.
    • For example, the list of recipes that are available for a level is not encoded in Assembly-CSharp.dll, but in assets that are specific to the level. It’s possible to change this in the code, but it’s very awkward and requires creative trickery.

Difficulty of Unity Asset Editing

You may have heard of tools like AssetStudio or UABE that can extract and edit Unity assets. Unfortunately, none of these work well for this game. There are a few reasons:

  • These tools mostly specialize in replacing graphical or audio assets, but most Overcooked mods would also require editing ScriptableObject objects (essentially, simple serialized objects without graphics). That makes these tools rather awkward to use.
  • The game uses streaming assets, which are newer than the old Unity asset formats supported by these outdated tools. I wasn’t able to get any of these to work even for basic asset replacement.

Using Unity Itself to Add Assets

The fact that the game uses StreamingAssets is actually very helpful to us. It means that we can compile an asset bundle using the official Unity Editor, and then just load it at runtime.

This is so clean - we don’t need to modify any of the existing assets at all. If we need to replace an existing asset, we can always just edit the code to modify some variable to point to our new asset.

However, there is a serious challenge. It’s not very useful to just add fresh new assets. These assets need references to existing assets. This becomes a real problem when creating these assets in Unity, since we don’t have the existing assets to reference at all.

It would be nice if we could load existing assets into the Unity Editor, but that’s not how it works. The Unity compilation process is lossy so that it’s not possible to revert the compiled assets back to editable assets.

A Creative Solution

We’ll first use uTinyRipper to reverse-engineer the game into a Unity project. This is far from perfect - there are numerous problems with the generated project, but it will give us the existing assets just so that they can be referenced. If we create a new asset this way and compile it into a new asset bundle (without the existing assets), when loading it at runtime, the new asset will reference the real existing asset in the game (because they have the same object ID as the reverse-engineered assets).

This is the basic idea, but there are a few more major issues to work out:

  • The generated project is not compilable, and Unity will refuse to export asset bundles unless we make it compilable.
  • uTinyRipper cannot decompile shaders, so any new asset we create has defective materials that must be fixed at runtime.
  • We cannot easily add new C#-backed components that are referenced by new assets, because there is a circular dependency problem.

Discord

Use this link to join my Overcooked Modding and TAS Discord Server!