Overview
Artifact ID: | 87c6128caaeea8f49a2366c17771f732e49bab5c |
---|---|
Page Name: | Compatibility notes |
Date: | 2020-12-05 08:05:53 |
Original User: | anonymous |
Parent: | 0a96b80dfd2bf534f5f996abe93a83add8fcc052 (diff) |
Content
Here are various notes about compatibility with Hero Mesh, determined by various tests to see what behaviour occurs, and then make the hypothesis and another experiment to test it, to see if it is good or not (the scientific method).
- If there is a quiz popup, then the BEGIN_TURN and END_TURN messages are not sent on that turn.
- Setting Arrived/Departed sets whether or not the ARRIVED and DEPARTED messages are received, although only the low 24-bits are readable. All bits are used when setting though; if it is set to a nonzero value (whether or not any of the low 24-bits are set), then the message will be sent, and if set to zero, then the message is cancelled.
- The From argument to the BEGIN_TURN message is the last object found with the Player flag.
- Jumping doesn't seem to affect OF_MOVED (it doesn't send the MOVED message). Probably, it is instead set at the "movesuccceeded" label.
- To broadcast to all objects, specify 0 as the class, not -1.
- Broadcasts (as well as the INIT and POSTINIT messages automatically sent) send the messages to objects in the reverse order of their creation (the most recently created object receives the message first).
- The FlushObj() function clears Arrived, Busy, Inertia, Moved, and UserSignal. It does not clear Distance, KeyCleared, or UserState.
- If inside of a ForEachObjAt block, it calls recursively the same block even if in another object of the same class, it will not continue, presumably because it stores the coordinates and up flag together with the P-code (like arrays do); in Free Hero Mesh we can allocate a global variable for this.
- Destroyed objects can't receive messages (although if any message block that has already been called will continue to execute).
- HeightAt (and probably also VolumeAt) ignores objects with the VisualOnly flag set (and probably also objects with Destroyed flag set).
- Destroyed objects won't move (perhaps this is checked in the internal MoveTo() function), and always returns 0 (failed).
- POSTINIT message is sent evento an object which is created during INIT. (However, since broadcasts are in the reverse order of creation, creating an object during POSTINIT will not cause the new object to receive a POSTINIT message.)
- Create: Destroying the object blocks MSG_CREATED and other messages. If the object is destroyed before Create returns, then it returns zero.
- FLOATED messages are sent in order from bottom to top, presumably using ObjAbove; moving the object uses the above the new location.
- If the object moving is VisualOnly, then MoveTo() won't send the SUNK/FLOATED messages to any objects. (This does not apply to created objects; if you create an object and set it VisualOnly in the MSG_CREATE block, it will still send the SUNK/FLOATED messages.)
- The trigger phase that sends ARRIVED/DEPARTED/MOVED messages is bottom to top, and it seems to remember the list of objects; perhaps, at each location, make a list of objects at that location, before sending any messages.
- Broadcasts do not count objects that do not contain any message blocks, nor are objects with the OF_DESTROYED flag counted. (Perhaps, when OF_DESTROYED is set, also remove the object from the linked list of objects.)
For moving objects (with the Move command), here is a separate list specifically for that:
- If you use Move(Self,constant_direction) then instead of Inertia=Strength it does Inertia+=Strength. In Free Hero Mesh, this is handled in the converter, which when finding such an instruction in the P-code, decompiles it into a different instruction due to this different behaviour.
- ObjF seems to be found just after the "restart:" label (prossibly at the beginning of the "if dir is" blocks, since the logic to find ObjRF and so on will differ). The "for( each object at ObjF's location )" actually starts at the topmost object (ObjF), and then on each iteration, looks below (as the ObjBelow() function does). Probably this is also true of ObjR, ObjRF, etc. Changes to LastDir have no effect on this movement, and LastDir is not reset if the move is restarted.
- Also at the "restart:" label, when ObjF is found, it also computes and remembers HeightAt(ObjF.Xloc,ObjF.Yloc). This is used rather than ObjF.Height below (this seems to be a mistake in the documentation).
- Skip shoving if target is VisualOnly (or Destroyed, probably).
- Where it says "if( EachObj.Height > 0 )", it probably should be "if( EachObj.Height > 0 AND (NOT obj.VisualOnly) AND (NOT obj.Destroyed) )"; note that it checks the VisualOnly and Destroyed of the object trying to move, and not EachObj (if those flags are set for EachObj, then ObjBelow() will already skip that object).
- The documentation for HSG_HIT says that bit15 is reserved. Its actual effect is as described in the pseudocode for the internal Move() function, but also see above about the "restart:" label.