Flash Player Oddities - ruffle-rs/ruffle GitHub Wiki
This page is a list of weird or buggy behaviors in the official Flash Player. Many of these issues are not well understood and require investigation. This also includes behavior that varies between different version of the Flash Player. Spooky! 👻
AVM1
DefineFunction2
skips preloading _parent
register
If a DefineFunction2
function on the root timeline tries to preload _parent
in a register, the player ends up skipping this preload because _parent
is undefined. _global
will mistakenly get preloaded in this register instead if the function also uses it. See the define_function2_preload_order
test for an example.
NaN == NaN
is true
NaN == NaN
returns true in AVM1 depending on the version of the Flash Player. Flash Player 6 and below(?) properly returns false. Higher versions return true. This is not affected by the SWF version.
NaN.toString(base)
returns garbage for non-decimal bases
NaN.toString(16)
returns -(0000000
for example. There are different garbage values for every non-decimal base. The int-to-string algorithm ends up chewing on the bit pattern for -NaN (0xFFF80000_00000000), getting negative values for the digit and indexing the wrong way from ASCII '0'.
Some simple code that should match the result of Flash Player for NaN: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=95ff82ad6762025e08556ace0e061ae0
This depends on the version of the Flash Player, regardless of SWF version. It seems to occur Flash Player 7? and higher. Flash Player 6 and below prints 0
for all non-decimal bases. Currently Ruffle returns 0 in this case, but we may want to make this a setting in the future.
o
is null
trace(o)
will print null
instead of the expected undefined
.
AVM2
stage.transform
stage.x
, stage.scaleX
throw an error when accessed. However, stage.transform
is still accessible. Changing stage.transform.matrix
does transform vector art on the stage, but other objects such as TextFields are not affected!
Addtionally, stage.transform.concatenatedMatrix
doesn't return an identity matrix by default. It returns a scale matrix depending on the stage quality level, e.g. High stage quality is 4x supersampling and results in a matrix that scales by 4x.
stage.tabChildren
stage.tabChildren
always returns true
when read, but when set, it actually sets the value of tabChildren
of the root movie clip. The weird thing is that the tabChildren
of the root is set even when the root is removed (e.g. by stage.removeChild(root)
).