OpenLoco

Bild des Benutzers meldrian

OpenLoco ist eine freie Engine für Chris Sawyer’s Locomotion aus dem Jahre 2004 und der Nachfolger von Transport Tycoon. Seit Version 0.18.02 kann sie auch unter Mac-OS und Linux kompiliert und ausgeführt werden. Die Original-Spieldaten werden zum Ausführen benötigt.

Installation

Originale Spieldateien

Eine Anleitung wie man über die verschiedenen Plattformen an die notwendigen Dateien kommt, findet sich auf Github innerhalb des verwandten OpenRCT2-Projekts wieder. Das Vorgehen kann analog auch im Zusammenhang mit Sid Mayers Locomotion angewandt werden. Link.

Ubuntu

Die nachfolgenden Schritte führten auf einem in einer VM frisch installierten Ubuntu 22.04 zum Erfolg. Auch auf einem bereits älteren produktiven Ubuntu 20.04 gelang der Bau des Pakets, allerdings kam es dort zu einem Konflikt mit den 64bit Varianten von "libsdl2-mixer-2.0-0" und "libopusfile0". Möchte man den Konflikt beheben werden darauf angewiesene Programme, beim Test waren das bspw. Blob Wars - Metal Blob Solid und Cataclysm: Dark Days Ahead, ebenfalls entfernt.
Stand August 2022 gibt es (noch) keine Unterstützung der Anwendung für 64bit. Daran wird weiterhin gearbeitet.
Sofern noch nicht in anderem Zusammenhang erfolgt muss man seinem System die Liebe zu 32bit zuvor wieder näher bringen.

sudo dpkg --add-architecture i386

Paketquellen aktualisieren und ausstehende Updates installieren.

sudo apt-get update || sudo apt-get upgrade

Wer Software kompilieren möchte muss das Betriebssystem zuvor mit den notwendigen Bibliotheken und Programmen ausstatten.

sudo apt-get install --no-install-recommends -y pkg-config:i386 g++-multilib cmake git ninja-build libsdl2-dev:i386 libsdl2-mixer-dev:i386 libpng-dev:i386 libyaml-cpp-dev libopenal-dev:i386

Mit dem nach diesem Schritt installierten GIT bezieht man den aktuellsten Stand der Entwicklung des Projekts.

git clone https://github.com/OpenLoco/OpenLoco.git

Dies resultiert in einem Ordner OpenLoco samt Inhalt. Dieser wird betreten.

cd OpenLoco

Hier bedarf es eines Ordners "build" von dem aus später gearbeitet werden wird.

mkdir build

Das Projekt benötigt YAML-cpp, jedoch geht Ubuntu aktuell teils stiefmütterlich damit um. Die Entwickler der Engine haben darauf reagiert und den Bau von YAML-cpp in den Kompilierprozess integriert, jedoch muss mal das Paket an der korrekten Stelle platzieren.
Man navigiert also nach /Thirdparty

cd src/Thirdparty

und bezieht via GIT das aktuellste YAML-cpp Paket.

git clone https://github.com/jbeder/yaml-cpp.git

Nun navigiert man in den weiter oben erwähnten Ordner /build.

cd ../../build

... und beginnt nachfolgend den Prüfprozess vor dem eigentlichen Bau des Programms

CXXFLAGS="-m32" cmake .. -G Ninja

Auf eventuelle Fehler (fehlende oder falsche Pakete) ist entsprechend zu reagieren. Hat alles geklappt, startet man den Bau der ausführbaren Datei "openloco".

ninja

Erneut gilt es den Prozess abzuwarten und auf eventuelle Meldungen zu reagieren. Hat alles funktioniert besitzt man nun unter /build eine ausführbare Datei "openloco". Diese ist an dieser Stelle deplatziert und muss eine Ordnerebene nach oben verschoben werden.

mv openloco ..

Gestartet werden kann das Spiel mit

./openloco

Der Pfad zu den Spieldateien wird beim Start des Programms im Terminal(!) abgefragt und muss dort entsprechend hinterlegt werden. Achtung: Der Ordnerpfad sollte keine Leerzeichen enthalten um Probleme zu vermeiden.

