Scirra / Construct-bugs

Public bug report submissions for Construct 3 and Construct Animate. Please read the guidelines then click the 'Issues' tab to get started.
https://www.construct.net
107 stars 83 forks source link

Loading Save state messes with hierarchy #8118

Closed Everade closed 1 week ago

Everade commented 1 month ago

Problem description

During specific circumstances, the loading process of a save state during runtime, can change the UID of a child instance and cause further issues associated with it. This creates weird edge cases, for example the child being assigned to the wrong parent and more.

Attach a .c3p

issueLoadStateChildren.zip

Steps to reproduce

  1. Preview the project
  2. It will automatically save state after 0.1seconds, so you don't need to save it yourself
  3. Left Mouse Click on the left parent. This will destroy its own child.
  4. Press L on your keyboard. This will load the original save state.
  5. The issue is now apparent. Observe what changed.
  6. Press L to load the save state again, it fixes the issues we just had!

Observed result

The middle child moved over to the third parent, the child's UID changed, as well as some text properties. A similar issue can be reproduced when destroying the middle child. Destroying the right child doesn't cause any oberservable issues. Meaning that, the current runtime state (deleted instances) interferes with the loading process of save states.

Expected result

It should load the save state, as it was saved. The runtime state should not affect the loading of a save state.

More details

This issue was found because it led to crashes when loading save states on runtime just 10 seconds later after it was saved on a checkpoint. When loading the save state you could continue the game until C3 tried to wrap text on a child instance when that instance came into view. It specifically crashes on the instance of which the UID changed when loading the save state. So an almost identical scenario to the issue reported, leading to a crash. loadStateCrash

We also noticed that it started to swap instances around. So it's not just an inconvenience, but can lead to crashes due to unpredictable loaded states. Unfortunately i wasn't able to reproduce the crash in a minimal project.

Affected browsers/platforms: Only tested in Chrome

First affected release: Unknown, i suspect this started with the release of hierarchies.

System details

View detailsPlatform information Product: Construct 3 r399 (beta) Browser: Chrome 126.0.6478.127 Browser engine: Chromium Context: webapp Operating system: Windows 11 Device type: desktop Device pixel ratio: 1 Logical CPU cores: 32 Approx. device memory: 64 GB User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Language setting: en-US Local storage Storage quota (approx): 503 gb Storage usage (approx): 2.2 gb (0.4%) Persistant storage: No Browser support notes This list contains missing features that are not required, but could improve performance or user experience if supported. Nothing is missing. Everything is OK! WebGL information Version string: WebGL 2.0 (OpenGL ES 3.0 Chromium) Numeric version: 2 Supports NPOT textures: yes Supports GPU profiling: no Supports highp precision: yes Vendor: Google Inc. (NVIDIA) Renderer: ANGLE (NVIDIA, NVIDIA GeForce RTX 3090 (0x00002204) Direct3D11 vs_5_0 ps_5_0, D3D11) Major performance caveat: no Maximum texture size: 16384 Point size range: 1 to 1024 Extensions: EXT_clip_control EXT_color_buffer_float EXT_color_buffer_half_float EXT_conservative_depth EXT_depth_clamp EXT_disjoint_timer_query_webgl2 EXT_float_blend EXT_polygon_offset_clamp EXT_render_snorm EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic EXT_texture_mirror_clamp_to_edge EXT_texture_norm16 KHR_parallel_shader_compile NV_shader_noperspective_interpolation OES_draw_buffers_indexed OES_sample_variables OES_shader_multisample_interpolation OES_texture_float_linear OVR_multiview2 WEBGL_blend_func_extended WEBGL_clip_cull_distance WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw WEBGL_polygon_mode WEBGL_provoking_vertex WEBGL_stencil_texturing Audio information System sample rate: 48000 Hz Output channels: 2 Output interpretation: speakers Supported decode formats: WebM Opus (audio/webm;codecs=opus) WebM Vorbis (audio/webm;codecs=vorbis) MPEG-4 Opus (audio/mp4;codecs=opus) MPEG-4 AAC (audio/mp4;codecs=mp4a.40.2) MP3 (audio/mpeg) FLAC (audio/flac) PCM WAV (audio/wav;codecs=1) Supported encode formats: WebM Opus (audio/webm;codecs=opus) MPEG-4 Opus (audio/mp4;codecs=opus) MPEG-4 AAC (audio/mp4;codecs=mp4a.40.2) Video information Supported decode formats: WebM AV1 (video/webm;codecs=av01.0.00M.08) WebM VP9 (video/webm;codecs=vp9) WebM VP8 (video/webm;codecs=vp8) MPEG-4 AV1 (video/mp4;codecs=av01.0.00M.08) MPEG-4 H.265 (video/mp4;codecs=hev1.1.2.L93.B0) MPEG-4 H.264 (video/mp4;codecs=avc1.420034) Supported encode formats: WebM AV1 (video/webm;codecs=av01.0.00M.08) WebM VP9 (video/webm;codecs=vp9) WebM VP8 (video/webm;codecs=vp8) WebM H.264 (video/webm;codecs=avc1.420034) MPEG-4 VP9 (video/mp4;codecs=vp9) MPEG-4 H.264 (video/mp4;codecs=avc1.420034)
shotgunanaconda commented 1 month ago

I want to confirm that this is/was a significant problem in my project, which Everglade gratefully helped me debug and work around. It led to crashes as described above and also made it more difficult to code logic based on UIDs, since you never know if or what object will change its UID from a load state. In my case, I could work around it by using instance values, but that won't always be possible.

I've also had situations where entire sprites get displaced, or custom actions trigger UID changes after a load state. It's great that it was possible to somewhat replicate the issue, because many other results seem to stem from a hodgepodge of actions interacting and can't be easily lifted over to an empty project.

I only use stables and can confirm that that its been happening on the last 2 specifically (but possible that it existed before). But it initially became really noticeable on an exported build on the second to latest stable.

DinoSystem commented 1 month ago

A classic xD

shotgunanaconda commented 1 month ago

image Jumping in again to say i believe this is another result of the same bug, loadstate makes this pick parent event not work. It cant reference whatever is in its hierarchy after a loadstate.

Interesting enough it only seems to have if a custom action has happened post save state. So for instance if i save, trigger the custom action, load = it cant do it again. Really makes this, currently, unusable for any larger project which is a shame since hierarchies makes things so much easier.

DiegoScirra commented 1 week ago

The specific issue in the example project will be fixed in the next beta.

It's very hard to tell if there will be other issues in more complex setups though as restoring the state of hierarchies in all cases is surprisingly difficult.