The part of a game which is "code" is not "large": it is "small", except if a game has really little data, namely it is a small game, and if it is a small game...

Then, on elf/linux systems, you have "alternatives" and serious abi instability due mostly, but not only, to gnu symbol versioning (it is pathological in glibc, or it could be a scam). Game binaries cannot expect _their_ alternatives to be there, that's why they have to rely on really only video game core, very video game core libs and the sysv abi(elf). The only way to properly "deal" with abi (modules, symbols, with their versions) stuff on elf/linux, is to dynamically load as much as possible from the system: libdl with only the 3 symbols dlopen/dlsym/dlclose.

Ofc, a game should statically link as much as it can (for instance libm), but it requires to dynamically load the video game core libs. Those video game core libs may be linked with musl (hope they have their libdl now), glibc, bionic (if it has a elf loader), etc. If you want full static binaries, you will need a full elf loader into your static binaries. You cannot create such static binaries with the glibc and it is not supported by the set of glibc libs as far as I know (I wonder if it is not done conveniently on purpose to "break" the usage of alternative elf/c runtimes), and if I recall properly you can with musl.

The video game core libs on a elf/linux system are:

- wayland window system code is static into game binaries, but for key symbols resolution, the game must dynamically load the libxkbcommon library for the xkb client state machine with the user configuration (you may not have the "right" xkb data files for a user). Basically, you feed wayland keycodes to the xkb state machine and based on user specific configuration files, you get out the right key symbol (some games have a mode to bypass key symbol resolution and work directly with keycodes).

- x11 system code, the usage is now to dynamically load the client xcb libs and libxkbcommon-x11 (do not use libX11).

- android has wayland, but I don't think it's xkb (no libxkbcommon(-x11) lib).

- GPU, vulkan by-design does require dynamic loading, and GL fallback will require to dynamically load of the targetted GL libs (some games could be 100% cpu rendering in window systems surfaces using a presentation interface).

- sound: you only need to dynamically load the alsa-lib (libasound) as software mixers (dmix/pulseaudio/pipewire/jack/etc) are hidden behind the alsa-lib. (I don't know for android, but alsa has a mobile phone specific configuration interface, don't think it is stable yet though).

- for joypad stuff, it is linux specific with the interface of /dev/input/eventN files.

In theory, games should be sets of pure and simple ELF64 binaries (with the least amount of relocation types), libdl-ing everything from the system. It means no c runtime main() function, but the sysv ABI entry point, which is a basically a main() anyway. To deal with cross-platform (elf/linux|doz|fruitOS|etc), platform specific fallbacks (on elf/linux platform: wayland->x11, vulkan->gl->cpu, etc), proper compile-time and runtime tables of functions usually will do the trick.

Reality check: libstdc++, some libgcc services, and many third-party libs are not libdl-ized. The mitigation is to use "-static-libgcc" and "-static-libstdc++" compiler/linker options and link with an extremely, EXTREMELY old glibc (what godot does). It seems libstdc++ will link with glibc internal symbols if linking happens with a glibc on the build system.

NOTES: for i18n games with "full" text input, an input method should be provided by the game itself as you cannot expect a specific input method to be installed on the user system, if any. A GUI toolkit is "above" the window system and related to user alternatives (some may prefere QT, other GTK, or enlightenment or neither of them, then for the same reason than before, a game must package its GUI toolkits.

Ofc, if you code in plain and simple C, a lot of those issues can be worked around much more easily.