openSUSE

zypper in -y libSDL2-devel libpng16-devel openal-soft-devel libyaml-devel yaml-cpp-devel glibc-devel-32bit gcc-32bit gcc-c++-32bit libSDL2-devel-32bit

Nächster Schritt, das Herunterladen eines Release von OpenLoco aus dem Releases: Link. Beachtet, dass OpenLoco weiterhin erstmal nur als 32bit angeboten wird, wir daher unbedingt die 32bit Bibliotheken benötigen. Für openSUSE müssen wir zudem noch einige Standard-Pfade aus dem Preset anpassen und die Google-Test-Suite deaktivieren, denn sie liegt hier nur als 64bit vor:

cmake --preset linux_release -DPNG_LIBRARY:FILEPATH=/lib/libpng16.so -DGTEST_ROOT:FILEPATH=/lib -DZLIB_LIBRARY:FILEPATH=/lib -DSDL2_DIR:PATH=/lib -DOPENLOCO_BUILD_TESTS=NO

Dann bauen:

cmake --build --preset linux_release

Sollten cmake oder make Fehler werfen erfährt man über die Suchmaschine der eigenen Wahl häufig über die Fehlermeldung eine zum Problem passende Lösung. Falls weiterhin Probleme bestehen bietet sich der Kommentarbereich unter diesem Artikel oder das Holarse Forum an.

Sollte make abgeschlossen worden sein, kopiert die nun existierende Datei "openloco" im Verzeichnis build in das Wurzelverzeichnis (/home/benutzer/spiele/openloco/). Startet openloco über ein Terminal mit

./openloco

hier wird man nach dem Pfad zu den originären Spieldaten gefragt. Diese könnt ihr zum Beispiel aus dem GOG-Installer mit dem innoextract extrahieren:

innoextract -L -d . -I /data -e setup_chris_sawyers_locomotion_4.02.176_\(22259\).exe

, oder natürlich aus dem Original über Wine.

Screenshots und Videos
Heinz
Bild des Benutzers Heinz
Offline
Beigetreten: 15.01.2019
Beiträge: 1

Kann mir jemand bei untenstehender Fehlermeldung weiterhelfen? Ist unter Ubuntu 16.04.
Es war nicht leicht, eine Version von gcc und c++ zu finden, mit der der Befehlt "cmake .." funktionierte. Momentan habe ich Version 6.5.

XXX@XXX-W65-67SH:~/Schreibtisch/OpenLoco-18.02/build$ make
[  5%] Built target segfiles
[  5%] Building CXX object CMakeFiles/openloco.dir/src/openloco/audio/audio.cpp.o
In file included from /home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:3:0,
                 from /home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/audio.cpp:2:
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:10:36: error: ‘wstring_view’ in namespace ‘std’ does not name a type
     std::string to_utf8(const std::wstring_view& src);
                                    ^~~~~~~~~~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:11:38: error: ‘string_view’ in namespace ‘std’ does not name a type
     std::wstring to_utf16(const std::string_view& src);
                                      ^~~~~~~~~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:13:43: error: ‘string_view’ in namespace ‘std’ does not name a type
     static inline bool iequals(const std::string_view& a, const std::string_view& b)
                                           ^~~~~~~~~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:13:70: error: ‘string_view’ in namespace ‘std’ does not name a type
    static inline bool iequals(const std::string_view& a, const std::string_view& b)
                                                                     ^~~~~~~~~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp: In function ‘bool openloco::utility::iequals(const int&, const int&)’:
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:15:15: error: request for member ‘sizein ‘a’, which is of non-class type ‘const int’
         if (a.size() != b.size())
               ^~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:15:27: error: request for member ‘sizein ‘b’, which is of non-class type ‘const int’
         if (a.size() != b.size())
                           ^~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:19:34: error: request for member ‘sizein ‘a’, which is of non-class type ‘const int’
         for (size_t i = 0; i < a.size(); i++)
                                  ^~~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:21:33: error: invalid types ‘const int[size_t {aka unsigned int}]for array subscript
             if (std::tolower(a[i]) != std::tolower(b[i]))
                                 ^
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/../utility/string.hpp:21:55: error: invalid types ‘const int[size_t {aka unsigned int}]for array subscript
             if (std::tolower(a[i]) != std::tolower(b[i]))
                                                       ^
