Unity is a multiplatform game engine, and it has supported Linux games since Unity 4. Since it is based on Mono, all that is required to run Linux games is an appropiate executable. There are several caveats to this procedure, but it is reasonably doable. I'll be explaining how to do it, my own attempts and it and how they panned out.
Most of this is based on an old wiki post on GamingOnLinux. The article (and the wiki itself) are gone, and they needed an update anyway. I was able to get an archive of it from the owner of GamingOnLinux. There's also an older version on PCGamingWiki.

Before porting

Save yourself some headache first by checking some relevant stuff. For starters, your game only needs manual porting if the game has not been already released on Linux. Games like SUPERHOT already have Unity Linux ports. From here on end, I'll assume the game has no native Linux buiild.
A major limitation of Unity building is that most Windows Unity games do not support OpenGL or Vulkan. You can check pcgamingwiki for information on that, but there is an easier way: You can run the game on windows with the arguments -force-glcore or -force-vulkan. If your game does not boot, the windows port cannot be used for a native port. Thanks to rythin for pointing this out to me.
As a rule of thumb, Mac ports usually support OpenGL right out of the gate. Check if your game has a Mac port too in case the Windows build is not available.
Another relevant element is Unity's introduction of IL2CPP in 2019. This guide will only work with Mono games (which should be any game prior to Unity 2019 and some games after). Porting IL2CPP builds should be possible, but I have not found good ways to do it.
Finally, this guide will not cover porting from Console builds. I have tried my hand at porting Switch builds but no luck so far.

Porting a Windows or Mac game

Obtaining game files

First, get your hands on the copy of the game you will be working with.
For Windows games, the obtained folder structure with GameName.exe and GameName_Data is the same as it would be for the Linux build. For Mac games, the file structure is different and you'll need to move some files around:
  mv GameName.app/Contents/Resources/Data GameName_Data
  mv GameName.app/Contents/Resources/unity\ default\ resources GameName_Data/Resources/unity\ default\ resources
  mv GameName.app/Contents/Resources/UnityPlayerIcon.png GameName_Data/Resources/UnityPlayer.png
The executable is stored in GameName.app/Contents/MacOS/GameName, but it won't be used. The rest of the files are not needed, as they will be replaced with contents from the Linux Unity player later on. GameName is the Unity project game name. You'll have to rename this file later.

Checking Unity version of the game

Second, you need to know which version of Unity is being used. Again, PCGamingWiki is an useful resource here as they list the Unity version quite often for Unity games. However, it never hurts to check and thankfully this is reasonably easy. There are two ways to get this done:
   strings level0 | head -1
If nothing is returned, it's a very old Unity engine version, which has the version information towards the end of the file, but for which no Linux support exists anyway.
   Expected version: 5.6.3p3. Actual version: 5.6.4p1.
Expected version is the version of the executable, in that case Unity Patch Release 5.6.3p3. Actual version is the version of the executable needed, in that case Unity Patch Release 5.6.4p1.

Relevant Unity files

Knowing the exact game version, Unity Linux Playback Engine files needs to be obtained. These can either be taken from another Linux Unity game of the same version, or can be extracted from official Unity Linux Build Support ~100 MB exectuable (Unity 5+) or ~1.5 GB Unity Editor (Unity 4). The files that are essential to work are:
Sometimes additional .so plugin files need to be put in either the GameName_Data/Plugins/x86 directory for 32-bit version or GameName_Data/Plugins/x86_64 for 64-versions. It's not needed in most cases, but if the game needs them, the names can be deducted from .dll files stored in GameName_Data/Plugins directory for Windows, or from .bundle directories in GameName.app/Contents/Plugins for Mac. Some common plugins include:

Obtaining the files

