220 lines
10 KiB
Plaintext
220 lines
10 KiB
Plaintext
---
|
|
title: "Stardew Valley on aarch64"
|
|
---
|
|
|
|
At the end of last year I got a Pinebook Pro - mostly for reasons of paranoia.
|
|
So far, it's been pretty good, but there was
|
|
one thing that I couldn't get working: Stardew Valley
|
|
|
|
You could call me a little bit addicted to this game, but it's proprietary,
|
|
closed-source, and the authors don't release binaries compiled for aarch64 -
|
|
although they do very kindly release x86_32 and x86_64 Linux binaries, which
|
|
is more than most companies do.
|
|
|
|
I left a message on the forum and moved on, confident that it wouldn't ever
|
|
happen. I vaguely knew it was written in C#, but it's not an ecosystem I have
|
|
any experience in. I figured it was going to be the kind of thing that comes
|
|
under "possible, but not trivial" - and aarch64 + linux is super-niche.
|
|
|
|
Fast forward a few weeks, I mentioned it in passing on the `#pinebook` IRC
|
|
channel, which went a little like:
|
|
|
|
```
|
|
<lupine> stardew valley never got back to me *sob*
|
|
<halosghost> lupine: trying to get Stardew Valley on the pbp as well?
|
|
<Nadia> The game itself is written in C# so runs through Mono
|
|
<lupine> they don't distribute aarch64-linux executables
|
|
<Nadia> You just need to build the libraries it needs and it should run
|
|
<lupine> it's closed source, so "just need to build" is rather an issue
|
|
```
|
|
|
|
They rather roundly assured me that it wasn't an issue at all, and literally
|
|
10 minutes later I had a working Stardew Valley setup. This is incredible.
|
|
|
|
I'm documenting the steps I took so I can come back to this in the future, but
|
|
maybe it'll be useful for others too.
|
|
|
|
First, you need a copy of the game. I was working with v1.4 as shipppd by
|
|
GOG Games. It comes as one of those `.sh` files that contains an archive. That
|
|
doesn't have aarch64 support, and doesn't run on the PBP. Fortunately, I'd
|
|
already installed it on an amd64 laptop so I just rsynced that over:
|
|
|
|
```
|
|
lupine@pbp:~$ rsync -avzP '10.0.1.104:GOG Games' .
|
|
|
|
# Might as well grab my savegames at the same time
|
|
lupine@pbp:~$ rsync -avzP 10.0.1.104:.config/StardewValley .config/StardewValley
|
|
```
|
|
|
|
I'm sure it's possible to make it run, I'm just being lazy. I'll update this in
|
|
the future if I work out how to go from the `.sh` file.
|
|
|
|
What does this give us?:
|
|
|
|
```
|
|
lupine@pbp:~/GOG Games/Stardew Valley/game$ ls -lh
|
|
total 438M
|
|
-rwxrwxr-x 1 lupine lupine 12K Dec 8 23:58 BmFont.dll
|
|
drwx--x--x 17 lupine lupine 4.0K Dec 8 23:58 Content
|
|
-rwxrwxr-x 1 lupine lupine 330K Dec 8 23:58 GalaxyCSharp.dll
|
|
-rwxrwxr-x 1 lupine lupine 336 Dec 8 23:58 GalaxyCSharp.dll.config
|
|
-rwxrwxr-x 1 lupine lupine 91K Dec 8 23:58 goggame-1453375253.hashdb
|
|
-rwxrwxr-x 1 lupine lupine 782 Dec 8 23:58 goggame-1453375253.info
|
|
drwx--x--x 2 lupine lupine 4.0K Dec 8 23:58 lib
|
|
drwx--x--x 2 lupine lupine 4.0K Dec 8 23:58 lib64
|
|
-rwxrwxr-x 1 lupine lupine 197M Dec 8 23:59 libGalaxyPeer64.so
|
|
-rwxrwxr-x 1 lupine lupine 177M Dec 8 23:59 libGalaxyPeer.so
|
|
-rwxrwxr-x 1 lupine lupine 5.3M Dec 8 23:59 libSkiaSharp.dll
|
|
-rwxrwxr-x 1 lupine lupine 119K Dec 8 23:58 Lidgren.Network.dll
|
|
lrwxrwxrwx 1 lupine lupine 14 Dec 9 00:00 mcs -> mcs.bin.x86_64
|
|
-rwxrwxr-x 1 lupine lupine 17M Dec 8 23:59 mcs.bin.x86
|
|
-rwxrwxr-x 1 lupine lupine 16M Dec 8 23:59 mcs.bin.x86_64
|
|
drwx--x--x 3 lupine lupine 4.0K Dec 8 23:59 mono
|
|
-rwxrwxr-x 1 lupine lupine 2.5K Dec 8 23:59 monoconfig
|
|
-rwxrwxr-x 1 lupine lupine 1.3M Dec 8 23:58 MonoGame.Framework.dll
|
|
-rwxrwxr-x 1 lupine lupine 527 Dec 8 23:58 MonoGame.Framework.dll.config
|
|
-rwxrwxr-x 1 lupine lupine 203K Dec 8 23:58 Mono.Posix.dll
|
|
-rwxrwxr-x 1 lupine lupine 328K Dec 8 23:58 Mono.Security.dll
|
|
-rwxrwxr-x 1 lupine lupine 3.6M Dec 8 23:59 mscorlib.dll
|
|
-rwxrwxr-x 1 lupine lupine 267K Dec 8 23:58 SkiaSharp.dll
|
|
-rwxrwxr-x 1 lupine lupine 1.2K Dec 8 23:58 StardewValley
|
|
-rwxrwxr-x 1 lupine lupine 4.0M Dec 8 23:58 StardewValley.bin.x86
|
|
-rwxrwxr-x 1 lupine lupine 3.8M Dec 8 23:58 StardewValley.bin.x86_64
|
|
-rwxrwxr-x 1 lupine lupine 4.1M Dec 8 23:58 StardewValley.exe
|
|
-rwxrwxr-x 1 lupine lupine 6.5K Dec 8 23:58 StardewValley.GameData.dll
|
|
-rwxrwxr-x 1 lupine lupine 127K Dec 8 23:58 System.Configuration.dll
|
|
-rwxrwxr-x 1 lupine lupine 879K Dec 8 23:58 System.Core.dll
|
|
-rwxrwxr-x 1 lupine lupine 2.0M Dec 8 23:58 System.Data.dll
|
|
-rwxrwxr-x 1 lupine lupine 2.2M Dec 8 23:58 System.dll
|
|
-rwxrwxr-x 1 lupine lupine 442K Dec 8 23:58 System.Drawing.dll
|
|
-rwxrwxr-x 1 lupine lupine 966K Dec 8 23:58 System.Runtime.Serialization.dll
|
|
-rwxrwxr-x 1 lupine lupine 130K Dec 8 23:58 System.Security.dll
|
|
-rwxrwxr-x 1 lupine lupine 3.1M Dec 8 23:58 System.Xml.dll
|
|
-rwxrwxr-x 1 lupine lupine 131K Dec 8 23:58 System.Xml.Linq.dll
|
|
-rwxrwxr-x 1 lupine lupine 161K Dec 8 23:58 WindowsBase.dll
|
|
-rwxrwxr-x 1 lupine lupine 48K Dec 8 23:59 xTile.dll
|
|
-rwxrwxr-x 1 lupine lupine 9.0K Dec 8 23:59 xTilePipeline.dll
|
|
```
|
|
|
|
The magic here is that not all the `.dll` and `.exe` files here are **Windows**
|
|
object files. Instead, many of them are just Mono bytecode, which is analogous
|
|
to JVM bytecode:
|
|
|
|
```
|
|
lupine@pbp:~/GOG Games/Stardew Valley/game$ file StardewValley*
|
|
StardewValley: Bourne-Again shell script, ASCII text executable
|
|
StardewValley.bin.x86: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4801f8881feefa8aa515f9fadc02c01598c44131, not stripped
|
|
StardewValley.bin.x86_64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=04fe4f2c2ca8b4dc7faf70c643417bf0df632a9e, not stripped
|
|
StardewValley.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows
|
|
StardewValley.GameData.dll: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows
|
|
```
|
|
|
|
We need Mono to run these assemblies. I guess the `StardewValley.bin.*` files
|
|
ar just stripped-down Mono runtimes that invoke `StardewValley.exe`!
|
|
|
|
The `mcs.*` binaries are "Mono C Sharp" - I don't know C#, but I assume it's
|
|
another essential part of the runtime.
|
|
|
|
Debian has Mono + MCS already, so...
|
|
|
|
```
|
|
lupine@pbp~/GOG Games/Stardew Valley/game$ sudo apt install mono-runtime mono-rcs
|
|
lupine@pbp~/GOG Games/Stardew Valley/game$ ln -sf `which mcs`
|
|
```
|
|
|
|
We can then try to run the game:
|
|
|
|
```
|
|
lupine@pbp~/GOG Games/Stardew Valley/game$ mono StardewValley.exe
|
|
```
|
|
|
|
Amazingly, that's **almost sufficient**, all by itself, to get a fully working
|
|
game, at least for me. It starts up, and the only obviously broken thing is
|
|
sound. There are some complaints on the comamnd line that don't seem to get in
|
|
the way of actually playing it.
|
|
|
|
Wat.
|
|
|
|
No sound is annoying though, how about we fix that?
|
|
|
|
Turns out Stardew Valley only **requires** two external libraries: SDL and
|
|
libasound. I've no idea if the graphics is working even though it can't find
|
|
SDL, or if it can find my native SDL libary but not the libasound one, or what,
|
|
but it's trivial to fix. Edit `MonoGame.Framework.dll.config` and add these
|
|
two lines:
|
|
|
|
```
|
|
<dllmap dll="SDL2.dll" os="linux" cpu="armv8" target="./libaarch64/libSDL2-2.0.so.0"/>
|
|
<dllmap dll="soft_oal.dll" os="linux" cpu="armv8" target="./libaarch64/libopenal.so.1" />
|
|
```
|
|
|
|
Now you just need to put those two .so files into that directory locally, and
|
|
sound begins to work!
|
|
|
|
(I just symlinked `/usr/lib/aarch64-linux-gnu` into place, which does the same
|
|
job).
|
|
|
|
At this point the game works perfectly, including LAN multiplayer - which is
|
|
ridiculous - and despite worries about endianness, it can load and run my saves
|
|
as well.
|
|
|
|
There are a few complaints on the console though. Let's see what we can do
|
|
about them.
|
|
|
|
|
|
```
|
|
Your mono runtime and class libraries are out of sync.
|
|
The out of sync library is: /home/lupine/GOG Games/Stardew Valley/game/System.dll
|
|
```
|
|
|
|
OK, these are shipped with `mono-runtime` (actually in `libmono-system4.0-cil`)
|
|
anyway. The complaint is that these assemblies were compiled with a different
|
|
version of Mono, but it's falling back to the main ones anyway, so we can just
|
|
move these out of the way.
|
|
|
|
The only `System.*.dll` file we need to keep is `System.Runtime.Serialization.dll` -
|
|
the rest can be moved out of the way.
|
|
|
|
```
|
|
System.TypeInitializationException: The type initializer for 'Galaxy.Api.GalaxyInstance' threw an exception. ---> System.TypeInitializationException: The type initializer for 'CustomExceptionHelper' threw an exception. ---> System.DllNotFoundException: GalaxyCSharpGlue
|
|
at (wrapper managed-to-native) Galaxy.Api.GalaxyInstance+CustomExceptionHelper.CustomExceptionRegisterCallback(Galaxy.Api.GalaxyInstance/CustomExceptionHelper/CustomExceptionDelegate)
|
|
at Galaxy.Api.GalaxyInstance+CustomExceptionHelper..cctor () [0x00011] in <22373852dcce42128dc7e065ea92368d>:0
|
|
--- End of inner exception stack trace ---
|
|
at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_generic_class_init(intptr)
|
|
at Galaxy.Api.GalaxyInstance..cctor () [0x00000] in <22373852dcce42128dc7e065ea92368d>:0
|
|
--- End of inner exception stack trace ---
|
|
at StardewValley.SDKs.GalaxyHelper.Initialize () [0x00000] in <1ed49e648be548bcae8e4508597c9f4c>:0
|
|
|
|
```
|
|
|
|
I am *astonished* that this one isn't a fatal error - but the game runs fine
|
|
even though it can't find an external library. Ridiculous.
|
|
|
|
Galaxy is GOG's multiplayer gubbins. If you've got a Steam game, it's different,
|
|
I'm sure, but the functionality this stuff is *for* is to negotiate multiplayer
|
|
games with strangers.
|
|
|
|
I have no use for this myself, but `libGalaxyCSharpGlue.so` is looked up via
|
|
another dllmap in `GalaxyCSharp.dll.config` - it's not packaged by Debian, and
|
|
it may even be proprietary GOG code, but if we can get an aarch64 version of it,
|
|
making it work should be as simple as adding an entry there.
|
|
|
|
If this did become a fatal error at some point, the minimum work would be a stub
|
|
implementation that meets the ABI but always says "no games available" or some
|
|
such.
|
|
|
|
And... that's all the errors. Despite a different architecture, despite being
|
|
short some libraries, and despite running reverse-engineered (Panfrost) graphics
|
|
drivers with only a bare whisper of OpenGL support, my favourite game is running
|
|
at normal speed on an architecture its authors and publishers didn't even think
|
|
about.
|
|
|
|
Again I say: ridiculous
|
|
|
|
...maybe I should learn some CSharp?
|
|
|
|
=> https://pine64.org/pinebook-pro Pinebook Pro
|
|
=> https://stardewvalley.com/ Stardew Valley
|
|
=> https://community.playstarbound.com/threads/arm-arm64-aarch64-linux-support.158840/ Forum message
|
|
=> https://www.gog.com/game/stardew_valley GOG Games: Stardew Valley
|