• 0 Posts
  • 6 Comments
Joined 3 years ago
cake
Cake day: March 21st, 2024

help-circle
  • I’ve been a part of the modding scene for these games for about a decade now.

    As easy as this is to get running, which is a great thing, I feel the effort to make this has been misplaced and that this is a fad which will die off in a month’s time.

    There are many better ways to go about this and, more importantly, there are much bigger issues to solve (such as lack of any meaningful new content for these games). It’s historically always been limited due to the lack of tooling that is functional and user-friendly enough to craft mods for this game.

    And that is changing for the better, for sure. But all of these slopped up mods and ports are just made for clout to ask for donos. It doesn’t feel right because there’s almost always no passion (or even any effort) put into this.


  • There’s more questions to ask beyond “who is playing the recomps/decomps”

    Regardless of AI, these questions pop up:

    • What is the use case?
    • Is it worth spending my time and energy as a developer (or from developer’s perspective) doing this?
    • Who is this for? (Same question as before, yes)

    Even before the AI boom, I asked these questions. Some games are indeed an enigma (Sonic Unleashed is a perfect example), but a lot of others are just… there I guess.

    Don’t get me wrong, it’s nice to get a better version on PC with keyboard and mouse support and better graphics and undefined aspect ratios, that’s all fine. But you have to understand one thing and one really big thing - not all games need or even deserve this treatment. A lot of people are just fine with what an emulator offers already.

    If you think that “oh all of those features are impossible or really hard to do without a recomp” - think again. I can tell you from first hand experience as a reverse engineer and developer that you can do a lot of those things without doing a decomp (and especially a recomp). All on the original hardware’s limitations sometimes, too. It’s provably quicker and easier to do (some of) those hacks on top of existing games rather than recompile it.

    As for the “broken games in emulators but are fine in recomps” - those fixes and hacks should’ve been presented to the emulator project first because it can not only fix this one game, but sometimes fix others too.

    Ports onto platforms like PSP or iOS sure are nice to have, but be honest - it’s not the best way to play these games. It’s not even a good way to play it portably a lot of the times either. A lot of the times, those same people have other means to play them too. I don’t think most gamers even care about an hour or two of extra battery life playing the game because it’s more power efficient than running the emulator.

    The more and more you think about this, the more irrational it becomes to spend time and energy on doing these things.

    And to a certain degree - it always was. It was always a “just because you can” type of deal. Some were doing it for clout (even before AI, yes, there are talented people who also are obnoxious doing it), some for the love of the game, etc.

    Now - you just have a lot of people doing it for clout and opening up dono pages in ko-fi and patreon. To them, this isn’t a hobby. It’s a business venture. It’s a job. And that is where the spirit of doing this kind of thing is undeniably and truly lost.


  • That I can confirm firsthand. Recompiled code is just prebaked CPU instructions in another language that can be compiled. That’s all there is to it.

    So for modding, it’s only slightly easier technically as you have the option to inject code easier than on the emulated platform and providing facilities for the host OS to load them (dynamic libraries, which is a big benefit which most of the slop coders don’t fully understand how or why it is).

    For proper modding research, a decompilation (of the portions of the game you want to mod very extensively) is needed.

    For a simple aspect ratio and UI fix patch (and other simple improvements) - that is achievable on the original code itself via cheats/code injection (anything that has an FPU should work, PS1 and older are harder generally). You generally do not need a whole recompilation/decompilation for this kind of a thing.

    Sometimes even the original hardware without any performance boost can handle it, but most of the times this is where emulator’s overclocking and memory extension features come into play to help.

    Honestly, in my opinion, machine code hacking is not that hard. It takes way less time and energy to do it than this to achieve the same “improvements” with way lower barriers to entry.



  • I do this quite a lot myself.

    Beside the games that do officially support it via modding APIs, or older games that are just naturally extensible like Unreal Engine games that ship with an editor; it is usually done by the way of code injection.

    Think of code injection like a manually placed interrupt - you modify the flow of execution at some point to execute your own code.

    For this, you need something known as an entrypoint - place where mod code begins executing. Usually, at the entrypoint, the mod code bootstraps itself further.

    To obtain an entrypoint, you have 2 options:

    1. On supported OSs, you can abuse dynamic library loading and make a library wrapper which masquerades as the original library. When its execution begins (on Windows this is usually very early in the importing stage, on Unix/Linux you need to swap functions), you can bootstrap your mod(s) further.
    2. On other systems (game consoles, embedded, etc), you have to modify the game executable directly. Either via the way of memory injection of another tool or direct binary modifications. Depending on the platform, if it supports loading of libraries, you would either load your mod as a library or, if not, inject the mod elsewhere into memory (slack/unused space).

    How do you figure all of this mumbo-jumbo out? Well, you use tools designed to disassemble the game binary into machine language. Most popular examples are IDA, Ghidra and Binary Ninja.

    You usually won’t have any information on what’s what, but if you know a bit about code design of games, you come to realize that a lot of them follow similar principles/patterns (depending on the era and platform), so you can probably figure it out once you’ve seen a few games. Especially if the game is using the same game engines as others, then you can cross reference stuff.

    However, if you’re lucky, you can obtain something known as debugging symbols which have all of the information about the generated binary. Ideally, it’d be for your executable that you’re working with directly, but if it’s not, you can usually just cross reference it by either binary pattern matching or simple deduction (same execution flows, same data, etc). This will give you a nice map of where’s what in your disassembler tool.

    Thanks to standardization of binaries, ABIs (Application Binary Interfaces) usually allows you to match the types as they’re defined originally and have them work directly in your bespoke code. This means, for example, that if a function takes 3 arguments, those 3 arguments will be passed in the same way (depending on its calling convention), so you can expect to receive them in your own code the same way. (This is what we call code reflection - you can reflect the game’s types in your own code. If you’re using the same compiler as the original, even better!)

    And, ideally, you would be working with code directly and not with machine language, but some lower level stuff will need it inevitably.

    Usually, in your mod source code, you would work with a library that is specifically designed for code injection. This is effectively a JIT compiler which emits machine code instructions which are needed to redirect the flow of execution to your own modded functions. (Usually is capable of memory editing and making branch instructions)

    There are 2 ways to perform a code modification:

    1. Inlined code - this means you write your own code in the middle of another game function. Usually, this is done via lower level assembly and a branch instruction to put it in. Requires decent knowledge of the target CPU to use it (to not corrupt any stack or registers)
    2. High-level function hooks - this usually means that you interrupt a function call/branch with your own equivalent. Your equivalent function will have to do the job of the original usually, but depending on the case, you may replace it outright or simply pass the call onto the original function. Thanks to ABIs, this is possible.

    With all of this being said, you need to have the knowledge being able to read machine language of CPUs. This isn’t too difficult once you realize RISC CPUs are mostly very similar at a glance which helps out a lot.

    But, in order to be able to read it, you have to first obtain it and, as we all know, DRMs, executable packers and anti-cheats/tampers protect this, so you may need to get your hands dirty a bit to bypass that (e.g. memory dumps). A lot of the same tricks that security researchers use in their rulebook apply to modding as well.

    I hope I’ve explained enough. I’m aware I used a bunch of terms that may be foreign, so I hope you will get the gist at the very least.