ruffle-rs / ruffle

A Flash Player emulator written in Rust
https://ruffle.rs
Other
15.1k stars 776 forks source link

Error on https://unblockedgames.blogbucket.org/electric-man-2-hacked/ #4932

Closed UsernameTakenorunavailable closed 1 year ago

UsernameTakenorunavailable commented 2 years ago

Error Info

Error name: Error Error message: panicked at 'called Option::unwrap() on a None value', core/src/display_object/container.rs:849:18 Error stack:

Error: panicked at 'called `Option::unwrap()` on a `None` value', core/src/display_object/container.rs:849:18
    at a.wbg.__wbg_new_df6e6ab7a65c4c4d (https://unblockedgames.blogbucket.org/ruffle/ruffle.js:1:7026)
    at std::sync::once::Once::call_once::{{closure}}::hcab81935c0617527 (<anonymous>:wasm-function[1001]:0x277822)
    at std::sync::once::Once::call_inner::h79faa41f4d270a0b (<anonymous>:wasm-function[967]:0x26d28d)
    at core::ops::function::FnOnce::call_once{{vtable.shim}}::ha2a5dc7de82b8523 (<anonymous>:wasm-function[3869]:0x41ac5a)
    at std::panicking::rust_panic_with_hook::hbdbceb5cd158bf19 (<anonymous>:wasm-function[2993]:0x3b93ea)
    at rust_begin_unwind (<anonymous>:wasm-function[4079]:0x42057c)
    at core::panicking::panic_fmt::h3ab5417155b7ba3b (<anonymous>:wasm-function[4229]:0x427348)
    at core::panicking::panic::h5bfdfaa3db9a4b4a (<anonymous>:wasm-function[4023]:0x41dcfe)
    at core::ops::function::FnOnce::call_once::h54a4376cf11af2c5 (<anonymous>:wasm-function[860]:0x24a804)
    at ruffle_core::avm1::function::Executable::exec::h8e7357a0bef754eb (<anonymous>:wasm-function[360]:0xd00e8)

Player Info

Allows script access: false Player type: Object SWF URL: https://files.blogbucket.org/2017/electricman2_hack.swf Attribute 0: undefined Attribute 1: undefined Attribute 2: undefined Attribute 3: undefined Attribute 4: undefined

Page Info

Page URL: https://unblockedgames.blogbucket.org/electric-man-2-hacked/ SWF URL: https://files.blogbucket.org/2017/electricman2_hack.swf

Browser Info

Useragent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36 OS: Win32

Ruffle Info

Version: 0.1.0 Name: nightly 2021-06-27 Channel: nightly Built: 2021-06-27T00:10:45.461Z Commit: 169c79fa3a5c5eb28a221712a3ef29a2c1871755

sombraguerrero commented 2 years ago

Subsequent reports of this issue have clarified that the crash is reproducible by entering the first level (after the tutorial). The crash occurs as soon as the start timer hits 0. If the crash does not happen on its own, and you're not able to enter the first level, it has been confirmed that spam-clicking a Round One level will eventually get you into it so you can reproduce the crash.

There is potentially, though only speculatively, relevant conversation surrounding #993 and #3839 Video: https://drive.google.com/open?id=12BEHrjycvOxX4hpRJfrvkTxLU5DUcLnw&authuser=bobertdos%40gmail.com&usp=drive_fs

Mipsters commented 1 year ago

Comment copied from #7681

Similar issue in this game: http://www.freeworldgroup.com/games6/electricman2/electricman2hs_fwg.swf

Error occurs every second fight, you can save and load to reach the following fights if you play the tutorial, after you beat the first enemy, the tutorial will speed the rest without user interaction and spawn the enemys of the first level before showing the level select menu

n0samu commented 1 year ago

I did a bit of testing and it seems like crashes can be avoided by simply skipping the tutorial. So for anyone having trouble playing this game, that's my recommendation for now!

sombraguerrero commented 1 year ago

That hasn't been my experience. Tutorial or not, you can last a couple stages consecutively sometimes, but in my experience, unless you reload to clear the stage, the crash will eventually happen.

n0samu commented 1 year ago

That hasn't been my experience. Tutorial or not, you can last a couple stages consecutively sometimes, but in my experience, unless you reload to clear the stage, the crash will eventually happen.

Oh okay, I didn't test that extensively. I did have an issue where the 3rd stage wouldn't complete until I reloaded, which might be related. So yeah, reloading between stages is definitely a good bet.

orhun commented 1 year ago

Can confirm that the error persists with Ruffle 0.1.0-nightly (084b25203 2022-09-14) on Arch Linux:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', core/src/display_object/container.rs:810:33
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
AVM2 stack trace:
Aborted (core dumped)
n0samu commented 1 year ago

@Aaron1011 has a branch that might help understand the issues with this game: https://github.com/Aaron1011/ruffle/tree/rewind_depth Here are his messages on Discord explaining the issue:

It looks like you get avm1 to get the same clip at two different depths, by using 'swapDepths' and then rewinding The rewind is not to the frame where the timeline object is added - it's just to a slightly earlier frame where nothing happens ok, it looks like === is just doing something odd - calling getDepth on each object returns different values, as expected So, https://www.kirupa.com/developer/actionscript/depths2.htm seems correct (as far as I've tested) - a rewind in avm1 wipes out the timeline, and forcibly overwrites anything at the timeline depth for every frame from frame 1 to your target frame plus some weirdness where === doesn't seem to do pointer equality for MovieClip and Electricman2 actually depends on this behavior It tries and fails to remove a clip with a negative depth, but then that clip ends up getting overwriten due to a subsequent rewind Because of the way it uses swapDepths, subsequent enemies end up with positive depths - this only happens when you kill the first tutorial enemy So I suspect the author was completely unaware of this behavior, and it just happened to work for an entirely unrelated reason

And later conversation between Aaron and kmeisthax:

Aaron:

The test I linked shows that === evaluates to true But they behave like two different objects you can call getDepth on them and it returns different values My guess is that === is actually checking some hidden properties (movie clip symbol ID or something) which looks like an object identity check in all other situations

kmeisthax:

the instance number, perhaps?

Aaron:

Yeah, maybe

kmeisthax:

hmm... so instead of if !child.placed_by_script() in run_goto we need if depth < AVM1_DEPTH_BIAS or whatever we call it

Aaron:

we also need logic to remove other objects with depth < AVM1_DEPTH_BIAS

n0samu commented 1 year ago

Panic has been fixed by #9447. Remaining problems will be tracked in #9594.