In file included from /home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/audio.cpp:2:0:
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp: At global scope:
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:329:21: error: ‘byte’ is not a member of ‘std’
         std::vector<std::byte> state;
                     ^~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:329:30: error: template argument 1 is invalid
         std::vector<std::byte> state;
                              ^
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:329:30: error: template argument 2 is invalid
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:332:27: error: ‘byte’ is not a member of ‘std’
         const std::vector<std::byte>& get_state() const
                           ^~~
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:332:36: error: template argument 1 is invalid
         const std::vector<std::byte>& get_state() const
                                    ^
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/../interop/interop.hpp:332:36: error: template argument 2 is invalid
/home/XXX/Schreibtisch/OpenLoco-18.02/src/openloco/audio/audio.cpp:8:40: error: ‘maybe_unused’ attribute directive ignored [-Werror=attributes]
     [[maybe_unused]] constexpr int32_t play_at_centre = 0x8000;
                                        ^~~~~~~~~~~~~~
cc1plus: error: unrecognized command line option ‘-Wno-unused-private-field’ [-Werror]
cc1plus: all warnings being treated as errors
CMakeFiles/openloco.dir/build.make:70: die Regel für Ziel „CMakeFiles/openloco.dir/src/openloco/audio/audio.cpp.o“ scheiterte
make[2]: *** [CMakeFiles/openloco.dir/src/openloco/audio/audio.cpp.o] Fehler 1
CMakeFiles/Makefile2:136: die Regel für Ziel „CMakeFiles/openloco.dir/all“ scheiterte
make[1]: *** [CMakeFiles/openloco.dir/all] Fehler 2
Makefile:83: die Regel für Ziel „all“ scheiterte
make: *** [all] Fehler 2

comrad
Bild des Benutzers comrad
Offline
Beigetreten: 13.05.2008
Beiträge: 5630

Cmake ist erstmal nur ein Build-Tool. Wahrscheinlich braucht OpenLoco eine bestimmte Version vom C++-Compiler. Hast du auch die CFLAGS gesetzt? Die Anleitung sagt ja:

mkdir build
cd build
CXXFLAGS="-m32" cmake ..
make

ich hab das mal versucht nachzuvollziehen. Meine openSUSE 15 hat GCC 7, das scheint auch nicht zu gehen, weil er aus irgendeinem Grund die 32bit Binary mit dem 64bit Linker linken will.

karl
Bild des Benutzers karl
Offline
Beigetreten: 01.02.2020
Beiträge: 1

Hi, leider bekomme ich unter Ubuntu Mate 19.10 nach make folgende Fehlermeldung:

