How do I start the Linux version of X3: Reunion from GOG in Fedora?

You should install zlib.i686 in addition to the regular zlib (x64), and (force) your game to link to it. It may work immediately, or you may have to use symlinks to get the game to load the correct library version.

The old version of zlib I need doesn't have an installer anymore, how do I install from source?

If the game is specifically looking for 1.2.9 (an obsolete version) then while we could try to utilize a newer version, this might cause bugs or crashes (although I guess that to be unlikely; this is a compression library which should want to be backwards-compatible). So there's no easy to install packages, which means you will have to compile the code yourself.

For that, you need a compiler. Take a look at the file Makefile.in. It contains all the instructions to compile the program. It also seems to be written in C, so we need a C compiler. I recommend installing either gcc or clang via your package manager if you don't have these already.

I recommend creating a working directory (in this example: ~/zlib129/). If you're paranoid, you can chroot into this directory to prevent any commands executed to compile code from affecting the rest of your system. Then commands to proceed would look like:

# Creates a directory to house the source code
mkdir ~/zlib129/
mkdir ~/zlib129/source/
# Create a directory to house the output of the compilation
mkdir ~/zlib129/chroot/
# Go into the directory
cd ~/zlib129/source/
# Download the zlib archive
wget https://zlib.net/fossils/zlib-1.2.9.tar.gz
# Extract it, skipping the root folder. 
tar -xvzf zlib-1.2.9.tar.gz --strip-components=1
# Let's check out how to compile it
nano makefile.in
### Read the instructions on how to compile...
./configure 
make install prefix=/home/grubbel/zlib129/chroot/
### Move the library to where we want it. 
### One easy thing to just do is put it in the game's lib folder (if it has one preconfigured). 
mv ~/zlib129/chroot/lib/libz.so.1 /path/to/game/lib/libz.so.1

Note: If you manage to compile the library, but the game can't find it in its own folder, then try using the LD_LIBRARY_PATH environment variable trick from my comment.

The reason why your solution doesn't work:

System libraries typically come in two flavors, in addition to a host of versions. Typically these two flavors (64- and the older 32-bit) are put in different folders. Usually something akin to /lib versus /lib64. For historic reasons distributions don't have the same naming convention for this.

By symlinking to it, you are trying to load a 64-bit library into a 32-bit binary. This won't work, because the pointer sizes are different. Pointers are a thing that all C and C++ programs must use to pass variables (such as buffers with data or text in them) between eachother.

A pointer is a number pointing to a location in memory; the N-th byte in virtual memory. 32-bit (or i686, from the name of the ubiquitous 32-bit Intel processor series 286..386..486, etc.), programs, as the name implies, use pointers that are 32 bits in width, or 4 bytes. 64-bit programs, on the other hand, use pointers that are 64 bits in width, or 8 bytes.

So when zlib expects a pointer to a string to be zipped (compressed), it expects a 64-bit address. It would segmentation fault (the OS terminates programs that try to access nonexistent or unpermissable memory) and crash if you gave it a 32-bit address instead , as the other 32 bits would be filled with random garbage. The same goes the other way around: the game wouldn't be able to interpret a 64-bit address returned from the library because it wouldn't fit in the variable.

It's likely that your linker won't even let you do this and will loudly complain to you instead of letting your application halt and catch fire.

Why do I sometimes have to symlink these libraries?

The game wasn't made with the consideration in mind that one day there could be multiple pointer sizes in use on the same system. It also was made on a linux system where libraries may have been in /lib instead of /usr/lib, and this may have been hardcoded. There are a lot more linux distributions nowadays and conventions have changed. Things usually work but you may need to fiddle to get older programs to behave properly.

When it was programmed, 64-bit PC's didn't exist yet. As far as it is concerned, a pointer is a 32-bit unsigned integer. In fact, a lot of game developers get even this wrong and freely cast to signed ints, which is why a some older games crash as soon as they get to 2GiB memory and why Windows has a special flag that the programmer needs to set before a 32-bit app is allowed more than 2GiB memory.


So, how I got X3: Reunion to run on Fedora:

1.) Install the following packages:

glibc-devel.i686
  which should install as dependencies:
    libxcrypt-devel.i686
alsa-lib.i686
alsa-lib-devel.i686
alsa-plugins-pulseaudio.i686
gtk2.i686
  which should install as dependencies:
    atk.i686, gdk-pixbuf2-modules.i686 and jasper-libs.i686
libxml2.i686
libxml2-devel.i686
  which should install as dependencies:
    cmake-filesystem.i686, xz-devel.i686, xz-devel.x86_64 and zlib-devel.i686 

2.) Get the older zlib version from here and compile it.

# Create a directory to house the source code
mkdir ~/zlib129/
mkdir ~/zlib129/source/
# Create a directory to house the output of the compilation
mkdir ~/zlib129/chroot/
# Go into the directory
cd ~/zlib129/source/
# Download the zlib archive
wget https://zlib.net/fossils/zlib-1.2.9.tar.gz
# Extract it, skipping the root folder. 
tar -xvzf zlib-1.2.9.tar.gz --strip-components=1
# Let's check out how to compile it
nano makefile.in
### Read the instructions on how to compile...
./configure 
make install prefix=/home/YourUsername/zlib129/chroot/
### Move the library to where we want it. 
### But rename the old one first.
mv ~/GOG Games/X3 Reunion/game/lib/libz.so.1 ~/GOG Games/X3 Reunion/game/lib/libz.so.1.old
mv ~/zlib129/chroot/lib/libz.so.1 ~/GOG Games/X3 Reunion/game/lib/libz.so.1

3.) Install the nvidia 32-bit libraries or just your respective gpu driver 32-bit libraries, in this answer I will cover the nvidia one.

Just:

sudo dnf install xorg-x11-drv-nvidia-340xx-libs.i686 

or

sudo dnf install xorg-x11-drv-nvidia-libs.i686

the later one seems to be for newer gpus while the first one was for my gpu, I have a rather old one. If you should have an older gpu, too, but not the 340 version driver just replace the 340 with your version.

4.) Then delete the ~/GOG Games/X3 Reunion/lib folder or rename it and start the game.

And that's it, wish you a happy gaming.


Special thanks to aphid from here and PabloTwo from the FedoraForum.


sources of research were:

https://stackoverflow.com/questions/48306849/lib-x86-64-linux-gnu-libz-so-1-version-zlib-1-2-9-not-found

https://www.gog.com/forum/x_series/x3_terran_war_linux_shared_library_issues

https://bbs.archlinux.org/viewtopic.php?pid=1864555#p1864555

https://forums.fedoraforum.org/showthread.php?326065-Will-32-bit-nvidia-libraries-interfere-with-the-64-bit-ones