C2 save/load system forgets disabled Physics collisions?

  • Problem Description

    Overview

    The native C2 save/load system appears to forget the "disabled collisions" state of Physics objects.

    After loading, all Physics collisions are enabled regardless of prior state.

    Details

    The Physics behavior has an option to "Disable Collisions" between objects, on an object-by-object basis.

    I'll refer to the data structure that stores that inter-object collision info, as the "collision relationships list".

    e.g. Given SpriteA, SpriteB, and SpriteC, you could disable collisions between only SpriteA and SpriteC.

    All other collision combinations would still occur normally.

    When using the native C2 save/load system, if you save, and then load, the Physics behavior's "collision relationships list" state is not restored.

    After loading, all collision relationships are set to enabled.

    Attach a Capx

    https://www.dropbox.com/s/jpvaro62rvj8t81/fi_demo_Physics_DisabledCollisionsForgottenOnSaveLoad.capx?dl=1

    Description of Capx

    Image of the capx.

    The capx shows a real-time interactive demo of the problem.

    There's text in the capx to explain steps to execute and what to look for.

    The capx shows two physics enabled sprite objects, a static (Immovable) Orange box, and a moving Blue box.

    The moving blue box is attracted to the Red "X" which drags it back and forth in a horizontal sine motion.

    On layout start, collisions between the blue mover box and orange static box are disabled.

    This allows the blue mover box to pass through the static orange box without colliding.

    At the bottom of the canvas are 5 buttons.

    • Save: Save game state via native C2 save/load system.
    • Load: Load game state via native C2 save/load system.
    • Set no-hit: Disables collisions between Mover & Static.
    • Restart: Restarts layout.
    • Toggle text: Show/Hide text.

    Steps to Reproduce Bug

    Run the capx.

    • Observe the blue box passing through the orange box without colliding. This is due to the event: On start, disable collisions between those objects.
    • Click the "Save" button, to save the game via C2's native save/load system.
    • Click the "Load" button, to load the last save state.
    • Observe the blue box now collides with the orange box. The disabled collision state has not been restored.

    You can optionally experiment a little further:

    • Click the "Set no-hit" button to re-disable collisions.
    • Observe, the boxes no longer collide.
    • Retry clicking the "Save" and then "Load" buttons.
    • The boxes now collide again.

    Observed Result

    The Physics behavior's "collision relationships list" is not restored after loading the game state, and so the boxes begin colliding with each other.

    Expected Result

    The "collision relationships list" is restored after loading the game state, the disabled collision status between the boxes is likewise restored. and so the boxes pass through each other without colliding.

    Affected Browsers

    • NW.js: YES
    • Chrome: YES
    • FireFox: YES
    • Opera: YES
    • Iron: YES
    • Internet Explorer: YES

    Operating System and Service Pack

    Win7 x64 - Pro

    SP1

    Construct 2 Version ID

    Release 247 (64- bit) checked

    Built at 13:33:48 on Sep 21 2017

    Release Notes

  • Hey Ashley, just curious if you got a chance to take a look at this.

    I know you have a ton going on, so no worries either way.

  • Hey Ashley, just curious if you got a chance to take a look at this.

    I know you have a ton going on, so no worries either way.

    hi fisholith, I just fixed your issue. all you have to do is add "On load complete" condition and then add the action to disable physics collision for the box in it

    https://drive.google.com/open?id=1rrmHOSK5Xr2k6hHl08eu9VPL6WO9mMj7 here's updated file.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Hey drg81, thanks for the reply.

    It does work, and it's one of the two options I can think of for dealing with the Physics save/load behavior.

    Using "On load complete" to manually reconstruct the prior "collision relationships list" is a workaround I've spent some time looking into. It gets a bit trickier in larger projects with conditionally disabled collisions, but it's still workable.

    In essence you have to store your own hand-made parallel "collision relationships list" in a dictionary object or something similar. You update your dictionary-based hand-made list every time you update the real Physics object. Since that dictionary object will be restored correctly when the save state is loaded, you can get the collision relationship data out of it and use it's entries to reconstruct the correct collision relationships in the Physics object.

    The other possible workaround, (much more self-contained, but much more iffy with update compatibility), is to modify the physics objects runtime JavaScript.

    The "instanceProto.saveToJSON()" function is responsible for serializing the internal state of the object into JSON. I think it should be possible to add the collision relationships list data into that outgoing data.

    Then in the "instanceProto.loadFromJSON()" you would have to extract the info and feed it back into the Physics object to reconstruct the collision relationships state.

    This is how most objects store and recall their collision state info, and it's what would be changed in order to resolve the save/load behavior described in the bug report.

    There are compatibility downsides to making unofficial modifications to the JavaScript of an official plugin though, so I don't really recommend it.

    Anyway, thanks again for the suggestion, drg81. I think the "On load complete" method is the way to go for the time being.

  • Thanks for the good .capx sample, it demonstrates the issue well. Unfortunately the main reason this doesn't work is because it's very difficult in the C2 runtime with the limited JavaScript features we must use to preserve broad compatibility with old browsers etc. Basically the C2 runtime architecture makes it difficult to save the data (which is global, rather than per-instance, so the instanceProto.saveToJSON() method is not really applicable), and the "collision relationship list" is a pretty advanced data structure that cannot be directly saved as JSON without some ugly hacks in the engine. I've already fixed this for the new C3 runtime since it's better architected to handle cases like this and the latest JS features makes it much easier to support (since there are better data structures to store the collision relationship list with).

    If this can be worked around by restoring disabled collisions in "on load complete" then I would prefer to leave it as only fixed in the C3 runtime given the difficulty of properly implementing this in the C2 runtime.

  • Hey Ashley,

    Thanks for the reply, and for explaining some of the inner workings, it's always interesting.

    The storing of global vs instance data is an interesting aspect.

    It sounds like maybe making an in-event-sheet wrapper function (via Function object), for enabling and disabling physics collisions might be a good alternative then. The wrapper could automatically update our own external collision relationship list, that could be stored on-save and later used to reload the relationships via "on load complete".

    Anyway thanks again.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)