Hi! Time of a very large post!
This is a topic I wanted to talk about
years ago. And you might ask: Then why did you didn’t? Easy answer: I didn’t
have a place to write crap like this. (Well, technically speaking I always had
this blog, but it was forgotten. Read the past post for that history). And
since there are people which asked about this topic from time to time in
assorted channels, then I decided is time to write about it.
Okay, let’s start.
One of the atypical personal projects I
have done in the past years was helping Netherware Entertainment with
publishing 2 games of theirs: Desolate City: The Blooding Dawn Enhanced
Edition and Super Crystal Hunter in that popular PC platform that we
all know by its name Steam. Easy task, no?
Wait wait… Netherware? Desolate City? Super Crystal whathever? Explain yourself!
Okay okay, calm down buddy! I will explain
it!
Let’s start
explaining what Netherware Entertainment is. Long history short: An
indie videogame developer company ran by a group of talented people which uses
RPG Maker 2003 as a main weapon of choice! Lead by CesarRP, they released a nice bunch of games, which you
can take a look at their website.
They also make a lot of great videos/podcasts (in spanish) about RPG Maker game
developing and publishing. Go take a look a their social media!
The roots of this company born
many years ago, when this was just all fun and games (?) when a bunch of people
made a GD (A short of Grupo Desarrollo … or Development group in the RPG
Maker scene slang), called PARPG. I participated there sometimes trying to
giving my knowledge regarding different things such as chicken-based instrument
melodies, tools&patches advisory or even avant-garde trailers.
The years passed, people go, people go away
(so I do), etc. But CesarRP, the head on that group took that PARPG and
converted in something way far more serious that’s what we call now Netwherware
Entertainment. And that’s the history of!
And yeah, Desolate City: The Blooding
Dawn Enhanced Edition and Super Crystal Hunter were two awesome
games from this game house.
RPG Maker 2000/2003 and Steamworks: Not a nice mixture.
Something big were being cooked at
Netherware Entertainment at that time: Desolate City was about to be released
in Steam with a brand new Enhanced Edition with plenty of new stuff compared
with the early version of the called The Atrezzo years ago at still
PARPG eras. Wow! And even with a publisher in the back.
Of course, dealing with publishers and platforms such like Steam means it requires plenty of extra stuff. Let’s say: Integration with the platform menus (Steam Overlay), Achievements, Embedded Multilanguage support, Multiplatform, etc etc etc etc… Of course, Steam does not require to implement all of those but it definitively a nice-to-have! And seems like at those years there are already people and companies with experience dealing with all of that with NodeJS based RPG Makers (MV/MZ) and Ruby based ones (XP/VX(a)). But what about 2000/2003?
Seems there were attempts to publish RPG Maker
2003 games at the time (2018 approximately ), but by putting all those extra
features away; in other words: Windows only, no achievements, no overlay, just
one language, etc. (Years after there were a increased number of games using it
but … after). Other popular option was just switching to use more modern
versions of RPG Maker. It was a decision for example, made at, Yume Nikki or
One Shot, which was not very welcomed by the fans of their original versions.
So… what was left for Desolate City?
Of course, call EN.I back!
First experiments with RPG_RT
My first attempt to solving an issue like
this (at that time we are dealing with multilanguage support) is trying to
solve that thing the way I was used to know at golden eras of RPG Maker:
Patches, patches and more patches. I was thinking about callbacks with Ineluki
KeyPatch (Patch that replaces Harmony Audio Engine with a upper layer that
allows you to invoke executables when playing specific audios) to make
callbacks to SteamAPI and do things, or even that DynRPG (which you can
code Plugins in C/C++) for the same…
… Or what about doing my own patches for
that?
(Well… that idea did not evolved in
something more, but at least, the remains of it were recycled and made this
tool https://github.com/elsemieni/RPGMaker2k3VarInspector
. )
So, as apart from that, CesarRP was also dealing with Unicode issues (remember,
RPG_RT does not support that; you need an special crafted RPG_RT hack for each
locale you want to), remembered that EasyRPG was more and more mature in that
era (reaching it’s 5.4 release at that time). Still having a bunch of nasty
bugs at that time, but It was able to run games in a playable state at a really nice percentage (with
some aesthetic sacrifices sometimes).
So… we had a discussion with CesarRP: How about selling games with EasyRPG Player? GPLv3 license does not forbid from doing that (as long as we publish any modified source code with it if we do so), it have an awesome (but at the time a bit mysterious in terms of how-to-properly-use-it) Unicode support and lots of mini extra features we can use! Yeah, as I said, it had some nasty bugs, but we agreed we can make workarounds inside the game for making the game working properly.
EasyRPG Player, GPLv3 and Steamshim
Ok, so for making a prototype to make it
work I just need to plug Steamworks SDK into EasyRPG Player source code,
compiling it an… wait wait WAAAAIT! There is an issue, and not a technical one.
You can’t do that! The reason is simple: EasyRPG is GPLv3 which requires
the code should be shared with the binary, and forbids linking against
proprietary libraries (with some exceptions if those libraries are crucial for
operating system… but that’s not the ideal for a free-as-in-freedom fanatic).
And of course, SteamSDK is a fully proprietary code with no source code
available plus some clauses of privacy (even if it’s super easily
downloadable with tons of contents available around the internet). In short
words: It’s illegal linking EasyRPG Player with Steamworks SDK… Is a
very similar reason why EasyRPG Player can’t be used in gaming consoles or some
other privative environments. A solution for that is switching Player’s license
to something more permissive such as MIT; and there’s a 32km long discussion
regarding that for years! https://github.com/EasyRPG/Player/issues/167
So... The end? Nah.
Luckly, I was not the only one in this same
sort of issue. Someone called icculus, which is the guy behind SDL created a clever but
shady solution for it called Steamshim which basically is a bridge between your GPL executable and another isolated
executable containing the privative code that links with the Steamworks
API. That bridge is not connected by “code” but with system pipes, making this
ting barely legal. Ugly/shady? Yes. It works? Yes. It is legal? Barely, but yes.
So, the possibility is now real. So… let’s
work! We have a game to “port”.
Putting all together.
For triggering all of Steam stuff from RPG
Maker, I choose an old-school approach. In old days, when you are using
patches, you usually listened all sorts of commands in different combinations.
For example, in BetterAEP (a patch by CherryDT that allows skip the
title screen in old RPG_RTs with extra features for exiting and triggering the
Load Menu), for calling the Load Menu, you needed to put certain values in
certain variables and then call “End Event Processing”.
Here I choose a similar approach: Each achievement will have an internal name something such as ARCHIVEMENT_NUMBER_X where X is an arbitrary number from 0 to … n. (whatever the number of achievements the game had, can’t recall now). So, I just made something like this:
Put a variable with value 1 (for example),
another variable with certain value (to replace End Event Processing
default behavior) and called End Event Processing. Then modified event
interpreter source code to evaluate that and then trigger the achievement ARCHIVEMENT_NUMBER_1
(as the variable is set at 1). In that way CesarRP was able to trigger
achievements in any place he wanted to, using convenient common events for
that.
(Achievements working on Desolate City. It was emotional... regardless the fact it is a crappy debug screen in a debug conditions. But it was emotional anways...)
For achievements based on metrics, the
logic was very, very similar. Just have special commands to set the desired
metric and the desired value (for example one variable for set bullets, and
other variable to set the number of bullets shoot) and End Event Processing for
sending that to Steam. Then steam itself will trigger an achievement if
applicable.
(Some achievements were… a bit complex
logic to be triggered as you can see)
Another interesting thing that Steamworks
have about is regarding how it handle game’s data internally. Without digging
so deep, it uses a “Repository” system, which separates the whole game
data in different “modules”, each one having different attributes (OS,
language, DLC, etc). So, by providing different repositories you can have
different game setups (For example: Base game data + Windows Binaries + DLC).
With that in mind we can play with that for adding interesting features using that Repository feature:
- Auto language detection: For example, if Spanish was set, it will download a Repository which contains a Map0004.lmt (for example) which have an automatic a event that set a Language variable to 2 (for example) then teleporting to the intro. Of course you can, after that, set any variable you want.
- DLC support: For example, If DLC was purchased, it will download a Repository which contains extra maps, extra data files and a Map0005.lmt (for example) have an automatic event that set a DLC variable to 2 (for example) then teleporting to the intro. Then it will check DLC variable for enabling or disabling certain features.
Cloud saving? Just tell Steam that it
should handle about .lsd files and that’s it. Now we have cross cloud
storage!
Overlay was not much science. With just
integrating Steamworks with Player you already have it. However many Steam
buttons conflicts with mapped button of EasyRPG player, sooo… We did not have
more option rather than re-map EasyRPG buttons to something else. It was easy,
as we are already modifying the source code.
Do I miss something here? Yes! Cross-OS
compatibility! But let me make a pause first as it is 2AM, so I will
continue tomorrow to write that chapter. (Yes, this post was made in 2 days).
Desolate city, available in your toaster and in your staubsauger
One of the nice features of EasyRPG Player
of course, is cross-compatibility, and Steam welcomes that (at least for Windows,
GNU-Linux (ahem* SteamOS/SteamDeck nowadays) and MacOS ). And since we are
using it, then why not we can offer that capability (even if probably, most
players will come from Windows OS... or maybe SteamDeck probably).
As I told you some paragraphs before, Steam,
by it’s repository modular system, you can switch OS binaries by simply specifying
the OS. So we can make a customized game setup using the correct binaries for
each platform. But there is just a tiny problem: Remember our player is
customized, right? We can’t just take the binaries from https://easyrpg.org
and done. We need to build our player for each platform.
Thanks for the EasyRPG team to make
something super buildable from scratch (they even make a dedicated repo for
building all the dependencies in bulk at https://github.com/EasyRPG/buildscripts
), this was not very complicated task (unless you are new in that world, such
as me at 2018). Of course this building process for each OS had it’s issues
there and there. Let’s manage some of those:
Windows
I will skip this part. I already told you about mistakenly trying to build Player using MinGW instead MSVC. The happy part of it is that we were able to provide a nice 32bit custom player. (Yes, 32 bit for that guy that still had issues running a 64 bit OS… which should be 0.00001% of our population playing the game).MacOS
For building a player for MacOS is easy:
You need a Mac. And have money for one. I don’t have either of those XD. Luckily
the Hackintosh community and efforts to run tweaked versions of OS running on
PCs is quite big out there. At least enough to find hacks for VMWare to run
MacOS EFI firmware that allows me to install a stripped-down version of MacOS
High Sierra at that time, with enough stuff to run a terminal, and a Xcode.
But wait there… You also need to install
all build tools (which comes with git, make, clang, etc, etc)… Or go by the
easy way and Install Xcode. I remembered spent 3 days trying to find the
correct version to download (cuz the official way via Apple Store did not
worked). Once I was able to find it, I did not had much hassle to build a
functional version:
(It even have a custom About screen,
yay!)
For those people who has built software for
MacOS they know I missed some steps there (that Steam at that era did not cared
about) such as Notarization and signing. At that time these were not required,
but surely that’s not the scenario today. Most probably you will have to tackle
lots of hefty warnings and alerts of unsecure software to make this run
nowadays. Not sure if signing for publishing in Steam is required, but at least
for notarizing you will need a Apple Developer ID. And yeah, that cost money!
Duck you Apple!
(Thanks to Ali Rastegar for lending me a
hand here; he already integrated some MKXP games with Steamshim in MacOS ).
GNU/Linux
That should be easy-as-a-pie building
something here, right? Of course it is! I just grabbed an Ubuntu ISO, installed
it somewhere, installed buildtools, built everything (remember to build
statically) and everything seems nice at the end of the day!
But the nightmare started when I wanted to
run the game in another PC with another Linux OS. The thing was badly dead. ldd
tool told me that my shiny executable was strongly tied to a very specific
version of libc I used from my version of Ubuntu, so it can be run only in
a small number of places. And you know, there is no such thing called “standard”
in GNU/Linux where I can compile this thing to run it in a bigger stake of OSes
(put Debian, RedHat, SuSe, arch and others in a cage and grab a popcorn to see
how it ends… if it ends XD).
Luckily,
the solution from that comes from Steam Itself: They offered a thing called Steam Runtime that offers a pretty-old Ubuntu 12 based runtime to build stuff for Steam and
attempt to make it compatible with a broader steak of OSes. Today that environment
is Docker based, but before that it was some sort of strange chroot stuff.
Struggled a bit to make things run to build a functional player, but after
dealing for a while I was able to accomplish my objective: Making a functional
custom EasyRPG Player able to run in whatever platform able to run Steam. Yay!
Final touches before publishing.
I have the things ready to be published! I must
ensure some random stuff:
I need to accomplish with GNU GPLv3: Okay, put license files on the game data files, plus publishing the
custom player source code at https://github.com/elsemieni/easyrpg-player-netherware
(warning: very outdated).
Optimized audio formats: If EasyRPG offered OPUS, then let’s use OPUS! (Well, after dealing
with an issue that made player crash when playing opus files on non AVX enabled
processors).
Loooooong pre-launch QA: Outside of the scope of this post, but it was looong and tedious!
Add proper controller support: At that
time, EasyRPG Player 5.4 had not a pretty well controller mapping (even worst
if applied to Desolate City). So I brought an Xbox One controller from a buddy
in my faculty for around $20 (from my own wallet) to remapping and testing!
Worth it!
(CesarRP, you owe me $20… nah, just
kidding).
Easter eggs: shhhhh. Did you guys played Moulin la Folie? It’s hidden somewhere inside Desolate City :D
Aftermath... wait, there are math in the after?
I guess CesarRP have better words than me for that chapter; but at least I can say the game was successfully launched in the markets, and you can play it too here.
Here the same basis than all before was
applied (with the sole difference that Player 0.6 was used and the
customizations were made a bit cleaner at https://github.com/elsemieni/easyrpg-player-ne-sch
). Just mention some extra stuff customization made there:
FluidSynth: Needed
as MIDI sounds different in non-Windows OS. At that time, FluidSynth backend
was not ready for Player, so made some hacks from a experimental branch (from
Ghabry I guess) and dealt with the issues and workarounds. So we were able at
that time to use a gm.dls clone soundfont to make it sound similar in
all Oses. (An interesting thing is that the trailer music was the main theme
with a custom soundfont working on Player’s Fluidsynth).
Rumble:
Absolutely not needed, but wanted to play with it because why not xDDD. Created
dummy special sounds that when you play it on Player it will rumble the
controller, depending of the Vol/Pan/Speed parameters. So, yeah. SuperCrystalHunter
has rumble support (in a game which is completely useless but … meh, don’t ruin
the fun).
Conclusions, issues and the future…
Of course this approach to implementing
Steamworks SDK (or any other backend) to EasyRPG Player games have a particular
issue: Each time you want to have a up-to-date player, you should update the
codebase of your custom player (with the risk of breaking it) and recompile for
all your platforms. Had to do that more than once and it’s tedious.
Probably in a very professional scenario
you want to stick to a particular version of Player instead of always having
the super latest version (that’s a very common practice in popular engine such
as Unity or Unreal Engine). And that is what I decided for Desolate City (Player
0.5.4) and Super Crystal Hunter (Player 0.6). CesarRP did not like
much the idea at that time as far as I remembered, and requested me sometimes
to update the codebase.
One way to avoid this could be implementing
something in Player such as the possibility to call external DLL/SO/dylib stuff
(such as the Win32API module in RPG Maker XP/VX(a)). However I believe this
will not be possible due 2 reasons: Very OS dependent, and very risky
in terms of security. Then, I guess the alternative to customizing the base
code is still the right option to do so. Also I think is the same reason of why
ExecProgram feature of KeyPatch is not implemented. (Let’s not
put DynRPG here, because this is other sort of issue… as that is special
crafted compiled code made to hack an specific version of RPG_RT itself).
And of course,
I already mentioned the GPLv3 vs MIT issue at the middle of this post (reminder
of this discussion here) that could allow implement not just
Steamworks API more cleaner, but also more heavy SDK such as game consoles! But
yeah, at the cost of sacrificing Freedom (some people strongly believe in that
part as core pillars of EasyRPG: A free-as-in-freedom RPG Maker). Anyways, the
debate is still hot sometimes there.
I want to add Steamworks into my EasyRPG game. What should I do?
- Get Steamshim, play with the included examples (uses Postal, it's free on Steam) to get it working and make yourself comfortable with it.
- Add Steamshim to EasyRPG Player source code, add a hook somewhere to call archivements from your game (there is not a guideline for putting specifically in any place... I put it in at "End Event Processing" event command, but you are free to put whathever you want).
- Build that custom player in your platform of your choice. I put some memos upper in this post about how I went at Windows/MacOS/Linux.
- Do not forget you are required to publish also your modified Player source code, as it's a requirement of GPLv3 license.
- Order a pizza. This is mandatory (?)
Oh, and this is the end of the post! Had to
make it in two whole days (or nights to be more specific). Now I can rest at
least 2% more peacefully, as at least I make this testament about how all of
this was made.
As always you can always ask me about this
stuff in a channel I can be available of course!
Now, I will go to sleep a bit,
byeee!