Glitchy behaviours just by objects being into a subfolder!!

Report Construct 2 bugs here.

Post » Sun May 14, 2017 8:43 pm

Changing the subfolder an object is in does not change the order in which they're stored in the XML file, or it's ID. You can look at the XML files to see this.

As for "presumably" - yeah. No. Presumptions don't help solve the issue. Especially when they're not accurate.
B
70
S
40
G
24
Posts: 517
Reputation: 20,068

Post » Mon May 15, 2017 9:28 am

digitalsoapbox wrote:Changing the subfolder an object is in does not change the order in which they're stored in the XML file, or it's ID. You can look at the XML files to see this.


Example project posted in this thread without modification:

Code: Select all
<object-folder>
  <object-folder name="New folder">
    <object-type name="Player" sid="461099846823012">
      <plugin id="Sprite" />
      <behaviors>
        <behavior-type name="Platform" sid="684013238865744">
          <behavior id="Platform" />
        </behavior-type>
      </behaviors>
      <animation-folder>
        <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="754574662893683" speed="5">
          <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
        </animation>
      </animation-folder>
    </object-type>
  </object-folder>
  <object-type name="Sprite" sid="251897685913489">
    <plugin id="Sprite" />
    <behaviors>
      <behavior-type name="Solid" sid="227558398387300">
        <behavior id="solid" />
      </behavior-type>
      <behavior-type name="Sine" sid="717431858105516">
        <behavior id="Sin" />
      </behavior-type>
    </behaviors>
    <animation-folder>
      <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="639043081041614" speed="5">
        <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
      </animation>
    </animation-folder>
  </object-type>
  <object-type name="Sprite2" sid="619511337493328">
    <plugin id="Sprite" />
    <behaviors>
      <behavior-type name="Platform" sid="399711601778041">
        <behavior id="Platform" />
      </behavior-type>
      <behavior-type name="Solid" sid="383344487100023">
        <behavior id="solid" />
      </behavior-type>
    </behaviors>
    <animation-folder>
      <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="961475536146256" speed="5">
        <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
      </animation>
    </animation-folder>
  </object-type>
  <object-type name="Text" sid="599919735085155">
    <plugin id="Text" />
  </object-type>
</object-folder>


After moving player object out of subfolder:

Code: Select all
<object-folder>
  <object-folder name="New folder" />
  <object-type name="Sprite" sid="251897685913489">
    <plugin id="Sprite" />
    <behaviors>
      <behavior-type name="Solid" sid="227558398387300">
        <behavior id="solid" />
      </behavior-type>
      <behavior-type name="Sine" sid="717431858105516">
        <behavior id="Sin" />
      </behavior-type>
    </behaviors>
    <animation-folder>
      <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="639043081041614" speed="5">
        <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
      </animation>
    </animation-folder>
  </object-type>
  <object-type name="Sprite2" sid="619511337493328">
    <plugin id="Sprite" />
    <behaviors>
      <behavior-type name="Platform" sid="399711601778041">
        <behavior id="Platform" />
      </behavior-type>
      <behavior-type name="Solid" sid="383344487100023">
        <behavior id="solid" />
      </behavior-type>
    </behaviors>
    <animation-folder>
      <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="961475536146256" speed="5">
        <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
      </animation>
    </animation-folder>
  </object-type>
  <object-type name="Text" sid="599919735085155">
    <plugin id="Text" />
  </object-type>
  <object-type name="Player" sid="461099846823012">
    <plugin id="Sprite" />
    <behaviors>
      <behavior-type name="Platform" sid="684013238865744">
        <behavior id="Platform" />
      </behavior-type>
    </behaviors>
    <animation-folder>
      <animation framecount="1" loop="0" name="Default" pingpong="0" repeatcount="1" repeatto="0" sid="754574662893683" speed="5">
        <frame duration="1" hotspotX="0.5" hotspotY="0.5" />
      </animation>
    </animation-folder>
  </object-type>
</object-folder>


