@Doods
@infosec.pubAnother crazy idea I share with this website.
I was developing a game and an engine in Rust, so I was reading many articles, most of which criticize the 'borrow checker'.
I know that Rust is a big agenda language, and the extreme 'borrow checker' shows that, but if it weren't for the checker, Rust would be a straight-up better C++ for Game development, so I thought: "Why not just use unsafe
?", but the truth is: unsafe
is not ergonomic, and so is Refcell<T>
so after thinking for a bit, I came up with this pattern:
let mut enemies = if cfg!(debug_assertions) {
// We use `expect()` in debug mode as a layer of safety in order
// to detect any possibility of undefined bahavior.
enemies.expect("*message*");
} else {
// SAFETY: The `if` statement (if self.body.overlaps...) must
// run only once, and it is the only thing that can make
// `self.enemies == None`.
unsafe { enemies.unwrap_unchecked() }
};
You can also use the same pattern to create a RefCell<T>
clone that only does its checks in 'debug' mode, but I didn't test that; it's too much of an investment until I get feedback for the idea.
This has several benefits:
1 - No performance drawbacks, the compiler optimizes away the if
statement if opt-level
is 1 or more. (source: Compiler Explorer)
2 - It's as safe as expect()
for all practical use cases, since you'll run the game in debug mode 1000s of times, and you'll know it doesn't produce Undefined Behavior
If it doesn't crash.
You can also wrap it in a "safe" API for convenience:
// The 'U' stands for 'unsafe'.
pub trait UnwrapUExt {
type Target;
fn unwrap_u(self) -> Self::Target;
}
impl<T> UnwrapUExt for Option<T> {
type Target = T;
fn unwrap_u(self) -> Self::Target {
if cfg!(debug_assertions) {
self.unwrap()
} else {
unsafe { self.unwrap_unchecked() }
}
}
}
I imagine you can do many cool things with these probably-safe APIs, an example of which is macroquad's possibly unsound usage of get_context()
to acquire a static mut
variable.
Game development is a risky business, and while borrow-checking by default is nice, just like immutability-by-default, we shouldn't feel bad about disabling it, as forcing it upon ourselves is like forcing immutability, just like Haskell does, and while it has 100% side-effect safety, you don't use much software that's written in Haskell, do you?
Conclusion: we shouldn't fear unsafe
even when it's probably unsafe, and we must remember that we're programming a computer, a machine built upon chaotic mutable state, and that our languages are but an abstraction around assembly.
Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3.
I am in love with this awsome document; I love its guidelines, and coding conventions.
However, when Rust was introduced into the kernel, they butchered these beautiful guidelines, I know it's hard to look at such heretic actions, but you have to see this:
The default settings of
rustfmt
are used. This means the idiomatic Rust style is followed. For instance, 4 spaces are used for indentation rather than tabs.
How can this even relate to the ideology of the first document? I am deeply saddened by these new rules.
I know this is "The Rust experiment", but this must be fixed before it's too late! This has to reach someone.
A counter-argument might be:
The code should be formatted using
rustfmt
. In this way, a person contributing from time to time to the kernel does not need to learn and remember one more style guide. More importantly, reviewers and maintainers do not need to spend time pointing out style issues anymore, and thus less patch roundtrips may be needed to land a change.
And to that I say that rustfmt
is configurable per project, and if it isn't, then it has to be. Doesn't something like .editorconfig
exist?
Edit: I think I read enough comments to come up with a conclusion.
At first, forcing another language's code style upon another sounds backwards, but both styles are actually more similar than I originally though, the kernel's C
style is just rustfmt
’s default with:
The part about switch
statements doesn't apply as Rust replaced them with match
.*
The part about function brackets on new lines doesn't apply because Rust does have nested functions.
The bad part about bracket-less if
statements doesn't apply as Rust doesn't support such anti-features.
The part about editor cruft is probably solved in this day & age.
The rest are either forced by the borrow checker, made obsolete by the great type system, or are just C
exclusive issues that are unique to C
.
I left out some parts of the standard that I do not understand.
This all turned up to be an indentation and line-size argument. Embarrassing!
*: I experimented with not-indenting the arms of the root match
expression, it's surprisingly very good for simple match
expressions, and feels very much like a switch
, though I am not confident in recommending to people. Example:
match x {
5 => foo(),
3 => bar(),
1 => match baz(x) {
Ok(_) => foo2(),
Err(e) => match maybe(e) {
Ok(_) => bar2(),
_ => panic!(),
}
}
_ => panic!(),
}
This texture pack, called Minecraftclone, is the best MC texture pack for MCL out there, because the only competition is NS-textures and this one which doesn't have a download link.
All the textures are taken from Minecraft 1.20 except for:
*: They are taken from mods with varying levels of editing done by me.
This pack supports the following mods:
*: Partial support
This pack is a work-in-progress, and lacks:
https://mega.nz/file/mcI1BIoI#jSB-T5RsZXzNpue4OEr_LQwZcEAbh-e_MOqbsFVT7SU
Keywords for search engines to increase visibilty:
I am also planning promote the pack on r/Minetest if this post fails to attract search engine results.
I have a huge library of game EXEs on my computer, but they run at a 4:3 aspect ratio as they're old, Proton/Proton-GE/WINE-GE keep the aspect ratio and place black bars left and right, which is desireble, unlike wine who stocks them to the left side of the screen.
This might seem stupid, but hear me out.
Fallout 3 on Epic is 39 GiB, the reason for that huge size is you're forced to download all the language packs, same story for Tomb Raider and FFXIII.
As someone with a monthly data limit of 140 Gib, and who has to share it with a family, these - unnecessary - download sizes are unacceptable and make me want - and plan - to pirate the game -which even though I didn't play for I still legally own*- and only having to download 7 GiB.
I would've complained about disk space but you can just remove the extra languages conveniently located in saperate folders**.
This also applies to single player games with privacy-invasive DRM and usability-hurting DRM***, and for people who hate the idea of DRM in general.
*Own as a service and a using license.
**Unless you are tight on disk space and cannot fully download the game before removing the files.
**DOOM 2016 didn't work on Linux duo to the DRM being incompatible with proton.
I made a git hub issue, but I want to ask here as well in hope of finding success
After running heroic in the terminal, the following thing catchs my eye: The terminal hangs at either
[Backend]: Running Wine command: wineboot --init
or
[Legendary]: Using cached install info
or
ERROR:gl_surface_presentation_helper.cc(260)] GetVSyncParametersIfAvailable() failed for 1 -and 2 & 3- times!
sometimes I get a notification to install mono when switching WINE versions (WINE-GE).
Somewhere along the loading process a "wineboot.exe" blank windows appears depending on the wine version (heppens with proton) and stays for a while. I am using Wine-GE
Things I tried:
-Deleting the "Games" folder in my home folder - Only heroic used it anyway.
-Adding the game to steam through Heroic's "Add to steam" button.
-Reinstalling heroic and all of its dependencies.
-Manually adding the game's EXE to steam and forcing a Proton version.
-Launching the game by double clicking it in my file manager Nemo.
Surprisingly, only the last two things succeeded in running the game properly.
Terminal output after a successful run:
(Excuse my inability to use a code block on this)
`[doods@doods-pc-7500 ~]$ flatpak run com.heroicgameslauncher.hgl [13:0803/011856.095179:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory Gtk-Message: 01:18:56.754: Failed to load module "xapp-gtk3-module" Gtk-Message: 01:18:56.791: Failed to load module "canberra-gtk-module" Gtk-Message: 01:18:56.791: Failed to load module "pk-gtk-module" Gtk-Message: 01:18:56.792: Failed to load module "canberra-gtk-module" Gtk-Message: 01:18:56.792: Failed to load module "pk-gtk-module" [13:0803/011856.811049:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory [13:0803/011856.811105:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory [13:0803/011856.819964:ERROR:socket_posix.cc(147)] bind() failed: Address already in use (98) [13:0803/011856.820012:ERROR:devtools_http_handler.cc(312)] Cannot start http server for devtools. which: no wine in (/app/bin:/app/bin:/app/utils/bin:/usr/bin:/usr/lib/extensions/vulkan/MangoHud/bin:/usr/lib/extensions/vulkan/OBSVkCapture/bin:/app/bin/heroic/resources/app.asar.unpacked/build/bin/linux) (01:18:56) INFO: [Legendary]: Running command: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary --version (01:18:56) INFO: [Legendary]: Legendary location: /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary (01:18:56) INFO: [Gog]: GOGDL location: /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/gogdl (01:18:56) INFO: [Connection]: Connectivity: check-online (01:18:56) INFO: [Connection]: Pinging external endpoints (01:18:56) INFO: [Backend]: DRM module staus { oimompecagnajdejgnnjijobebaeigek: { name: 'Widevine Content Decryption Module', status: 'new', version: '4.10.2557.0' } } APPIMAGE env is not defined, current application is not an AppImage LaunchProcess: failed to execvp: xdg-settings (01:18:57) WARNING: [Backend]: Failed to register protocol with OS. [13:0803/011857.103342:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed [13:0803/011857.103557:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed [13:0803/011857.103689:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed (01:18:57) INFO: [Gog]: Running command: /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/gog_store/auth.json --version (01:18:57) INFO: [Connection]: Connectivity: online (01:18:57) ERROR: [Gog]: Unable to syncQueued playtime, userData not present (01:18:57) INFO: [Nile]: Running command: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/nile_config /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/nile --version (01:18:57) INFO: [Backend]: Loading Screen Ready (01:18:57) INFO: [Backend]: AreWeAntiCheatYet data downloaded (01:18:57) INFO: [Frontend]: Refreshing undefined Library (01:18:57) INFO: [Legendary]: Refreshing library... (01:18:57) INFO: [Legendary]: Refreshing Epic Games... (01:18:57) WARNING: [Backend]: refresh not implemented on Sideload Library Manager (01:18:57) INFO: [Legendary]: Game list updated, got 26 games & DLCs (01:18:57) INFO: [Backend]: Frontend Ready (01:18:57) WARNING: [Backend]: listUpdateableGames not implemented on Sideload Library Manager (01:18:57) INFO: [Gog]: Found 0 game(s) to update (01:18:57) INFO: [Backend]: Checking for current version changelog hostname: invalid option -- 'f' Try 'hostname --help' for more information. (01:18:58) INFO: [Legendary]: Checking for game updates: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary list --third-party (01:18:58) INFO: [Legendary]: Running command: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary list --third-party (01:18:58) INFO: [Backend]:
Heroic Version: 2.9.1 Boa Hancock Legendary Version: 0.20.32 Dark Energy (hotfix #6) GOGdl Version: 0.7.3 Nile Version: 1.0.0 Jonathan Joestar
Electron Version: 24.4.1 Chrome Version: 112.0.5615.204 NodeJS Version: 18.14.0
OS: Freedesktop SDK KERNEL: 6.4.6-200.fc38.x86_64 ARCH: x64 CPU: Intel Core™ i5-7500 @3.4 GOVERNOR: powersave RAM: Total: 7.62 GiB Available: 4.68 GiB GRAPHICS: GPU0: HD Graphics 630 VRAM: 256MB PROTOCOL: x11
(01:18:58) INFO: [Legendary]: Checking if EOS Overlay is enabled: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary eos-overlay info --prefix "/home/doods/Games/Heroic/Prefixes/default/Tomb Raider GAME OF THE YEAR EDITION" (01:18:58) INFO: [ExtraGameInfo]: Using cached ExtraGameInfo data for Tomb Raider GAME OF THE YEAR EDITION (01:18:58) DEBUG: [Legendary]: Using cached install info (01:18:58) INFO: [ExtraGameInfo]: Using cached ExtraGameInfo data for Tomb Raider GAME OF THE YEAR EDITION (01:18:58) DEBUG: [Legendary]: Using cached install info (01:18:58) DEBUG: [Legendary]: Using cached install info (01:18:59) INFO: [Legendary]: Abort command "XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary eos-overlay info --prefix "/home/doods/Games/Heroic/Prefixes/default/Tomb Raider GAME OF THE YEAR EDITION"" Error occurred in handler for 'isEosOverlayEnabled': AbortError: The operation was aborted at abortChildProcess (node:child_process:746:27) at EventTarget.onAbortListener (node:child_process:816:7) at [nodejs.internal.kHybridDispatch] (node:internal/event_target:735:20) at EventTarget.dispatchEvent (node:internal/event_target:677:26) at abortSignal (node:internal/abort_controller:308:10) at AbortController.abort (node:internal/abort_controller:338:5) at callAbortController (/app/bin/heroic/resources/app.asar/build/electron/main.f23c4159.js:2:404) at Object.onOutput (/app/bin/heroic/resources/app.asar/build/electron/main.f23c4159.js:190:23627) at Socket. (/app/bin/heroic/resources/app.asar/build/electron/main.f23c4159.js:100:743) at Socket.emit (node:events:513:28) { code: 'ABORT_ERR' } which: no wine in (/app/bin:/app/bin:/app/utils/bin:/usr/bin:/usr/lib/extensions/vulkan/MangoHud/bin:/usr/lib/extensions/vulkan/OBSVkCapture/bin:/app/bin/heroic/resources/app.asar.unpacked/build/bin/linux) (01:18:59) INFO: [Winetricks]: Downloading Winetricks (01:18:59) DEBUG: [Legendary]: Using cached install info which: no wine in (/app/bin:/app/bin:/app/utils/bin:/usr/bin:/usr/lib/extensions/vulkan/MangoHud/bin:/usr/lib/extensions/vulkan/OBSVkCapture/bin:/app/bin/heroic/resources/app.asar.unpacked/build/bin/linux) (01:19:00) INFO: [Legendary]: Found 0 games to update (01:19:00) DEBUG: [Legendary]: Using cached install info (01:19:00) DEBUG: [Legendary]: Using cached install info (01:19:01) INFO: [Backend]: d6264d56f5ba434e91d4b0a0b056c83a: Setting wineVersion to {"bin":"/home/doods/.local/share/Steam/compatibilitytools.d/GE-Proton8-7/proton","name":"Proton - GE-Proton8-7","type":"proton"} (01:19:02) DEBUG: [Legendary]: Using cached install info (01:19:02) INFO: [Backend]: Starting the Download Queue (01:19:02) INFO: [Backend]: Launching Tomb Raider GAME OF THE YEAR EDITION (d6264d56f5ba434e91d4b0a0b056c83a) (01:19:02) INFO: [Backend]: Preventing display from sleep (01:19:02) INFO: [Backend]: Checking if wine version exists: Proton - GE-Proton8-7 (01:19:02) INFO: [Backend]: Preventing machine to sleep (01:19:02) INFO: [Backend]: Stopping Power Saver Blocker (01:19:02) DEBUG: [Legendary]: Using cached install info (01:19:02) DEBUG: [Legendary]: Using cached install info (01:19:02) DEBUG: [Legendary]: Using cached install info (01:19:02) DEBUG: [Legendary]: Using cached install info (01:19:03) INFO: [Backend]: Checking if wine version exists: Proton - GE-Proton8-7 (01:19:03) WARNING: [Backend]: You are using Proton, this can lead to some bugs. Please do not open issues with bugs related to games (01:19:03) INFO: [Backend]: Checking if wine version exists: Proton - GE-Proton8-7 (01:19:03) INFO: [Backend]: Checking if wine version exists: Proton - GE-Proton8-7 (01:19:03) DEBUG: [Backend]: Running Wine command: run wineboot --init (01:22:57) INFO: [Legendary]: Launching Tomb Raider GAME OF THE YEAR EDITION: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig STEAM_COMPAT_CLIENT_INSTALL_PATH=/home/doods/.var/app/com.heroicgameslauncher.hgl/.steam/steam STEAM_COMPAT_DATA_PATH="/home/doods/Games/Heroic/Prefixes/default/Tomb Raider GAME OF THE YEAR EDITION" STEAM_COMPAT_INSTALL_PATH=/mnt/9d0ba9a2-ba39-4b1c-84d9-1198e5020470/EGS/TombRaiderGOTYE WINE_FULLSCREEN_FSR=0 PROTON_NO_ESYNC=1 PROTON_NO_FSYNC=1 STEAM_COMPAT_APP_ID=0 SteamAppId=0 SteamGameId=heroic-TombRaiderGOTYE PROTON_LOG_DIR=/home/doods/.var/app/com.heroicgameslauncher.hgl /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary launch d6264d56f5ba434e91d4b0a0b056c83a --language en --no-wine --wrapper " '/home/doods/.local/share/Steam/compatibilitytools.d/GE-Proton8-7/proton' run
(01:25:05) INFO: [Backend]: Stopping Display Power Saver Blocker [13:0803/012505.514317:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed [13:0803/012505.514366:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed [13:0803/012505.514425:ERROR:browser_main_loop.cc(274)] Gtk: gtk_widget_add_accelerator: assertion 'GTK_IS_ACCEL_GROUP (accel_group)' failed (01:25:05) INFO: [Frontend]: Refreshing legendary Library (01:25:05) INFO: [Legendary]: Refreshing library... (01:25:05) INFO: [Legendary]: Refreshing Epic Games... (01:25:05) INFO: [Legendary]: Game list updated, got 26 games & DLCs (01:25:05) DEBUG: [Legendary]: Using cached install info (01:25:05) DEBUG: [Legendary]: Using cached install info (01:25:05) INFO: [Legendary]: Running command: XDG_CONFIG_HOME=/home/doods/.var/app/com.heroicgameslauncher.hgl/config/heroic/legendaryConfig /app/bin/heroic/resources/app.asar.unpacked/build/bin/linux/legendary list --third-party `
Update: I found a repo for fedora on their github page, downloaded it and games started working fine.