Scanning dependencies of target segfiles
[  1%] Generating openloco_text
214+0 Datensätze ein
214+0 Datensätze aus
876544 Bytes (877 kB, 856 KiB) kopiert, 0,00231486 s, 379 MB/s
[  3%] Generating openloco_data
78+0 Datensätze ein
78+0 Datensätze aus
319488 Bytes (319 kB, 312 KiB) kopiert, 0,00125086 s, 255 MB/s
3133+0 Datensätze ein
3133+0 Datensätze aus
12832768 Bytes (13 MB, 12 MiB) kopiert, 0,0182692 s, 702 MB/s
[  3%] Built target segfiles
[  5%] Generating openloco_text_section.o
[  7%] Generating openloco_data_section.o
Scanning dependencies of target openloco
[  9%] Building CXX object CMakeFiles/openloco.dir/src/openloco/audio/audio.cpp.o
[ 11%] Building CXX object CMakeFiles/openloco.dir/src/openloco/company.cpp.o
[ 12%] Building CXX object CMakeFiles/openloco.dir/src/openloco/companymgr.cpp.o
[ 14%] Building CXX object CMakeFiles/openloco.dir/src/openloco/config.cpp.o
[ 16%] Building CXX object CMakeFiles/openloco.dir/src/openloco/console.cpp.o
[ 18%] Building CXX object CMakeFiles/openloco.dir/src/openloco/date.cpp.o
[ 20%] Building CXX object CMakeFiles/openloco.dir/src/openloco/environment.cpp.o
[ 22%] Building CXX object CMakeFiles/openloco.dir/src/openloco/graphics/gfx.cpp.o
[ 24%] Building CXX object CMakeFiles/openloco.dir/src/openloco/gui.cpp.o
[ 25%] Building CXX object CMakeFiles/openloco.dir/src/openloco/industry.cpp.o
[ 27%] Building CXX object CMakeFiles/openloco.dir/src/openloco/industrymgr.cpp.o
[ 29%] Building CXX object CMakeFiles/openloco.dir/src/openloco/input.cpp.o
[ 31%] Building CXX object CMakeFiles/openloco.dir/src/openloco/interop/hook.cpp.o
/home/karl/Downloads/OpenLoco-18.02/src/openloco/interop/hook.cpp: In lambda function:
/home/karl/Downloads/OpenLoco-18.02/src/openloco/interop/hook.cpp:193:57: error: expected ‘{’ before ‘->’ token
  193 |             [](registers& regs) FORCE_ALIGN_ARG_POINTER -> uint8_t {
      |                                                         ^~
/home/karl/Downloads/OpenLoco-18.02/src/openloco/interop/hook.cpp: In function ‘void openloco::interop::register_hook_stub(uintptr_t)’:
/home/karl/Downloads/OpenLoco-18.02/src/openloco/interop/hook.cpp:193:57: error: base operand of ‘->’ has non-pointer type ‘openloco::interop::register_hook_stub(uintptr_t)::<lambda(openloco::interop::registers&)>’
At global scope:
cc1plus: error: unrecognized command line option ‘-Wno-unused-private-field’ [-Werror]
cc1plus: all warnings being treated as errors
make[2]: *** [CMakeFiles/openloco.dir/build.make:227: CMakeFiles/openloco.dir/src/openloco/interop/hook.cpp.o] Fehler 1
make[1]: *** [CMakeFiles/Makefile2:105: CMakeFiles/openloco.dir/all] Fehler 2
make: *** [Makefile:84: all] Fehler 2

comrad
Bild des Benutzers comrad
Offline
Beigetreten: 13.05.2008
Beiträge: 5630

Da scheint ein Programmierfehler zu sein, verwendest du den master-branch? Dort wird meistens entwickelt und es können Fehler drin sein. Am besten lädst du dir ein Release runter und baust das.

meldrian
Bild des Benutzers meldrian
Offline
Beigetreten: 12.05.2009
Beiträge: 2007

Da mit neueren Versionen der Software weitere Libraries notwendig wurden, unter anderem (yaml-cpp) ist es aktuell (unter Ubuntu) nicht (oder nur so erschwert so das ich es nicht schaffe) möglich openloco zu kompilieren. Bedauerlicherweise werden weiterhin nur Windows- und MacOS-Versionen fertigkompiliert auf github angeboten. Ich scheine damit nicht der einzige zu sein (Link nach Github Issue 1257).

Edit: Es gelang mir doch noch erfolgreich zu kompilieren. Bei Zeiten aktualisiere ich die Anleitung im Artikel. Das Video werde ich wohl Offline nehmen müssen.
So viel vorab:
https://github.com/OpenLoco/OpenLoco/releases
https://github.com/OpenLoco/OpenLoco/issues/1257
https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.7.0
https://github.com/OpenLoco/OpenLoco#42-compiling-and-running
https://github.com/janisozaur/OpenLoco/

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install --no-install-recommends -y pkg-config:i386 g++-multilib cmake git ninja-build libsdl2-dev:i386 libsdl2-mixer-dev:i386 libpng-dev:i386 libyaml-cpp-dev libopenal-dev:i386
git clone https://github.com/OpenLoco/OpenLoco.git
cd OpenLoco
mkdir build
cd src/Thirdparty
git clone https://github.com/jbeder/yaml-cpp.git
cd ../../build
CXXFLAGS="-m32" cmake .. -G Ninja
ninja

  1. Prozess abwarten und/oder auf Fehlermeldungen reagieren*

mv openloco ..
./openloco

Mastodon