Clearly, the player object has moved, and as such, the order has changed.

digitalsoapbox wrote:As for "presumably" - yeah. No. Presumptions don't help solve the issue. Especially when they're not accurate.


You reeeaaally don't want to go there.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Mon May 15, 2017 10:11 am

And here's why.

data.js object definitions from unmodified example:

Code: Select all
[
      ["Player", 1, false, [], 1, 0, null, [["Default", 5, false, 1, 0, false, 754574662893683, [["player-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Platform", 2, 684013238865744]], false, false, 461099846823012, [], null],
      ["Sprite", 1, false, [], 2, 0, null, [["Default", 5, false, 1, 0, false, 639043081041614, [["sprite-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Solid", 3, 227558398387300], ["Sine", 4, 717431858105516]], false, false, 251897685913489, [], null],
      ["Sprite2", 1, false, [], 2, 0, null, [["Default", 5, false, 1, 0, false, 961475536146256, [["sprite2-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Platform", 2, 399711601778041], ["Solid", 3, 383344487100023]], false, false, 619511337493328, [], null],
      ["Text", 0, false, [], 0, 0, null, null, [], false, false, 599919735085155, [], null]
   ]


data.js object definitions after moving the Player object out of the subfolder:

Code: Select all
[
         ["Sprite", 1, false, [], 2, 0, null, [["Default", 5, false, 1, 0, false, 639043081041614, [["sprite-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Solid", 2, 227558398387300], ["Sine", 3, 717431858105516]], false, false, 251897685913489, [], null],
         ["Sprite2", 1, false, [], 2, 0, null, [["Default", 5, false, 1, 0, false, 961475536146256, [["sprite2-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Platform", 4, 399711601778041], ["Solid", 2, 383344487100023]], false, false, 619511337493328, [], null],
         ["Text", 0, false, [], 0, 0, null, null, [], false, false, 599919735085155, [], null],
         ["Player", 1, false, [], 1, 0, null, [["Default", 5, false, 1, 0, false, 754574662893683, [["player-default-000.png", 825, 0, 0, 0, 0, 1, 0.5, 0.5, [], [], 0]]]], [["Platform", 4, 684013238865744]], false, false, 461099846823012, [], null]
      ]


In case you haven't noticed, the order these are stored in matches the order in the XML 1:1. The ID numbers used in the runtime are the indices into this array. The object names only exist unmodified in preview. In exported projects, they are replaced with t0, t1, t2, etc.

Care to tell me I'm wrong now?
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Thu Jun 22, 2017 4:31 pm

Sorry for taking so long to get round to this, the launch of C3 has been manic.

The original .capx is not a very good case - it relies on Platform + Solid on the same object, which has never been a directly supported case in the engine. The engine treats objects as either a moving object or an obstacle; you shouldn't use both. (I might actually block this case in C3 since it's not supported and people keep doing it.) I'd appreciate a different example .capx that shows a similar problem without using this not-really-supported case.

If we investigate the .capx anyway, the problem comes down to the order of ticking behaviors. Platform has special code to say "if on a moving platform, move with it". Since the .capx uses the unusual case of a platform and a solid, and then another platform on top, it creates a 2-link chain, and the order of updates becomes important. If the bottom object ticks first, it moves to follow the platform, then the top object ticks and follows the bottom object, and everything worked OK. However if the top object ticks first, the bottom object has not moved so it stays where it is. Then the bottom object ticks and moves away to follow the platform, causing a gap to form between the two, which is the problem here.

There is no obvious way to fix this problem, because we have to tick the behaviors in some order. Any changes we make would just move the problem somewhere else. If we sort by the object name and tick in that order, then renaming objects can change the tick order. If we tick in the order objects were created in the editor, then deleting and recreating an object can change the tick order. There's no gold standard tick order that is the "correct" one. I am also against letting the user customise the tick order; micro-managing such obscure parts of the engine is the exact opposite of the design principles that has made Construct successful.

I'm also not convinced this is actually a serious problem - C2 has been out ~6 years and we've only just had a report involving an obscure case of using platform and solid at the same time (which is why I'd be interested to see a more convincing example). For the most part, the order behaviors tick in shouldn't matter.

Even if this does affect a number of projects, it's not clear what to do about it. We have to choose some order to tick behaviors, and that order can probably be changed by something the user does.
Scirra Founder
B
387
S
230
G
87
Posts: 24,248
Reputation: 192,238

Post » Sat Jun 24, 2017 5:13 pm

Ashley wrote:The original .capx is not a very good case - it relies on Platform + Solid on the same object, which has never been a directly supported case in the engine. The engine treats objects as either a moving object or an obstacle; you shouldn't use both. (I might actually block this case in C3 since it's not supported and people keep doing it.) I'd appreciate a different example .capx that shows a similar problem without using this not-really-supported case.


Thanks for your anwser, Ashley. But I think you should reconsider your posture on Platform + Solid not working well together and maybe look into making them more compatible (or offering some alternative for solid platformer objects). Also blocking it on C3 could break a lot of old/current projects and negatively impact backwards compatibility.

While I don't know the inner workings of Construct and assume it may be difficult to fix that incompatibility, think that stuff like pushable solid blocks (for wich using platform behaviour seems like the simplest and more obvious solution so they are affected by gravity, move around with Simulate control when pushed and interact with platforms) are actually a pretty common case on platformers (So there's the reason a lot of us keep doing it! ;) ). Just to name a few examples, Spelunky, some Sonic games (like the first one) or even solid enemies you can stand on like in Super Mario Bros 2, and the list goes on and on.

For what is worth, as far as I can tell platform + solid currently works pretty well anyways, except on this case (on a moving platform, wich on most games it probably would be considered a rare case)
B
26
S
7
G
1
Posts: 71
Reputation: 2,072

Post » Tue Jul 04, 2017 5:56 am

Ashley wrote:There is no obvious way to fix this problem, because we have to tick the behaviors in some order. Any changes we make would just move the problem somewhere else. If we sort by the object name and tick in that order, then renaming objects can change the tick order. If we tick in the order objects were created in the editor, then deleting and recreating an object can change the tick order. There's no gold standard tick order that is the "correct" one. I am also against letting the user customise the tick order; micro-managing such obscure parts of the engine is the exact opposite of the design principles that has made Construct successful.


Sure there is. In the Quake engine derived games, moving brushes used a special movement called MOVETYPE_PUSH. MOVETYPE_PUSH entities were responsible for pushing other entities if they were in the way, as well as moving entities that were resting on top of them. Adopting this to Construct 2 would require a few changes (such as being able to specify which objects can be "pushed"), but If you did this, and added a recursive check to it, developers would get the result they want, and the tick order wouldn't matter at all.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Tue Jul 04, 2017 11:33 am

I am sure there are a number of non-obvious dependency chains, and if they are accidentally set in a circle of dependencies then that cannot be resolved. If you carefully design a game to use the correct attributes on the right kinds of objects as intended then sure, that works, but this is more an issue when you throw in a bunch of objects with various behaviors in a random combination and find there's a tick order dependency somewhere.
Scirra Founder
B
387
S
230
G
87
Posts: 24,248
Reputation: 192,238

Post » Fri Jul 14, 2017 6:31 pm

Platform and Solid are not officially supported? Image, That's a bit strange that construct 2 is shipping with features that are not officially supported in a presumably Full product
B
22
S
11
G
33
Posts: 54
Reputation: 18,435

Post » Fri Jul 14, 2017 7:01 pm

It is a pretty big issue as projects grow bigger and I am sure there is no need to remind you that people are still working on their years long projects started with C2. Which explains why symptoms like this are being reported now .
Working on creating MYTHS, a 2D sidescroller adventure game - check more at :
nativepixels.com
Image
B
20
S
4
G
1
Posts: 11
Reputation: 1,547

Previous

Return to Bugs

Who is online

Users browsing this forum: No registered users and 0 guests