mtkennerly / ludusavi Goto Github PK
View Code? Open in Web Editor NEWBackup tool for PC game saves
License: MIT License
Backup tool for PC game saves
License: MIT License
This is a follow-up to discussions in #16, #26, and #28. This could simplify the requirements for #25.
Right now, saves are organized like this, using Base64 for encoding:
the-backup-folder/
MTAwMCBBbXBz/ # 1000 Amps
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTE= # D:/Steam/steamapps/common/1000 Amps/save1
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTI= # D:/Steam/steamapps/common/1000 Amps/save2
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTM= # D:/Steam/steamapps/common/1000 Amps/save3
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2V0dGluZ3M= # D:/Steam/steamapps/common/1000 Amps/settings
MS4uLiAyLi4uIDMuLi4gS0lDSyBJVCEgKERyb3AgVGhhdCBCZWF0IExpa2UgYW4gVWdseSBCYWJ5KQ==/ # 1... 2... 3... KICK IT! (Drop That Beat Like an Ugly Baby)
other/
registry.yaml
Each game can also have an other
folder with a registry.yaml
if it has any registry data to back up.
It would be nice to use something more human-friendly than Base64, but there are some challenges:
C:
) and UNC path prefixes (local: \\?\C:\
, remote: \\shared_drive\
) in a safe, cross-platform way.hack//G.U.
and ***
)The solution to the above points needs to be simple enough that you can write a script to do the restoration without depending on Ludusavi at all. The current Base64 approach allows that (just decode to get the original path, then copy), but at the cost of human-readability.
Here's a possible option, using Base64 just for the game name and path prefix, but otherwise storing things normally:
the-backup-folder/
MTAwMCBBbXBz/ # 1000 Amps
RDo=/ # D:
Steam/
steamapps/
common/
1000 Amps/
save1
save2
save3
settings
MS4uLiAyLi4uIDMuLi4gS0lDSyBJVCEgKERyb3AgVGhhdCBCZWF0IExpa2UgYW4gVWdseSBCYWJ5KQ==/ # 1... 2... 3... KICK IT! (Drop That Beat Like an Ugly Baby)
registry.yaml
An advantage of this is that, although Ludusavi uses UNC paths internally to avoid the legacy Windows path limits, each component of a UNC path still can't exceed 255 or so characters, so a very long original path might produce Base64 that's too long for a UNC path component.
A further step would be to only use Base64 for the game names when they aren't a valid folder name, but otherwise just store them normally. That creates a special case in the rules, which I think is a dealbreaker, but it would make a lot of cases friendlier. Ignoring the special case issue, there would need to be a super clear indicator for which style is in use, because some things that look human-readable could actually be valid Base64 too: Whoopsie
= Z\x1a(\xa6\xc8\x9e
.
Some ideas:
# Launch GUI by default:
ludusavi
# Grab everything:
ludusavi backup
ludusavi backup --preview
ludusavi restore
ludusavi restore --preview
# Override current config:
ludusavi backup --target C:/ludusavi
ludusavi restore --source C:/ludusavi
# Filtering:
ludusavi backup Celeste Terraria
ludusavi backup --no-screenshots
I've made a few unsuccessful attempts at this. Not really sure how to proceed.
name: ludusavi
base: core18
version: '0.1'
summary: Backup tool for video game save data
description: |
Test.
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
parts:
executable:
source: https://github.com/mtkennerly/ludusavi/releases/download/v0.5.0/ludusavi-v0.5.0-linux.zip
# source: target/release/
plugin: dump
prime:
- ludusavi
override-build: |
chmod +x ludusavi
snapcraftctl build
stage-packages:
- libfontconfig1
- libfreetype6
- libpng16-16
- libxau6
- libxcb-render0
- libxcb-shape0
- libxcb-xfixes0
- libxcb1
- libxdmcp6
- libx11-6
- libxcursor1
- libxrandr2
- libxi6
- libx11-xcb1
apps:
ludusavi:
command: ludusavi
environment:
LD_LIBRARY_PATH: /root/stage/usr/lib/x86_64-linux-gnu
$ snapcraft && snap install --dangerous --devmode ludusavi_0.1_amd64.snap && ludusavi
Launching a VM.
[...]
ludusavi 0.1 installed
/snap/ludusavi/x17/ludusavi: error while loading shared libraries: libxcb.so.1: cannot open shared object file: No such file or directory
$ snapcraft --shell-after
$ LD_LIBRARY_PATH=/root/stage/usr/lib/x86_64-linux-gnu ./prime/ludusavi
thread 'main' panicked at 'Failed to initialize any backend! Wayland status: XdgRuntimeDirNotSet X11 status: XOpenDisplayFailed', /rustc/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2/src/libstd/macros.rs:13:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
name: ludusavi
base: core18
version: '0.1'
summary: Backup tool for video game save data
description: |
Test.
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
parts:
executable:
source: https://github.com/mtkennerly/ludusavi/releases/download/v0.5.0/ludusavi-v0.5.0-linux.zip
# source: target/release/
plugin: dump
prime:
- ludusavi
override-build: |
chmod +x ludusavi
snapcraftctl build
stage-packages:
- libfontconfig1
- libfreetype6
- libpng16-16
- libxau6
- libxcb-render0
- libxcb-shape0
- libxcb-xfixes0
- libxcb1
- libxdmcp6
- libx11-6
- libxcursor1
- libxrandr2
- libxi6
- libx11-xcb1
desktop-helper:
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
plugin: dump
prime:
- desktop-launch
override-build: |
echo '#!/bin/bash' > desktop-launch
cat common/init >> desktop-launch
cat common/desktop-exports >> desktop-launch
cat common/mark-and-exec >> desktop-launch
chmod +x desktop-launch
snapcraftctl build
apps:
ludusavi:
command: desktop-launch ludusavi
environment:
LD_LIBRARY_PATH: /root/stage/usr/lib/x86_64-linux-gnu
$ snapcraft && snap install --dangerous --devmode ludusavi_0.1_amd64.snap && ludusavi
Launching a VM.
[...]
ludusavi 0.1 installed
/snap/ludusavi/x19/desktop-launch: line 536: exec: ludusavi: not found
One way to do this would be to have an "add redirect" button in the restore screen, where you could configure replacements for parts of the paths. It would probably look a lot like the roots editor from the backup screen.
Currently, ludusavi only supports creating backups of wine/proton saves for steam games. Since there are many games that aren't available through steam/available for free somewhere else, adding support for different/custom wine prefixes is very desirable for integration in third party launchers & normal usage.
I'm looking into adding backup support to steam-buddy
for gamer-os, which will add support for EGS games in the next release, while using steams shortcut system for the proton integration with predictably generated game ids.
For this purpose, calling ludusavi separately for each game is alright, so a CLI option would suffice, with the mapping (wine prefix <-> game) handled by steam-buddy
Lords of Doom has its gamesave location reported as A:, B:\ on PCGW because it stored saves on floppy. If you use these drives for internal HDDs, then the entire drives will be copied to your backups folder.
I think that a check for drive root save paths could be conducted to remove cases like these. In this case, I feel PCGW shouldn't be edited because it is not incorrect. But, it doesn't make sense to backup entire drive roots in general.
This would be a Windows-specific fix.
Using the GUI, Ludusavi tries to backup many GB worth of files it identifies as "Battlefield II"'s save data (a game I've never had on my PC). The GUI crashes after it tries to display the list of those files. After following through with the backup, it turns out the files are actually the entirety of my %userprofile%.
This doesn't happen if the CLI is used instead of the GUI.
This may depend on iced-rs/iced#33 (text shaping and font fallback), although iced-rs/iced#213 has a workaround that's worth exploring (setting a custom font).
There are cases where certain PCGW articles have incomplete or wrong information, which can lead to issues like this:
This can later lead to issues when trying to restore the save file of any of the games that coincide in files, since it will overwrite the other one. It would be useful if Ludusavi warned if there are cases like this detected, maybe showing them on top of the list to see them easier and/or a warning with the conflicting games. Identifying them this way could also help to more easily see errors like this and fix them in the respective pages.
I just checked your Playnite extension for ludosavi and it worked great but I think it would be great to have an option to not import screenshots and in the better of cases, perhaps make this option configurable per game.
And I have another question: When backing up again, does it copy the same files again and overwrite them or does ludosavi detecti if it already exist and that it's the same file without changes to only copy files that have changed?
Also curious as to why use Base64 for naming since it makes things more difficult for manual manipulation on the user side and for other purpose and I don't see what's the benefit with this approach.
P.D: Someone made a thread for the extension here and that's how I knew about the extension, although it would be better if you made an official thread there https://playnite.link/forum/thread-342.html
And linking this relevant issue in Playnite: JosefNemec/Playnite#124
I've only run into one game so far (The Elder Scrolls IV: Oblivion) that fails for me with the default backup folder, because the paths are too long. My understanding is that using UNC paths (\\?\C:\...
) for operations internally would avoid this issue. Rust already handles UNC paths, but Ludusavi converts to simple paths for both internal use and display - instead, internal use should stick to UNC.
The CLI already indicates when it can't back up or restore a file, but the GUI doesn't currently do this, which is confusing.
Similar to how PCGW itself handles it in it's paths, not using hardcoded paths would give benefit of being more universal: if ludusavi is used as a cloud sync solution for saves with different usernames or drive letters, this can be problematic. Ideally ludusavi would automatically solve the data path to the ones that correspond with the current user using ludusavi. For example, this file:
Current Base 64 name: QzovVXNlcnMvQnJhbmRvbi9BcHBEYXRhL0xvY2FsL0Nyb3NzQ29kZS9jYy5zYXZl
Decoded name: C:/Users/Brandon/AppData/Local/CrossCode/cc.save
Decoded name without hardcoded data path: %LOCALAPPDATA%/CrossCode/cc.save
Base 64 name without hardcoded data path: JUxPQ0FMQVBQREFUQSUvQ3Jvc3NDb2RlL2NjLnNhdmU=
Another idea: changing the file and folder structure that Ludusavi has, using human readable directories.
BaseDirectory/%LOCALAPPDATA%/CrossCode/cc.save <- "CrossCode/cc.save" could be named in base64, so it would be BaseDirectory/%LOCALAPPDATA%/Q3Jvc3NDb2RlL2NjLnNhdmU=
BaseDirectory/%APPDATA%/...
BaseDirectory/%Documents%/...
BaseDirectory/%Other%/...
etc
I'm not sure how the scenario would be handled for drive letters or UNC paths. Maybe those should just be configured in the application itself and not as part of the save backup. With this approach file names of data could be named normally, just having the BaseDirectory in base64 since it's the only thing that could be problematic because of the game name.
This came up in #26. When you're just dealing with local backups, this doesn't really matter, but if you're backing up to a folder that's synchronized with a cloud service, then needlessly recreating/re-copying files can trigger the cloud sync and waste bandwidth.
These are already supported by default:
These would need to be added specially:
This is a follow-up to #16. The idea would be to have a YAML file in the backup folder like this:
MTAwMCBBbXBz:
name: 1000 Amps
files:
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTE=: D:/Steam/steamapps/common/1000 Amps/save1
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTI=: D:/Steam/steamapps/common/1000 Amps/save2
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2F2ZTM=: D:/Steam/steamapps/common/1000 Amps/save3
RDovU3RlYW0vc3RlYW1hcHBzL2NvbW1vbi8xMDAwIEFtcHMvc2V0dGluZ3M=: D:/Steam/steamapps/common/1000 Amps/settings
The goal is so that people can quickly check the contents without opening up Ludusavi and to help alleviate the unfamiliarity of Base64 for most users. It would also allow for text searching, since Ludusavi doesn't have that right now.
This is probably dependent on #3, but it'd be nice to have a plugin for Playnite that adds the option to back up or restore saves for a specific game in the library. The plugin itself would go in a separate repository.
Games that have save files in directory with other game files have everything copied over
Example game: Iconoclasts
Just those 3 files are save files.
All game files and folders get backed up:
I'm not sure if it's something that should be fixed on Ludosavi or PCGW side but I imagine there must be a lot of games that will have this issue.
Even if the entry was pointed directly in PCGW, it could be a problem that this game has a save file for each save slot, for example: save1
.
First of all, that's a very good project! Thank you for sharing it! But I think it would be a great thing to be able to backup and restore to and from a cloud, Drive or Dropbox, for example.
If you want, I can write that "module" in Python, as it is possible to run Python code in Rust, using pyo3. Let me know what you think!
I'm not sure if this would be useful to everyone so it's just an idea. I've wanted to play games that I left halfway and I just preferred to delete the saves and start over, but to do that you have to go to PCGW and search for the save location(s). Having an option to do it within Ludusavi would be useful for this and similar cases. If implemented, I think having a button next to the game name would work and also having to accept an extra confirmation dialogue after pressing the button to prevent mistakes.
With this, Ludusavi could completely manage the game saves and be a global save manager for all operations.
This is dependent on iced-rs/iced#209. At the same time, we can add options for more stores in addition to "other", since right now there isn't enough room for that many options in the window.
For example, backing up the save data for a game on Linux and restoring it on Windows. This would be a killer feature for me, as I tend to hop between machines and OSes pretty often and some games just don't have cloud sync.
I might start looking into how to do this myself, but I would love to hear your thoughts. Any guidance is appreciated :)
First backup try: save correctly backups
C:\Users\Brandon\AppData\Roaming\DarkSoulsIII\0110000103e0448f\DS30000.sl2
C:\Users\Brandon\AppData\Roaming\DarkSoulsIII\GraphicsConfig.xml
Second backup try: backup fails
Files full path:
C:\Users\Brandon\Google Drive\[Backup]\Game Saves\PC\Dark Souls III\drive-C\Users\Brandon\AppData\Roaming\DarkSoulsIII\0110000103e0448f\DS30000.sl2
C:\Users\Brandon\Google Drive\[Backup]\Game Saves\PC\Dark Souls III\drive-C\Users\Brandon\AppData\Roaming\DarkSoulsIII\GraphicsConfig.xml
It seems to only happen on games with long paths.
Iced doesn't have a built-in tab view component, but it should be feasible to set up with some custom-styled buttons in a container.
GSM has a "Steam Spreader" function for moving/symlinking game installs, as well as a "Link & Sync" function for doing the same just for save data. It may be worth adding similar functionality here for users coming from GSM, since it provides a way to redirect game saves to a cloud storage folder or alternative drive, thus acting as another form of backup. This would require some care to ensure it works well cross-platform and that it won't break anything (e.g., if folders/files are affected that shouldn't be or if it could interfere with the operation of Steam/etc).
About the directories, It's kind of hard navigating when a game has multiple save files, for example, in Dragon Age:
When a game has multiple saves, the program lags until you scroll over the files.
For the presentation, it would be better as a tree structure, if possible, giving the option to collapse folders. Like this:
Some games include screenshots folder. I know, there's a option to exclude steam screenshots but not all games are from steam or save in there. So before there is a automatic way, the user could have the option to just uncheck a specific folder so It doesn't backup it.
Having this option, could save cloud storage, because some game folder are just massive because of it.
The data set indicates whether a save location has been confirmed for a particular OS and store, but right now Ludusavi backs up everything regardless, since it's generally safer to back up too much than too little. That's good for Linux and Mac users, since some games may only have confirmed locations for Windows even though it's the same on any OS, but it's not so good for Windows users since they typically won't gain anything from the extra Linux/Mac locations (and those locations may not be as refined as the Windows data, leading to extraneous files like game assets).
This will just be a global setting. I don't think it's appropriate to set for individual games - for that use case, I would rather introduce a concept of ignored paths (although the ideal solution there would be to refine the data set so that no one would have a desire to ignore specific files in the first place).
It may be worth adding a similar filter for store type, but I doubt that there would be many store-specific false positives. For example, even if we happen to check a Steam subdirectory (like userdata/<id>
) in an Epic root, it just won't find anything, rather than finding something irrelevant. I'm not opposed to adding that, but I'd like to wait for a confirmed use case.
Firstly, I'd like to clarify that I have not tried ludusavi yet, but it's been in my bookmarks for a while.
From the README.md, It looks like it does something I've wanted for a while, and I will definately be checking this out.
The below can be taken as seriously as you want, and you may decide it to be "out of scope", but I figured it was better to communicate the ideas than to not.
The timing was funny, as I recently had created a reddit post to r/selfhosted:
https://www.reddit.com/r/selfhosted/comments/gnjv7r/an_idea_for_the_right_dev/
Basically, it seems like it would be a little spin on what you are already doing here since you are already supporting cross-platform.
What I'm suggesting; A server-client setup, a server application that stores the backups. and a client agent that communicates with the server. This would also allow multiple devices to not only backup, but also possibly sync.
The extra work would involve a web interface (for being headless), user management control, api key stuff for authentication.
Another idea that occurred to me as a I was typing this, is that you could even share game saves to other people, if reverse proxied.
This came up in #33. Right now, a preview/backup always triggers a full scan. It would save time to do a full scan initially, then just rescan the games that were found (plus any custom games). That should make backups almost as fast as restores.
We would still have to do a full scan after:
Theoretically, you could leave Ludusavi open for weeks and not have it pick up on newly installed games, but people probably won't have it running that long at a time, and if they did, they would be missing out on manifest updates anyway until they relaunched it.
As a means for more flexible backups, allow the use of an arbitrary backup command. Where the user would supply the entirety of the command and ludusavi fills in the save paths and game name.
Not sure how restores would be handled in this case though.
cp
:cp #{SAVE_PATHS} /my/backups/location/#{GAME_NAME}
rclone copy #{SAVE_PATHS} googledrive:/gamesaves/#{GAME_NAME}
restic backup #{SAVE_PATHS}
Since Ludusavi checks for all matching directories in the manifest for all games, there can be issues in certain game entries that have general locations for save files. For example: The Next Penelope
This is a game I've never played but since I have the directory listed in PCGW, it detects the save files.
Although it wouldn't be much of an issue, since the location is not specific, it tries to backup a lot of files.
The problem could be solved for this specific game by correcting the entry, but that's only possible if you own the game and can check. Another option is deselecting, but you'd have to do this each time you press select all and it's possible that you can forget to do it. I think adding an ignore list for games could solve this and other games that can have this issue in the future.
This is a follow-up to #2, where I had to make ctrl+x behave like ctrl+c in order to avoid a crash. This can be addressed with the next release of Iced.
Hello ๐
I have created a page for your app : https://alternativeto.net/software/ludusavi/
You can change anything wrong or complete if something is missing
Modals currently show their buttons at the top of the app, aligned with where the main screens show their buttons, but that makes it easy to accidentally click them without reading the message. If the buttons were shown below, then it would prevent accidental clicks.
I created a scoop manifest for ludusavi to handle automated installs and updates.
Once that is merged, can be installed via:
scoop bucket add extras
scoop install ludusavi
Upgrade
scoop update ludusavi
First of all thanks for the software, i am using with playnite and is really impressive. You could please could add support to make backups compressed? i think is better for backups on the cloud becase some problems on multiple folders tree or folder names and for share saves easily. could be something like "gamename/gamename.7z"
Thanks.
It's just using a generic program icon right now. An icon specific to Ludusavi would be a nice touch.
Just cargo install
ed with latest nightly compiler and got a crash on startup; reinstalled with --debug
and getting the following backtrace:
$ RUST_BACKTRACE=full ludusavi
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `0`,
right: `1`', /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.3/src/command/mod.rs:266:23
stack backtrace:
0: 0x5612f222c175 - backtrace::backtrace::libunwind::trace::h34afbfad7fd770fc
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
1: 0x5612f222c175 - backtrace::backtrace::trace_unsynchronized::h460d522b1619a600
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
2: 0x5612f222c175 - std::sys_common::backtrace::_print_fmt::ha45fac10086813b4
at src/libstd/sys_common/backtrace.rs:78
3: 0x5612f222c175 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hde84f63fcfd0e6de
at src/libstd/sys_common/backtrace.rs:59
4: 0x5612f2255adc - core::fmt::write::h540ac4a6a1232abc
at src/libcore/fmt/mod.rs:1076
5: 0x5612f22258d2 - std::io::Write::write_fmt::hc344eafd6e850b4d
at src/libstd/io/mod.rs:1537
6: 0x5612f222ed20 - std::sys_common::backtrace::_print::h4db88ff15cb5d61d
at src/libstd/sys_common/backtrace.rs:62
7: 0x5612f222ed20 - std::sys_common::backtrace::print::h5fc39e1b1f610bd3
at src/libstd/sys_common/backtrace.rs:49
8: 0x5612f222ed20 - std::panicking::default_hook::{{closure}}::h59e55edacb1d974a
at src/libstd/panicking.rs:198
9: 0x5612f222ea6c - std::panicking::default_hook::heee4c8016dfbf328
at src/libstd/panicking.rs:217
10: 0x5612f222f363 - std::panicking::rust_panic_with_hook::h8405b6301c79fb5a
at src/libstd/panicking.rs:526
11: 0x5612f222ef5b - rust_begin_unwind
at src/libstd/panicking.rs:437
12: 0x5612f222eecb - std::panicking::begin_panic_fmt::h0ed87aa3b2c392e6
at src/libstd/panicking.rs:391
13: 0x5612f20653eb - <wgpu_native::hub::Storage<T,I> as core::ops::index::Index<I>>::index::hfc55fb9a7c15150e
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.3/src/hub.rs:120
14: 0x5612f20653eb - wgpu_native::command::command_encoder_begin_render_pass::{{closure}}::hcf5d75ae5055f21a
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.3/src/command/mod.rs:266
15: 0x5612f20653eb - core::option::Option<T>::map::h697fd97b1316ecfe
at /rustc/8ac1525e091d3db28e67adcbbd6db1e1deaa37fb/src/libcore/option.rs:453
16: 0x5612f20653eb - wgpu_native::command::command_encoder_begin_render_pass::h718f23b331153491
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.3/src/command/mod.rs:264
17: 0x5612f20653eb - wgpu_command_encoder_begin_render_pass
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-native-0.4.3/src/command/mod.rs:739
18: 0x5612f204e681 - wgpu::CommandEncoder::begin_render_pass::h9198cf2b2350af10
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.4.0/src/lib.rs:1059
19: 0x5612f1e1fedc - <iced_wgpu::window::backend::Backend as iced_native::window::backend::Backend>::draw::h84288e61d0fdadac
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/iced_wgpu-0.2.3/src/window/backend.rs:81
20: 0x5612f1d848eb - iced_winit::application::Application::run::{{closure}}::h68bec22a0ffd22f5
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/iced_winit-0.1.0/src/application.rs:331
21: 0x5612f1dbd28c - winit::platform_impl::platform::sticky_exit_callback::h1d6fe088192a30ca
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/linux/mod.rs:698
22: 0x5612f1dbd28c - winit::platform_impl::platform::x11::EventLoop<T>::run_return::hdd831da1b9561a55
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/linux/x11/mod.rs:312
23: 0x5612f1dbd28c - winit::platform_impl::platform::x11::EventLoop<T>::run::h08b32b2a1301b722
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/linux/x11/mod.rs:390
24: 0x5612f1d88da2 - winit::platform_impl::platform::EventLoop<T>::run::ha61a340b9abc6bb3
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/linux/mod.rs:645
25: 0x5612f1da959a - winit::event_loop::EventLoop<T>::run::hb9cd14cd85b44659
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.22.2/src/event_loop.rs:149
26: 0x5612f1da05f9 - iced_winit::application::Application::run::hd3a53b48f5881e80
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/iced_winit-0.1.0/src/application.rs:214
27: 0x5612f1e29c40 - iced::application::Application::run::h922dcf1168625d92
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/iced-0.1.1/src/application.rs:201
28: 0x5612f1e29c40 - ludusavi::gui::run_gui::hf1e3fb9a0fc5a955
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/ludusavi-0.2.0/src/gui.rs:948
29: 0x5612f1e29c40 - ludusavi::main::h59784ecabf0ae9a3
at /home/mc/.cargo/registry/src/github.com-1ecc6299db9ec823/ludusavi-0.2.0/src/main.rs:14
30: 0x5612f1e16d17 - std::rt::lang_start::{{closure}}::hc238cc9d46fce9ba
at /rustc/8ac1525e091d3db28e67adcbbd6db1e1deaa37fb/src/libstd/rt.rs:67
31: 0x5612f222f803 - std::rt::lang_start_internal::{{closure}}::h7cea099ad4edf1eb
at src/libstd/rt.rs:52
32: 0x5612f222f803 - std::panicking::try::do_call::h42d93372c44025d2
at src/libstd/panicking.rs:348
33: 0x5612f222f803 - std::panicking::try::hb47a4182362d3341
at src/libstd/panicking.rs:325
34: 0x5612f222f803 - std::panic::catch_unwind::h2afcfbf3125915b4
at src/libstd/panic.rs:394
35: 0x5612f222f803 - std::rt::lang_start_internal::h4f696727fe904f48
at src/libstd/rt.rs:51
36: 0x5612f1e29c78 - main
37: 0x7f04cc844002 - __libc_start_main
38: 0x5612f1d5e1ee - _start
39: 0x0 - <unknown>
FWIW, I'm running Arch and using a tiling window manager (awesome
). It does display the UI for a few hundred milliseconds before it crashes.
If there's anything else I can do to help debug, let me know.
It would be great if each entry was maybe saved in a zipped structure with original file names. Potential reasons for this:
I'm planning to implement this with native-dialog once the changes from this PR are released.
Adding this https://github.com/hecrj/iced/blob/master/.github/workflows/build.yml#L44
to the github flow will ensure that "VCRUNTIME140_1.dll was not found" won't appear anymore.
Got that tip from Iced creator himself. Figured I would share that.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.