Pages: 1
  Print  
Author Topic: Instance System 3  (Read 1332 times)
Offline (Male) Josh @ Dreamland
Posted on: March 31, 2010, 12:38:30 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2949

View Profile Email
R4's new instance system is going to require a slight amount of -further- rethinking.

Over R3's system, the new system is intended to implement a few things that probably should have been done from square one, honestly. The highlights of these are as follows.

For the first revision, a few half-contemplated changes were implemented:
  • Depth was accounted for by mapping/listing draw events by depth, then in a second, subset container by ID.
  • Events were added to their own lists, one for each event classification.
  • An option was added to determine the return type of instance_* functions.

The implications and philosophies of each are this:
Depth: This was a reasonably poor idea, though it seemed like the best thing to do at the time. The newer system was floating about in my head, but I rejected it for the time due to lack of apparent need.
Events: Storing events in their own linked lists allows for iteration and execution that will not slow down based on a number of empty particles. Tests on Game Maker seem to indicate that it does the same thing. Overall, one of Mark's better ideas, IMO.
Option: In theory, this will allow for constant-time member access with return values from the instance_* functions. Note that instance_nearest and the like will still require O(N) iteration (details outlined in newer proposals below).


Further thought, especially on how to handle GM inheritance, was given since, leading to further ideas:
  • Depth should be determined not by the order of instances in the main map, but rather by the order of pointers in the draw event queue.
  • Instances will instead (of being sorted by depth) be stored in separate arrays by object_index. This array will be static, so defrag-IDs will be your friend.

The former revision will free organization method for the latter.
This will vastly improve performance of, for example, instance_nearest(x,y,object0), since only one list will need iterated for object0. The entirety can still be iterated at little cost. What's more, heredity can be achieved using this method by having each object, on instantiation, add itself to all concerned lists.

For example, a call to instance_nearest(x,y,someparent) will iterate the list of objects having ID "someparent," which will contain a pointer to all children of "someparent" as well.

I can only imagine this is what Game Maker does. However, if you think you have an instance where this method (referencing all children in a list of the parent) would break some form of compatibility with GM, please verify it and inform me.


Potential problems with any of the above:

- A problem could result from treating too many scenarios as pointers instead of GM-IDs. The most obvious of thees is in room-given instance IDs. Many room create codes reference other objects in the room by integer-index ID. Failing to store the IDs and to offer a look-up by them could break that system. As such, it should certainly be kept as an option and defaulted to false.

- A problem could result from storing by object_index: redundancy in iterating all objects as a whole. For this reason, a separate container may be needed to store a continuous list.
« Last Edit: March 31, 2010, 12:41:27 am by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Female) IsmAvatar
Reply #1 Posted on: March 31, 2010, 10:34:00 am

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
I'm not completely sure about half of what you said, but depth arbitration in GM is actually not performed by the ID, but rather by a "last touched" index. For example, placing 2 instances of the same Depth value in a room will cause the higher ID one to appear in front, not because it has a higher ID, but because it was placed more recently. If you grab the back instance, and place it again, without changing the ID, it will now assume drawing in front. Furthermore, deactivating and reactivating instances, while not changing their ID, nor their Depth value, does change their locations in the "last touched" index and thus changes when they are drawn (a discovery by yours truly, from years back. I reported it as a bug, way back when, but Mark never addressed it).

This behavior is wonky, not well-defined, and not documented, and anybody who depends on it is depending on undefined behavior. so I'd highly encourage replacing it with a more stable system. Some game devs might get confused because their depth arbitration is treated different in enigma, but that's simply because, like I said, they were relying on undefined behavior in the first place. Whatever the case, there should be an easy and well-defined way to automate the conversion from the current GM system (depth variables) to whatever the new system will be.
Logged
Offline (Male) Josh @ Dreamland
Reply #2 Posted on: March 31, 2010, 10:38:35 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2949

View Profile Email
Certainly. The behavior will be the same in ENIGMA.
On construct, the instance will add its draw event to the container at [depth]. It will be at the end of this list, and so will be executed last, as in your "last touched" method.

That's all that really defines this behavior. It'll perform the same, aesthetically.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Pages: 1
  Print