There are two ways of obtaining the required files. The most widely available is to obtain them directly from Unity official downloads. This changes depending on the type of release, of which there are four of:
For Unity 4, you'll need to download the full executable. For Unity 5.3 and above, you can find the downloadable for Linux Build support in the official release page for it, which usually looks like https://unity.com/releases/editor/whats-new/5.3.0-1. The fully archive of downloadable versions is on the Unity Download Archive: https://unity.com/releases/editor/archive
After obtaining the installers, you need to extract the files from them. The archives are an NSIS installers and can be extracted with 7zip. Navigate to the location of the downloaded file for example using cd in terminal and extract the files with e.g. 7z x UnitySetup-version.exe, where version is either the respective version of Linux Support for Editor for Unity 5+ or the full installer for Unity 4 downloaded. For Unity 5+, the files needed will be located in $INSTDIR$_XX_/Variations/ folder, where XX is a random number, and for Unity 4 in Data/PlaybackEngines/linuxstandalonesupport/Variations/ folder. The variations needed are most likely the linux64_withgfx_nondevelopment_mono and/or linux32_withgfx_nondevelopment_mono, but feel free to experiment.
For Unity 2019 and onward, they changed the way the NSIS installers are packaged and therefore you might not get any actual files form them. If you run into this issue, you can instead download the Mac version of the Linux build target support package, for example: https://download.unity3d.com/download_unity/b7c424a951c0/MacEditorTargetInstaller/UnitySetup-Linux-Support-for-Editor-2018.4.1f1.pkg. You can open this with 7zip as well, but you'll have to decompress the Payload specifically, which you can do with this command: cat Payload | gunzip -dc | cpio -i.
Only the files mentioned in Obtaining Unity files section are needed, so feel free to remove the rest – replacing the files that ship with Windows game may result in game not starting otherwise! Renaming LinuxPlayer to GameName and Data directory to GameName_Data is also needed, where GameName is the game name (see Obtaining game files section.)
You can also get the files from an already existing Linux Unity game using the same Unity version. The process should be identical otherwise.
Once you've obtained the files, make a copy of your game directory, replace the files as stated above, and you should have a native build of your game! Make sure to run it on its own before jumping into libTAS, to make sure any potential issues are not caused by libTAS itself.

Debugging

if your build doesn't work, don't despair. Unity games usually print any debug information for errors to an specific folder found on ~/.config/unity3d. The folder then goes to developer name and game name. That's also where the game will store save data. Reading this information will help find issues be it on your port or while running the game with libTAS.

Working with libTAS

Once you've confirmed the game runs, you can connect it with libTAS. Open the location of your executable in libTAS to get started. To ensure sync, add -force-gfx-direct to the Command Line Arguments, as otherwise some games will refuse to run or desync heavily. Since Unity is based on Mono, you might need to check Runtime - Time Tracking - clock_gettime() (for libTAS 1.4.3 or prior) or clock_gettime() monotonic (libTAS 1.4.4+). DO THIS ONLY TO AVOID SOFTLOCKS, as enabling this otherwise is likely to introduce more desync possibilities.
Ask me how I know.

Common Issues

Desyncs are by far the most common enemy of Unity TASers. Even with all the precautions, Unity games love async loading, and you will have to come to understand how your game handles loading to avoid issues. It's worth mentioning that Unity games are remarkably easy to decompile, to the point where that info is widely available and I won't provide it here. Taking a look at code to figure out potential trouble points never hurts.

Tested games

Here's an absolutely not comprehensive list of Unity games that have been user ported, and the degree of success to which they worked.
GameUnity VersionPorted byStatus
Untitled Goose Game2018.4.1f1WDN2010Worked with libTAS 1.4.2, and was submitted, but the judge could not get it to sync. Has been tested in newer libTAS versions and it appears to work better.
Cuphead5.6.2p1/2017.4.9f1DemoJameson/SBDWolfWorks, but has serious desync issues
Sayonara Wild Hearts2019.4.1f1ikuyoWorks in libTAS 1.4.4 with minor desync issues.
Yo! Noid 22017.4.9f1rythinWorked well enough to get published!
Dandara2018.4.12f1kilayeWorks, but has issues with RNG
Bug Fables2018.4.12f1CyanDirect3D only, unlikely to work
Cave Story's Secret Santa2021.2.1f1ikuyoDirect3D only

HomePages/ikuyo/Unity last edited by ikuyo on 1/8/2023 10:44 PM
Page History Latest diff List referrers View Source