Difference between revisions of "Alone in the Dark (1-3)/Game Mechanics and Glitches"

From SDA Knowledge Base

Jump to: navigation, search
m (STAIRS/TRANSITIONS)
m (STAIRS/TRANSITIONS)
Line 1,193: Line 1,193:
 
** Can't get any kind of lamp turns to happen during the E1R6 transition.
 
** Can't get any kind of lamp turns to happen during the E1R6 transition.
  
* The staircase rotate command takes 2 seconds to finish regardless of how large the angle to cover is. This means it's never faster than manual turning.
+
* The staircase rotate command takes 2 seconds to finish regardless of how large the angle to cover is. This means it's never faster than manual turning, unless you were using the push action to move.
  
* You can speed up the TRACK-governed turns like with rotating doors. It calls the same internal function and uses Timer 2.
+
* You can speed up or revert the TRACK-governed turns with s/l manipulation like with rotating doors etc. More under "timers".
  
 
* The PC always turns around the way that's faster when needing to rotate to go up or down stairs, after any preceding turns have finished.
 
* The PC always turns around the way that's faster when needing to rotate to go up or down stairs, after any preceding turns have finished.
Line 1,201: Line 1,201:
 
* The disabled collisions in stairs doesn't prevent collisions with pushable objects, meaning you could get stuck in E3R11 for example if you put a chair inside the stairwell. Doing that doesn't seem to have any interesting effects anyway.
 
* The disabled collisions in stairs doesn't prevent collisions with pushable objects, meaning you could get stuck in E3R11 for example if you put a chair inside the stairwell. Doing that doesn't seem to have any interesting effects anyway.
  
* Taking the north stairs or south stairs down from E2 activates the same TRACK.
+
* Taking the north stairs or south stairs down from E2 has exactly the same effect.
  
 
* When observing the Y-position at a given horizontal position when entering the staircase in the same way multiple times, slight differences are seen in the exact positions. Probably to do with lag.
 
* When observing the Y-position at a given horizontal position when entering the staircase in the same way multiple times, slight differences are seen in the exact positions. Probably to do with lag.
Line 1,207: Line 1,207:
 
* Jumping into a staircase (and generally moving into them with uninterruptable ANIMs) makes the player move deeper in before assuming normal stair-climbing movement. This means you can jump through the E5R0 trigger to clear the stairs quickly (and without risk of getting turned back). The keyframe you were on when you hit the trigger is incremented and the movement resumes from the start of the next keyframe, meaning you're losing a bit of time if you don't skip most of any slow keyframe that you had just entered.
 
* Jumping into a staircase (and generally moving into them with uninterruptable ANIMs) makes the player move deeper in before assuming normal stair-climbing movement. This means you can jump through the E5R0 trigger to clear the stairs quickly (and without risk of getting turned back). The keyframe you were on when you hit the trigger is incremented and the movement resumes from the start of the next keyframe, meaning you're losing a bit of time if you don't skip most of any slow keyframe that you had just entered.
 
** The same applies more broadly on any transition, but the other critical example is E5 going through to E4 which is also slow if you don't jump through.
 
** The same applies more broadly on any transition, but the other critical example is E5 going through to E4 which is also slow if you don't jump through.
 
* Climbing the E1R6 stairs: If you try to, e.g. enter the staircase from the side while facing a weird angle, it'll first do a 360 trying to get to set coordinates. It can even softlock without you ever reaching it, esp. if you lag the game a lot.
 
  
 
* Extra stairs movement from lag: If you lag the game on the last few frames right at the end of the transition, it causes you to move forwards further compared to no lagging. This is because of the last few commands in the TRACK normally being executed very quickly but this way you're drawing them out.
 
* Extra stairs movement from lag: If you lag the game on the last few frames right at the end of the transition, it causes you to move forwards further compared to no lagging. This is because of the last few commands in the TRACK normally being executed very quickly but this way you're drawing them out.
 
** A difference of around 300 units has been observed, though this may vary.
 
** A difference of around 300 units has been observed, though this may vary.
  
* Whether you press right or left when jumping up the stairs from E5, the game rotates you cw at the top. Just ONE time got it to rotate ccw somehow (I thought I was hitting down and/or left on the keypad). This effect is the same if you're just walking up and getting a lamp snap or just starting to turn at the top. It's the only set of stairs leading up that hasn't got two parts or a warp towards the end, which might explain why it's possible to do this there but nowhere else.
+
* If you're holding down right or left when jumping up the stairs from E5, the game rotates you cw at the top. This effect is the same if you're just walking up and getting a lamp snap or just starting to turn half-way through. The transition seems to always start this rotation right as you're reaching the end since you're not perfectly aligned with the target point, and holding the rotation bind just makes that turn continue.
 
** If you try doing a slt during the erroneous turn, you can complete the quadrant by holding the same wrong (left) button down whereas holding the other one doesn't do anything.
 
** If you try doing a slt during the erroneous turn, you can complete the quadrant by holding the same wrong (left) button down whereas holding the other one doesn't do anything.
** If you lag while coming up the stairs to E3R11, it might also turn you right before the track finishes with no other requirements, suggesting this is just something that happens at the top of that staircase. This makes some sense seeing as there might just be a little bit of rotation before the game has hit the target.
 
 
* Even though you can do it right at the start of going into stairs like anywhere, you can't seem to be able to abuse s/l snapback to move backwards and up after triggering stairs with gravity on to cause falling, probably because the interpolation doesn't start until the ANIM has changed and then it's too late.
 
** The command that has to have started is "walk stairs". By that point, in every staircase track, your SPEED will have changed to 4. SPEED 4 is associated with the walk_stairs ANIMs (or crawling) during transitions, so the ANIM must have changed from whatever it was before.
 
** Even if you kept the erroneous walk_stairs ANIM (holding SPACE) and somehow managed to turn around to get back into the E3R11 stairs, you have the wrong stairs ANIM and so it'll change anyway. Furthermore the SPEED during the erroneous walk is 0, not 4 or 5.
 
  
 
* Sometimes you'll be sent back down the E3R11 stairs after climbing them.
 
* Sometimes you'll be sent back down the E3R11 stairs after climbing them.
** Sometimes you get a 30-unit offset from (850, 0, 50) to (820, 0, 49) before the climb has started when coming up the E3R11 stairs. This happens on the frame the TRACK advanced to position 1 (it has just disabled triggers). Because the start position is not stored until after this has happened, it explains why you'll end up at different positions at the end. There's probably things like small amounts of global lag also involved though, and possibly which SPEED you had when entering the staircase. Other staircases probably behave in a similar way, but E3R11 just happens to allow the climb to finish on (900, 0, 50) where you're inside the upper stairs trigger sending you back down.
+
** Sometimes you get a 30-unit offset from (850, 0, 50) to (820, 0, 49) before the climb has started when coming up the E3R11 stairs. This happens on the frame the TRACK advanced to position 1 (it has just disabled triggers). Because the start position is not stored until after this has happened, it in part explains why you'll end up at different positions at the end. There's probably things like small amounts of global lag also involved though, and possibly which SPEED you had when entering the staircase. Other staircases probably behave in a similar way, but E3R11 just happens to allow the climb to finish on (900, 0, 50) where you're inside the upper stairs trigger sending you back down.
 
** You're sent back to E5 the more frequently the higher the framerate regardless of anything, since this means you're less likely to skip a position due to lag.
 
** You're sent back to E5 the more frequently the higher the framerate regardless of anything, since this means you're less likely to skip a position due to lag.
 +
** If the framerate is high enough, the E1R6 stairs can behave similarly.
  
* There is a way to interrupt a transition. It's based on this: in the middle of a transition, you hit a door (use lag and Timer 2 manipulation to get to one). Collisions with actors can still happen and so it should cause the door to open. Afterwards, you are restored control and so MOVE changes. The TRACK is never completed. You're left with the wrong ANIM_MOVE and cannot access your inventory but you might also be left without collisions. This is basically useless without triggers being active though, and only going between E0 and E1 are there transitions where triggers are re-enabled before collisions, meaning you could, in theory, interrupt the TRACK just before collisions are back on.
+
* There is a way to interrupt a transition. It's based on this: in the middle of a transition, you hit a door (use lag and Timer 2 manipulation to get to one). Collisions with actors can still happen and so it should cause the door to open. Afterwards, you are restored control and so MOVE changes. The TRACK is never completed. You're left with the wrong ANIM_MOVE and no INV but you might also be left without collisions. This is basically useless without triggers being active though, and only going between E0 and E1 are there transitions where triggers are re-enabled before collisions, meaning you could, in theory, interrupt the TRACK just before collisions are back on to no-clip around afterwards.
 
** If you get past the target point to turn back around (especially doable with gravity on in many places), you can definitely reach nearby doors unless the falling prevents the right kind of collision from happening. After hitting the door, if you need to get back up or go further down to reach the target point just in time, you can just manipulate Timer 2 to prevent the door from fully opening too soon.
 
** If you get past the target point to turn back around (especially doable with gravity on in many places), you can definitely reach nearby doors unless the falling prevents the right kind of collision from happening. After hitting the door, if you need to get back up or go further down to reach the target point just in time, you can just manipulate Timer 2 to prevent the door from fully opening too soon.
** Going out of the way to hit a door (might only work if you're not falling?) is a significant time investment and you don't want to do this before reaching E3 anyway. You could try to do it going back towards E2 instead of descending the E3R5 stairs. The desk is going to block you in E3R11 unless you end up being above it, but at that point you might not be able to reach the lighter in R13.
 
 
** You can't do anything with this in E3R11 seeing as how are you going to get to E5 if the track doesn't complete? TRACKPOS -1 is what triggers the room warp.
 
** You can't do anything with this in E3R11 seeing as how are you going to get to E5 if the track doesn't complete? TRACKPOS -1 is what triggers the room warp.
** The only other seemingly useful effect is being left higher up or down than usual. If you have triggers left on, you could then hit certain triggers like the E3R11 stairs trigger despite the desk being there, but this is about as good as it gets, unless you can get up to -3750 exactly at which point you can pass over walls inside the house but still activate triggers.
+
** The only other seemingly useful effect is being left higher up or down than usual. If you have triggers left on, you could then hit certain triggers like the E3R11 stairs trigger despite the desk being there, but this is about as good as it gets, unless you can get up to ROOM Y -3750 exactly (!) at which point you can pass over walls inside the house but still activate triggers.
** The better approach to this is probably to start opening a door first, then get knocked back so you're freed. Now trigger the transition while delaying the door opening until you're on a suitable step of the TRACK. There are no TRACKs that disable collisions before triggers unfortunately so you can't noclip this way.
+
** The better approach to this is probably to start opening a door first, then get knocked back so you're freed. Now trigger the transition while delaying the door opening until you're on a suitable step of the TRACK. There are no TRACKs that disable collisions before triggers unfortunately so you can't noclip this way by interrupting the transition at the start.
** If you could somehow move about the place without collisions, because this is implemented in its strange way (player is always seen as colliding with collider 0), you could at least hit certain colliders and e.g. pick up the talisman this way.
+
** If you could somehow get into this no-clipping state with triggers left on, because this is implemented in its strange way (see "TEST_COL"), you could at least make the game think you're hitting collider 0 and e.g. pick up the talisman this way.
  
* Moving between E5 and E6 doesn't set your facing like the other transitions.
+
* Moving between E5 and E6 doesn't set your facing like the other transitions do.
  
 
* If you have control but don't lose the TRACK movement in a staircase, you can sort of control your direction if you have a MAN_ROT action and hold space while a turn has just started.
 
* If you have control but don't lose the TRACK movement in a staircase, you can sort of control your direction if you have a MAN_ROT action and hold space while a turn has just started.
** To get into this kind of state is probably impossible. LIFE 550 sets INV and VAR 0 to 0 at the same time as well as switching to MOVE TRACK so you'd have to be able to affect just VAR 0 while in LIFE 550 without also setting MOVE. This doesn't seem to ever happen. Using the INV + control restoration after throwing in LIFE 549 is no good because then you're not in LIFE 550.
+
** To get into this kind of state without cheating is probably impossible. LIFE 550 sets INV and VAR 0 to 0 at the same time as well as switching to MOVE TRACK so you'd have to be able to affect just VAR 0 while in LIFE 550 without also setting MOVE. This doesn't seem to ever happen. Using the INV + control restoration after throwing in LIFE 549 is no good because then you're not in LIFE 550.
  
* You can lag the game when you enter E5 through E4, before you've rotated S, and get Emily to enter the wall on the side. If you move directly to the E, it seems you can get to X 125. This leaves you inside the trigger and sends you back to E4. However, if you could avoid being in the trigger (easy if you were facing an angle like 89 degrees) and also got to X 152, you could now run through the wall OOB, presumably acting as a shortcut compared to other routes.
+
* You can lag the game when you enter E5 through E4, before you've rotated S, you can get Emily to enter the wall on the side. If you move directly to the E, it seems you can get to X 125. This leaves you inside the trigger and sends you back to E4. However, if you could avoid being in the trigger (easy if you were facing an angle like 89 degrees) and also got to X 152, you could now run through the wall OOB, presumably acting as a shortcut compared to other routes.
** The X-position always ends up being 125 at furthest (the offset is 425, on kf2 or kf3 of crawling). If SPEED was 5, the ANIM would be walking instead, but that ANIM's kf's are all slower anyway.
+
** The X-position always ends up being 125 at furthest (the offset is 425, on kf2 or kf3 of crawling). If SPEED was 5, the ANIM would be walking instead, but that ANIM's kf's all have a smaller offset anyway.
 
** Several frames will pass between SPEED being set to 4 in TRACK 40, and the player getting to E5, thus you can't possibly be in your running ANIM after the transition. It doesn't look possible to get further into the wall. Going the other way around, the distances to the walls are even greater with similar code preventing having SPEED 5.
 
** Several frames will pass between SPEED being set to 4 in TRACK 40, and the player getting to E5, thus you can't possibly be in your running ANIM after the transition. It doesn't look possible to get further into the wall. Going the other way around, the distances to the walls are even greater with similar code preventing having SPEED 5.
 
** If you jump through to E4 instead, if you have kf 5 after the warp and an angle of 180 (+-3.2) degrees, you can lag the game to get to Z 5925. This isn't quite enough to run through the N wall, for which you'd need Z 5953. There seems to be no way to get any further as you're immediately turned to face the W afterwards.
 
** If you jump through to E4 instead, if you have kf 5 after the warp and an angle of 180 (+-3.2) degrees, you can lag the game to get to Z 5925. This isn't quite enough to run through the N wall, for which you'd need Z 5953. There seems to be no way to get any further as you're immediately turned to face the W afterwards.
** What does work is if you first make sure the barrels have been moved, jump through to E4, start to rotate as soon as you can (kf 3 works), do two slt's to face E while keeping the same kf, and lagging the game once through again. You may have to face due E as you go through but possibly not. Now you just lag after the transition and you should go far enough into the wall to get OOB. You can even drop something at the end of the jump to get the hover if desired.
+
** What does work is if you first make sure the barrels have been moved, jump through to E4, start to rotate as soon as you can (kf 3 works), do two slt's to face E while keeping the same kf, and lagging the game once again. You may have to face due E as you go through but possibly not. Now you just lag after the transition and you should go far enough into the wall to get OOB. You can even drop something at the end of the jump to get the hover if desired.
  
 
* After entering a staircase, if the warp is immediate, the residual movement from the previous ANIM can cause you to move sideways after the warp, which can in turn cause you to enter a rotation during the transition. This could enable you to end it OOB even if it otherwise wasn't possible. It might be better to walk into the trigger instead of running because more residual movement is kept this way as the SPEED rolls down to 3-2-1-0. The movement you get also depends on what part of the walking ANIM you were in at the time.
 
* After entering a staircase, if the warp is immediate, the residual movement from the previous ANIM can cause you to move sideways after the warp, which can in turn cause you to enter a rotation during the transition. This could enable you to end it OOB even if it otherwise wasn't possible. It might be better to walk into the trigger instead of running because more residual movement is kept this way as the SPEED rolls down to 3-2-1-0. The movement you get also depends on what part of the walking ANIM you were in at the time.
** E0-E1: Because the stairs descent ANIM only has a speed of 238 (all kf's), the player can only just barely get (1-unit margin) far enough into the thick E wall to pass through if they start from a position right next to the wall. Even if you use the residual movement to get to X 15 (next to the wall), you now surely cannot turn to face the E during the transition without at some point being W of the target X point (0). Thus this should be impossible to do.
+
** E0-E1: Because the stairs descent ANIM only has a speed of 238 (all kf's), the player can only just barely get (1-unit margin) far enough into the thick E wall to pass through if they start from a position right next to the wall. During the transition, even if you use the residual movement to get to X 15 (next to the wall), you now surely cannot turn to face the E during the transition without at some point being W of the target X point (0). Thus this should be impossible to do.
 
** E1-E0: Because of the warp command at the foot of the stairs, your starting position seems to be set in stone more or less. So there should probably be no sideways movement available during the climb (SPEED 0 is even issued before the warp).
 
** E1-E0: Because of the warp command at the foot of the stairs, your starting position seems to be set in stone more or less. So there should probably be no sideways movement available during the climb (SPEED 0 is even issued before the warp).
** E1-E7: Doesn't seem to work because you're always dragged to Z 250 no matter what.
+
** E1-E2: Doesn't seem to work because you're always put at Z 250 no matter what.
** E2-R1: The target points seem too far away from the walls.
+
** E2-R1: The target points seem too far away from the walls to end up OOB.
** E2-E3: Can be done easily but there's nowhere to lag to near the foot of the stairs.
+
** E2-E3: Can be done easily but there's nowhere to lag OOB to near the foot of the stairs.
 
** E3-E2: No walk stairs command in E2, there's a rotation first, then warp, so no chance.
 
** E3-E2: No walk stairs command in E2, there's a rotation first, then warp, so no chance.
** E3-E4: The W wall is just too far.
+
** E3-E4: Here it IS possible to use a long series of lagging (and timer manipulation) to eventually end up at the foot of the stairs but outside the room.
 
** E4-R3: No walk stairs command in E3, there's a rotation first, then warp, so no chance.
 
** E4-R3: No walk stairs command in E3, there's a rotation first, then warp, so no chance.
 
** E3-E5: Can get some residual movement this way but seemingly only towards the SE.
 
** E3-E5: Can get some residual movement this way but seemingly only towards the SE.
** E5-E3: Nowhere useful to go without a massive amount of manipulation to get through to R13 during the transition.
+
** E5-E3: Your position at the foot of the stairs is set.
 
** E5-E6 (either exit): Collision flag is never switched off anyway.
 
** E5-E6 (either exit): Collision flag is never switched off anyway.
 
** E6-E5 (either exit): Collision flag is never switched off anyway.
 
** E6-E5 (either exit): Collision flag is never switched off anyway.
 +
 +
* In the E3-E5 transition, you could bypass the locked door. The method would involve using the natural rotation at the top of the stairs (since your position and angle are otherwise set), and just lagging and timer-reverting a lot of times so you keep moving directly N without the transition quite being able to finish. This seems extremely slow.
  
 
* When running into the E1 stairs, if you save on the frame after the next floor has been loaded in, reload, and immediately lag the game, you can get a snap that wouldn't otherwise be possible. This isn't really useful since you just need a little bit of offset at the top of the stairs to manipulate turning to the side near the bottom, which is enough to get OOB (even if it wasn't possible otherwise).
 
* When running into the E1 stairs, if you save on the frame after the next floor has been loaded in, reload, and immediately lag the game, you can get a snap that wouldn't otherwise be possible. This isn't really useful since you just need a little bit of offset at the top of the stairs to manipulate turning to the side near the bottom, which is enough to get OOB (even if it wasn't possible otherwise).
Line 1,262: Line 1,257:
 
*** E2-E3 (don't even have to save)
 
*** E2-E3 (don't even have to save)
 
*** E3-E4
 
*** E3-E4
*** E4-E5 (don't even have to save but doesn't get you far enough)
+
*** E4-E5 (don't even have to save but doesn't get you far enough by itself)
 
** Not possible:
 
** Not possible:
 
*** E1-E2
 
*** E1-E2
Line 1,272: Line 1,267:
 
* If you could interrupt the transition from E4 to E5, you could probably get the gravity flag to stay on in E4 this way. Furthermore, this should result in jumping being possible inside the house. However, this should be impossible to do since there's no doors in E4 and seemingly no other code that could interrupt the transition.
 
* If you could interrupt the transition from E4 to E5, you could probably get the gravity flag to stay on in E4 this way. Furthermore, this should result in jumping being possible inside the house. However, this should be impossible to do since there's no doors in E4 and seemingly no other code that could interrupt the transition.
  
* You can use a lowered framerate to cause goto and walk stairs commands to end a bit further (if the first position that could have cause this to happen is skipped due to lag).
+
* You can use a lowered framerate to cause goto and walk stairs commands to end a bit further regardless of how quickly the last commands in the TRACK are executed afterwards (if the first position that could have cause this to happen is skipped due to lag).
** The theoretical limit to the difference in the position you end up in going up or down stairs should be no greater than the horizontal movement that corresponds to a Y-difference that makes you completely miss the target point (past this, you'll simply turn back or walk indefinitely). Of course you'd need the slope to be very steep for this to be possible. In practice a difference of around 350 has been observed after brief testing.
+
** The theoretical limit to the horizontal difference in the position you end up in going up or down stairs should be no greater than the horizontal movement that corresponds to a Y-difference that makes you completely miss the target point (past this, you'll simply turn back or walk forwards indefinitely due to the indecision bug). Of course you'd need the slope to be very steep for this to be possible. In practice a difference of around 350 has been observed after brief testing.
 
** You shouldn't be able to do anything with this, presumably, that wasn't possibly by lagging the game at specific times, but this is difficult to prove.
 
** You shouldn't be able to do anything with this, presumably, that wasn't possibly by lagging the game at specific times, but this is difficult to prove.
  
* Stairs don't use modX/Y/Z values, instead setting the coordinates directly. This suggests that any sudden snap, such as a lamp snap, shouldn't be possible in them, at least not based on the same mechanism.
+
* Stairs don't use modX/Y/Z values, instead setting the coordinates directly. This suggests that any sudden [forwards] snap, such as a lamp snap, shouldn't be possible in them, at least not based on the same mechanism.
  
 
* The stairs ANIMs have a "pulse" of about 80 frames so each step takes 0.75 seconds.
 
* The stairs ANIMs have a "pulse" of about 80 frames so each step takes 0.75 seconds.

Revision as of 12:41, 14 July 2019

Contents

Alone in the Dark 1

ABOUT THE GUIDE

  • Most of the information here is derived from testing the English CD-ROM version (GOG). If you want to study AitD 1 more, you should consider using a different version, since no other version has been tested nearly as thoroughly. The French CD version in specific is a good choice because of reasons explained under "known version differences".
  • Mostly Emily was used in testing, there being no known reasons to go with Edward in a speedrun.
  • The division into topics is sometimes quite arbitrary. Feel free to discuss the format on the discussion page (top left) so future guides may be better-organized. That having been said, to get well-enough versed in the game's/games' workings to be able to competently run them or build on the theory, you will have to cut through a very decent portion of the guide regardless of its exact structure.
  • Inevitably some points are made more than once so edits should ideally happen in both, and even more vague and more detailed bullets may be given on the same topics. The notes were generally made from a segmented run's point of view, being able to abuse saving and loading at will with the small natural penalty segmented runs incur for this. Some save/load tricks may sound too optimistic though, and this is because I (LotBlind) made the false assumption the time in the menu before reaching the save menu would not be counted (which would have meant the penalty was diminutive).
  • Because of some issues with file conversions, I may have been working with files that were at 25 FPS instead of 60 FPS (what you should use) sometimes when counting frames between events happening. Thus there may be a small amount of incorrect frame counts given in the guide. Please report this and any other mistakes.
  • Feel free to contact the primary author of the guide (LotBlind) or tigrou (code-related and more technical questions) through the SDA forums for consultancy during any serious [speedrunning] endeavours. Also the guide is in a wiki format for a reason: it may be edited by anyone. Use the discussion page for relevant questions.

GLOSSARY

Game-internal terms

Game-internal terms Meaning
object the entities in the OBJETS.ITD file that have properties like BODY, LIFE, FOUNDLIFE etc., but in the guide this may have been used in the everyday sense as well
actor refers to any object that has been moved into the active actors' array in the RAM, but may have been confused with objects in some places
FRAME the game uses this to refer to keyframes, confusingly
TRACK pre-scripted movement, defined in LISTTRAK
BODY 3D models defined in the LISTBODY and LISTBOD2 files
ANIM animations defined in the LISTANIM and LISTANI2 files
LIFE the game's scripts are called LIFEs. The term "script" has been used sometimes. Stored in a file called LISTLIFE.
LIFE_MODE called LIFEMODE in the guide, determines if an actor is active at a given time based on focused actor location
MOVE movement mode
TRACK_MODE/TRACKMODE deprecated term for "MOVE"
animActionType an actor field, ACTIONTYPE in the guide
HIT This is all of: a possible actor ACTIONTYPE field value; the name of the command that causes an actor to enter the PRE_HIT and HIT ACTIONTYPEs (in the LIFEs); and an actor field that stores the ID of the actor that has just been HIT by it.
IN_HAND the item currently equipped, e.g. a weapon
VAR/CVAR the variables and constant variables the game writes into during gameplay
ExRy floor and room, as given in the game files and shown in the Room Viewer
TYPE Sets the flags for the actor in question. Replaced with the word "FLAGS" by LIFEDISA.
Example Example
Additional terms Meaning
focused actor actor that was set as the CAMERA_TARGET, usually the PC
PC player character
EM/ED Emily/Edward
"having control" VAR 0 being 1
INV ALLOW_INVENTORY = inventory being accessible
OOB [to go] out-of-bounds (verb, noun, adjective...)
IB in-bounds
desync by default means desync of the ZV and ROOM Y-coordinates from their normal difference = vertical desync
kf keyframe inside an ANIM
subframe really sub-keyframe (one frame within a keyframe: what's normally called a "frame")
hitbox the box that is used to check whether a melee attack is connecting with another actor, displayed in red in the RV
bbox bounding box (also known as "zv"): the box used for collision checks with other actors and colliders, displayed in green (or white) in the RV
transition the PC hitting a floor/transition trigger to move onto another floor
s/l save and reload the same file
slt save/load turn
ftt deprecated term "first-time turn" referring to an incomplete slt
Cx camera with ID x
ExCy camera on floor x with ID y
RV/Viewer Room Viewer
MV Memory Viewer
CV Cache Viewer
FitD Free in the Dark; a very accurate source port of Alone in the Dark.
HARD_COL abbreviation for HARD_COLLIDER
Example Example
  • LIFE, ANIM etc. numbers are given in the guide with a space in-between for clarity (ANIM 55, LIFE 112) even though in the scripts they're always spelled together. Also in the scripts CVAR is spelled C_VAR.
  • All of the VARs, CVARs, ANIMs, BODYs etc. were named by LotBlind and those names are, as such, unofficial. All the names were written into a file called vars.txt. The game doesn't come with human-readable names for most things, except for items that you pick up which have the names shown in-game. Even those are only referred to by their IDs in the code if vars.txt was not present during decompiling LISTLIFE.ITD.
  • Some variables and such may be referred to with different names/typography since during the project, tigrou may have renamed game-internal fields to be easier to understand, and in some cases, the original terminology was returned to afterwards. An attempt was made to conformize everything. Then again, the information is often too technical to get a perfect grasp of through this guide alone anyway.

META

USEFUL FILES

  • If you aren't sure where to find a particular file or program, look here.


DOSBOX/EMULATORS

  • While runs can only officially be recorded on whatever GOG or Steam copies are packaged with (unless the SDA rules have changed since writing this), other emulators may offer features beneficial to testing.
  • While it would make a big difference in lag times, you're not allowed to change the default GOG CPU cycles setting of 11.000.
  • If DOSBox has been left in the background while you're doing something else, it sometimes fails to refresh the window when you refocus it. Just minimize and un-minimize it until it shows right.
  • ALT-F12 in DOSBox fast-forwards the game. This is not supposed to affect its functioning.
  • DOSBox SVN-Daum has save states and other features that make it superior to DOSBox 1.4. It was not utilized at all.
  • The state of PCem as a TAS-ready emulator should be kept an eye on. It seems the most likely candidate that could actually allow to TAS AitD for TASVideos.org.

ROOM VIEWER

  • The Room Viewer (Viewer, RV) is a custom-made RAM watch utility coded by tigrou for Alone in the Dark series games that was gradually expanded on over the course of the segmented run project. Its functionalities are the widest in scope when used in conjunction with AitD 1. It comes with an attached readme for instructions but here are some additional notes as well.
  • The RV has a built-in function (hit the "1" and "2" keys) to quickly test the workings of the two timers by winding them back 5 seconds at a time, and get specifically Timer 2 closer to a desired value. The game state that results, however, is not the same one it would have been had the timer been reset by rebooting the game, and so this is definitely not allowed during actual running.
  • When recording runs and other material for AITD, please set up also recording two instances of the Room Viewer at the same time (one for the game world, one for the VARs), because this helps to analyse your work afterwards. In order to record both instances, you need two differently named copies of the Viewer. Recording your key presses will also help immensely. This can be done using NohBoard with THIS PRESET.

EDIT IN NOHBOARD AND THE PRESET FILE, MAKE SURE THE SECOND VERSION OF THE VIEWER IS PROVIDED?

    • You might also find this Windows .bat file handy:
      • ECHO "Remember Num Lock on!"

PAUSE start "" "AITD room viewer" -screen-width 960 -screen-height 720 -screen-fullscreen 0 -speedrun start "" "AITD room viewer 2" -screen-width 1627 -screen-height 360 -screen-fullscreen 0 -speedrun start "" "NohBoard\NohBoard.exe"

    • Just create a .bat file in the same folder as the .exes and that should work. Change the width and height to match your screen. The NUMLOCK reminder is there because NohBoard needs it to be on to see the keypad, but feel free to delete it. Also to make NohBoard see the inputs in the first place, you have to run it as administrator, which is a setting you can change through right-clicking and going to the compatibility tab.
    • "-speedrun" makes the Viewer use default settings that make recording speedruns etc. more convenient and consistent: for example always making sure the extra info is shown on the bottom right with the player actor being focused. It may also cause some data to be displayed that wouldn't be otherwise.
    • In order to avoid having to give every program permission to run separately, you can also just make a shortcut to the .bat file, and choose the "run as administrator" option for it.
  • The Viewer cannot follow the player around during the intro cutscene unless you manually go to the right rooms. This is because it's set to track the actor that has TRACK_MODE 1 (manual movement) that only the PC has during regular gameplay. The actors used in the intro and outro are actually different from the usual PC actor.
  • The Viewer's Model Viewer shows not only the BODYs but also can play ANIMs on top of them (indiscriminately). It also gives you the keyframe lengths and offsets.
  • The warp command, even when just changing the actor's angle, can desync its coordinates. If it's happened to the PC, it should be reflected on by a new red bbox being drawn where the ROOM coordinates are. To avoid this, you should pause the game or make sure the actor isn't moving when you warp it.
    • You can only get some actors (most monsters and all pushables) to move between rooms, not e.g. any room script actors.
  • The Viewer refreshes its memory (reads from the game process) at the same speed as your display refresh.
  • There may be very small (e.g. one-frame) delays before a changed memory value shows in the Viewer. This may explain why it sometimes seems things that are supposed to happen on the same frame do not. You shouldn't always read too much into discrepancies of this size.
    • The same goes for any keyboard visualizers you're using. I've seen the Room Viewer reacting to a key press before NohBoard did (which means the game reacted even quicker).
  • There's information that will only be displayed in the RV for the CD-ROM release of AitD 1. This includes everything to do with timers.
  • The delay/lag meter is set to only time instances of lag of over 100ms long (i.e. major loading lag). The total lag -counter, on the other hand, adds up everything.
  • The Room Viewer gives you back the player character's information automatically if the currently selected thing is clicked on again to deselect it. This is so speedruns etc. recordings are less likely to drop that information. However, if you never deselect that other entity before it's disappeared from memory (as when moving between floors), it will not revert to the player. This is because of another feature that's designed to make it easier to monitor some actor from the moment it's been loaded into memory. This is generally when you go back to the floor or area it's in.
  • SUB_KEYFRAMEs as shown in the RV are not reset when the game is reloaded. The field only exists in the RV, not in RAM.
    • Just in general, the RV does not directly know if the game has been reloaded.
  • There is another branch of the RV called "highlighting" that highlights changes in all or most of the actor fields etc. shown in its window like they are in the VARs mode. This was deemed to make the screen too busy, and thus removed from the master.
  • There are a few kinds of artifacts shown in the RV that look like the game glitches for a frame in a way that you can't see in the game's own window. Most of these are explained by the RV reading memory more frequently than the game updates it, thus showing mid-frame states as well as completed frame ones. The common trait is that you can't ever pause the game in the glitched state, which is how you can tell as well.

LIFEDISA/TRACKDISA/MEMORY VIEWER

  • The "DISAs" are the tools used to unpack the game's scripts and tracks and the Memory Viewer shows the game's entire RAM.

Instructions:

  1. Create a new folder.
  2. Unpack all files of LISTLIFE.PAK to that folder with quickBMS.
  3. Search for a file named "OBJETS.ITD" (in AITD root folder) and copy it there as well
  4. Unpack ENGLISH.PAK (or FRANCAIS.PAK if you have the French version). Search for a file named 00000000.dat. Rename it to "ENGLISH.TXT". Copy that file to the same folder.
  5. Copy LifeDISA.exe to the folder and run it.
  6. A file named "output.txt" with all scripts will be created.

The files ENGLISH.TXT and OBJETS.ITD allow the tool to convert objects' hard-coded IDs inside scripts (e.g.: 50, 201, 203) to human-readable names (e.g.: "A rifle", "A letter", "A key", ...). In addition, the file called vars.txt can optionally be placed in the same folder before running LifeDISA to replace a lot of other names as well, including all the ANIMs, LIFE names and VARs. This will make the output file more cluttered but a lot easier to understand.

  • After you have obtained output.txt, opening it with something like NotePad++ choosing "Assembly" as the language is recommended to make it even easier to read.
  • TrackDISA works the same, except it extracts the file called LISTTRAK.PAK that contains the game's TRACK scripts. vars.txt also helps make TrackDISA's output file easier to read.
  • The Memory Viewer reads the first two megabytes of DOSBox RAM (more than enough to see all of AitD's memory) and displays it using the in-game palette so that you can clearly see where the two background images and the backbuffer are stored. Launch the program before or after AitD and it should recognize when it's running. Give it admin privileges if DOSBox also has those.
    • The exact positions of items in the memory are dynamically allocated and so might not be exactly the same from time to time but they're always stored in the same order. In practice, if you launch the game the same way, the DOSBox RAM should also be identical.

CACHE VIEWER

  • A program that displays the contents of the cache in detail. Works best if launched after the game is already running. The data shown is as follows:

Bytes Used – Bytes Maximum ... Number of Entries – Maximum Number of Entries

Then for each entry (sorted by last access time): ID – Size – Timestamp

  • You have to use the following as arguments (case sensitive), depending on what you want to display:

ListSamp ListLife ListBody / ListBod2 ListAnim / ListAni2 ListTrak

    • You can combine up to five arguments. ListBod2 and ListAni2 are for Emily.

FREE IN THE DARK / FITD HACK

  • Free in the Dark is a very accurate source port whose history is unknown, though it is suspected someone might have had access to the AitD source in order to be able to make it. It is part of the reason so much is known about various aspects of how AitD works.
  • There is a hacked .exe for the "Free in the Dark" port of Alone in the Dark that makes it easier to study the render bug specifically (see "render bug"). It is capable of rendering 32000 units of the game world in a given resolution (e.g. 1080p) while the camera still uses the same 320x200 projection settings.
    • Just copy the files in your INDARK folder into the port's folder and you are good to go. If asked to overwrite SDL.dll or SDL_mixer.dll files, say no.
    • The .exe, like FitD in general, is not compatible with the Room Viewer.
  • FitD keys: T - top camera, C - no hard clipping, B - 3D mode, N - 2D mode.
  • Hack keys: +, -, * and /.
    • You can zoom with O and P, at least after you've hit B/N or T to give the top-down view.
    • The red lines are the -32768/32767 range (so 65536 values) to give an idea of when the 2D array should be about to overflow.
    • You can import a save file from AitD (FitD scans for SAVE0.ITD in its folder). This means you can first set up whatever situation you like in AitD with the help of the Viewer, then quickly copy-paste the resulting save file and resume inside the FitD hack to see what the full projection looks like.
  • FitD is very buggy...
    • In case the character suddenly starts to spin uncontrollably, you have to restart the program.
  • If you get "The procedure entry point SDL_getenv could not be located in the dynamic link library E:\GOG Games\Alone in the Dark\INDARK\FITD.exe", you have to make a backup of the DLLs in the INDARK folder and replace them with the ones in the zip.

GAME

GAME FILES

File - CAMERAXX.PAK All background camera images (in 320x200 8-bit 256 color). Can be opened in Photoshop etc. as RAW images.
ENDSEQ.PAK Various resources (e.g. backgrounds) related to the end sequence (after Pregzt is defeated).
ETAGEXX.PAK Room and camera information, used by the Room Viewer.
ENGLISH.PAK 00000000.dat is the English translation for the object names and also user interface/messages, the other files are the readables. There are also other language files with obvious names.
LISTANIM/LISTANI2.PAK 3D models' skeletal animation data. Can be viewed in the Room Viewer.
LISTBODY/LISTBOD2.PAK 3D models. Can be viewed in the Room Viewer.
LISTLIFE.PAK Scripts.
LISTMUS.PAK Music files in the ADL format.
LISTSAMP.PAK Sound samples (8000 Hz 8-bit mono VOC files). Can be opened in many audio programs like GoldWave.
LISTTRAK.PAK Pre-recorded 2D paths for actors (e.g. when climbing stairs).
PRESENT.PAK The screenshots shown in attract mode (let it idle in the main menu).
ITD_RESS.PAK Various GUI/gfx data (e.g.: menus, fonts...)
VARS.ITD The initial values of variables.
DEFINES.ITD The initial values of flags.
PRIORITY.ITD  ???
OBJECTS.ITD A table with all objects used in the game and their properties (e.g.: name, room, 3D position, ...). Unpacked into the AitD Objects worksheet.
  • Save files are called SAVE0.ITD – SAVE5.ITD. The one shown up top in the save menu is SAVE0.


KNOWN VERSION DIFFERENCES

  • These are the versions that the most is known about:
    • The GOG release, which is probably just the old official English CD-ROM version.
    • French floppy version.
    • French CD-ROM (same download page).
  • Only the original French CD-ROM version seems to have been released in debug mode (accidentally), meaning it's a lot easier to reverse-engineer. In fact this version was used for that purpose.
    • Despite debug versions normally running slower than release versions, this doesn't seem to be the case with the debug/non-debug versions of AitD (tested using the RV).
    • The downside to it being in debug mode means direct file comparisons are impossible and so it's not really known which differences may exist between French CD and other versions.
  • Version difference: the French CD-ROM version doesn't crash coming form a save file where reaching the actor limit was otherwise causing crashing (the file seems to be missing).
  • Some Room Viewer data is only displayed for the CD/GOG releases of the game. This includes anything to do with the game's timers (FPS meter, lagometer, CHRONO...).
    • Also ALLOW_INVENTORY is only shown for the GOG release.
  • Some typos were corrected between the initial floppy and later CD-ROM releases.
  • The CD-ROM version does not have a copy protection screen.
  • The floppy version (tested on the English one) seems to crash a lot more seldom due to the render bug though generally similar outcomes are seen. It's not known why. The CPU values were matched with the GOG version to make sure that's not the cause.
  • The CD version has a slightly different tracklist, and changes in associated logic. Also the READ commands in the LIFEs have a third parameter: the voice file to play back.
    • These differences are in at least all of these LIFEs: 15, 118, 140, 175, 185, 191, 192, 193, 194, 265, 380, 430, 438.
    • No other kinds of differences exist in the scripts.
  • The orchestral hit sound sample played when entering dangerous areas such as E1R7 has been replaced with a short piece of music (string cacophony).
  • There are no differences in the trigger or camera trigger data.
  • There are small differences in the room/collider data, from the floppy to the CD-ROM version:
    • E3R2:
      • 3 colliders have their width increased by 200 units, including two that overlap (on the W side, they actually reach into R3 in a way that might make some theoretical difference in getting OOB from one of the two rooms if you had to get OOB from that area)
      • 2 colliders have flag set to 0 instead of 1 (not known why)
    • E5R0:
      • 6 colliders have been added. They are all the walls around the bridge. For some reason, the long E wall is 10 units lower than the rest.
    • E5R7:
      • 4 colliders have been changed (size+position):
        • 6950, -3000, -100 (made thicker along Z-axis to prevent the player from getting into a blind corner)
        • 5949, -1000, 3000 (made thicker along X-axis so it overlaps with E wall, preventing clipping into corner)
        • 6800, -1000, -2000 (made thicker along Z-axis so it overlaps with the collider to the N of it, preventing clipping into it)
        • -5699, -1000, -5650 (made thicker along Z-axis so it overlaps with S wall, preventing clipping into corner)
      • 2 colliders were moved inside the list for some reason, but otherwise left unchanged.
  • Because the lagometer only works for the CD-ROM version, it's difficult to tell exactly which version has the most lag, or if there even is a difference. The CD-ROM music is played off the CD image directly, so it's not cached and thus doesn't cause lag. The midi files loaded in by the floppy version might cause a bit of lag?
  • The headers of room data files: In the floppy version some of them contained garbage (they pointed to areas outside the file). In GOG/CDROM version those had been set to zero (cleaned by the devs?). No known relevance.
  • The floppy version seems to temporarily store some other data right after starting a new game in the part of RAM where the VARs are kept during gameplay.
  • The Japanese release (3DO/FM Towns) has the known difference of taking more damage from some sources such as the smoke in the smoke room. It is unknown which other ports were the same. Generally no testing was done on non-PC versions.
  • In the earlier of the two demo versions, spending time in the menu still causes the CHRONO to advance.

GENERAL

  • There's various situations where there are one-frame windows to e.g. still be able to access your inventory. These should be checked for by buffering the inputs.
  • If it benefits testing in any way, you can change VAR 9 to a different value in the middle of dropping something to cause the object with that ID to be spawned in front of you. This just teleports it to that location, it doesn't create a copy. There needs to be room for it to be dropped. This was not done much during testing and the only known way to do it without cheating is to corrupt memory, and as such, is of theoretical/testing interest.
    • Actors other than items that you've dropped this way are dangerous to touch and usually cause instant crashing with few exceptions.
  • A small difference between holding the main ENTER key and keypad ENTER (see "lag manipulation") was only spotted late into the project. In the future the two keys should probably be tested separately but it seems very unlikely there's other differences. Similarly hitting 'I' to get to the inventory was initially overlooked, but is does the exact same thing as either ENTER key outside the inventory itself.

CONTROLS

  • The game checks the state of the keyboard at the beginning of the frame and stores it. This state will be used for all logic for the entire frame, and thus pressing or releasing buttons during the frame won't alter the state until the start of the next frame (there's no sub-frame inputs).
  • 'p' to pause, "action" to unpause.
  • alternative keys:
    • enter/keypad enter for "menu" and "select"
      • there seems to be a small difference between the functionalities of these two keys (see "lag manipulation")
    • space/keypad ins/keypad del for "action" and "select"
    • esc to "cancel", also to select not picking up an object quicker
    • other keypad keys for movement, also with numpad 7 and 9 you can combine running with turning and 1 and 3 are the same backwards
    • some other random keys are mapped to movement as well
    • these can obviously be adjusted in the DOSBox keymapper as well and may be different with different keyboards
  • 'i' takes you to the inventory but doesn't otherwise act as 'select'
  • The 'ö' key in a Finnish keyboard switches music on and off in the CD version. In most keyboards this is probably 'm'.
    • In the floppy version, only the 'm' key works for this.
  • 's' toggles sound effects, interrupting the current sample.
  • If you just hold down keypad ENTER, after entering the inventory, the game seems to eventually count it as another key press, and eventually selects fighting all on its own. The same behaviour is observed in the menu. No other keys seem to work this way. It's not clear what's causing this.

MEMORY/CACHES/BUFFERS/SOUND SAMPLES

  • The game has separate caches/buffers for LIFEs, TRACKs, sound samples, BODYs and ANIMs, and the floppy versions have a music cache as well. They have the following maximum sizes in terms of number of entries and number of bytes:
    • LIFE, 100, 10000
    • TRACK, 10, 1000
    • SAMPLE, 30, 64000
    • BODY, 50, 65000
    • ANIM, 80, 65000
    • Every cache entry has a field called "timestamp" telling the game when the resource was last used.
    • If either limit is getting exceeded, the game in theory removes the least-recently-used entries for that cache until there is enough room. In practice this is bugged and often the wrong entry is removed.
  • The cache can be read in detail with the Cache Viewer.
  • The music cache (in the floppy releases) has unknown properties since those versions are encrypted and cannot be read.
  • In addition, there are two arrays for keeping actor data in. These are discussed under "actors".
  • Upon starting a new game, and any time the game has been restarted, the game flushes the caches, including any actors from adjacent rooms you've just been to, and only loads in whatever is currently present without making any assumptions about what will be needed in the cache otherwise. This means rebooting the game might lose you time unless you take the time to get every sound effect (especially), ANIM etc. cached before you start recording any segment where they will be accessed.
    • All the LIFEs used are also always cached.
    • The approximate time sound samples load for in milliseconds (from the Room Viewer total delay meter)(one frame is approximately 16.7 milliseconds)(the global FPS during these measurements was around 35 in case that matters):
Sample ID Description Approximate Loading Lag
0 drawer opening 77
1 vase breaking 84
2 glass breaking 167
3 lock opening 83
4 door creaking 133
5 heavy object moving (wood) 67
6 thunderclap 200
7 taking a shot (house) 50
8 reloading 32
9 weapon click 17
10 Edward after flask 33
11 Emily after flask 32
12 Edward coughing 33
13 Emily coughing 34
14 hit sound 33
15 hit sound 2 33
16 Edward attacking 33
17 Emily attacking 18
18 Edward attacking 2 32
19 Emily attacking 2 18
20 Edward attacking 3 15
21 Emily attacking 3 0
22 Edward jumping/climbing 17
23 Emily jumping/climbing 17
24 Edward climbing 2 17
25 Emily climbing 2 16
26 Edward hit 67
27 Emily hit 16
28 bird bite 33
29 zombie groan 167
30 stepping on wood 33
31 stepping on wood 2 33
32 stepping on stone (house) 33
33 stepping on stone 2 (house) 33
34 Edward dying 0
35 Emily dying 50
36 doors slamming 50
37 door creaking 2 116
38 Edward falling through crack 166
39 Emily falling through crack 134
40 Edward falling into a pit 217
41 Emily falling into a pit 216
42 thud 34
43 thud 33
44 nightgaunt screech 67
45 nightgaunt dying 116
46 stepping on carpet 17
47 stepping on carpet_2 33
48 axe/arrow fired 33
49 page turning 67
50 sword clang 51
51 stepping on stone (house) 32
52 stepping on stone 2 (house) 33
53 water dripping 284
54 water dripping 2 66
55 water dripping 3 101
56 stepping on stone (underground) 34
57 stepping on stone 2 (underground) 34
58 aquaphone chime 151
59 eerie howl 117
60 taking a shot (underground) 50
61 drinking 16
62 heavy object moving (stone) 115
63 eldritch gurgle 234
64 back cracking 33
65 throwing 17
66 hoarse laughter 84
67 malicious laughter 49
68 deep laughter 81
69 drawer opening 50
70 wading through water 33
71 wading through water 2 50
72 water splash 116
73 rat squeal 83
74 car revving 67
75 car approaching 417
76 crickets and frogs 183
77 frog and car 217
78 slamming car door 34
79 opening car door 34
80 exiting car 50
81 stepping on gravel 17
82 stepping on gravel 2 15
83 wasp hoot 0
84 slimy slurp 49
85 slimy wheeze 83
86 Deep One growl 133
87 vortex chant 84
88 bird call 50
89 chimes tinkling 335
90 low rumble 100
91 saber breaking 99
92 beetle grunt 100
93 Cthonian cackle 184
94 pained moan 83
95 birds chirping 416
96 croaky laughter 49
97 Necronomicon whip 34
98 Vagabond growl 150
99 fireball explosion 101
100 fireball launch 67
    • The lag values are all within 1-2 ms from the discrete values you get when multiplying the length of one frame by different factors, as you'd expect.
    • It looks like the delay for samples is simply a function of the sample's filesize, which is apparent enough when considering the information in the table. The variance between attempts looks to be around two frames generally so consider that the margin of error in the above information. Thus a frame or two could be lost per sample effectively at random. For some reason, sample 34 (Edward dying) seems to always be pre-cached as is #83 (wasp hoot).
    • The worst samples to have to load in during a run (outside the intro/outro) are the talisman chimes and one of the random water dripping samples played in E5, both wasting around 300 ms.
  • If you take a step (sample 30), then get sample 75 (car approaching) to play, then take another step, the step sample will have been flushed. Thus we can tell the cache just about fits the long car sample but not that and the step sound at once.
  • The music file caching load times (only applicable to the floppy versions) were not tested much but they're midi files and as such have very small sizes.
  • Any sounds and cache entries could have a compound effect worse than just how long they loaded for initially if they're also forcing more samples to be recached later that were removed to make room for them.
  • It's not clear what kind of hierarchy there is between samples that determines which samples can interrupt which other ones. It doesn't seem to be about the size of the samples so that e.g. the longer/(more significant) sample overrides the shorter one (the throwing sample can cancel out the slimy slurp for example), nor does it seem to be directly tied with the sample "ID" if that's even used by the game at all (other samples like melee attacks cannot interrupt the slimy slurp despite having a lower ID just like the throwing sample does). Nor does it seem to have anything to do with whether or not the latter sample was already cached before. It's difficult to test whether it's a question of where in the cache each sample happens to have been stored but this doesn't seem like a very likely explanation either.
    • There could even be some customized tablebase in which different sounds are given different priorities.
    • If there's another repeating sample playing, it may cancel out [some] other ones completely so they're not even loaded into the cache thus saving some time. This at least works with the vortex hum and melee attacks. Single-time samples don't seem to cancel subsequent samples from being cached and played.
    • The vortex also cancels out the talisman tinkle (chimes) which would be useful since it takes a third of a second to cache whereas the vortex sound takes less than a tenth.
  • Hitting SPACE may sometimes result in a sample not playing in case it's taken you away from the main loop in LIFE 549 (skipping the ANIM_SAMPLE calls).
  • It's difficult to tell how exactly lag is created by loading in actors. It looks like the presence of a lot of dropped items in a room that you've either entered before since the last reloading or have not entered since then causes a difference in loading lag for that room/view of about 10 milliseconds per item, which can probably be used as an estimate of how much of the lag owes to actors. Thus if you needed to go between rooms A-B-A, if you s/l'd in room B, it might cause you to lose some time this way compared to saving in room A then going to B and returning to A in one segment, unless you take the time to make sure the actors in A have been cached again. However, no such effect is seen with the presence of stationary actors (though each one causes more loading lag in general). It could be that actor flushing is done selectively based on their flags.
  • If you push a lightweight to another room, or an actor otherwise moves to another room further away from the one you're in, if you save and reload, it might disappear, suggesting that there is no flushing of actors unless the PC herself moves from room to room.
  • ANIMs played for the first time seem to be cached. It takes a short time (mostly just one frame at most).
  • Objects that move too far away without the view changing (by being pushed from room to room for example) will be removed from memory only when the game gets reloaded the next time (returning from inv or menu).
  • One thing that seems to be never cached is the 2D background, it is always loaded from disk. Also sometimes it seems to be loaded twice, causing extra lag.
  • In summary, make sure to cache as many relevant sound samples and ANIMs etc. as you can when starting a new session. Other than that it may be difficult if not impossible to find chances to save time optimizing cache usage without losing it to the detours taken to accomplish it, except if you have some waiting time during which you can save a few frames by avoiding messing around causing new ANIMs or samples to play.
  • PRIORITY.ITD is always cached. It's unknown what it's used for but it's a small file.
  • Cache bug: the code should look like this:
max = 0
oldest = 0

for (i = 0 to entries.count - 1)
{
	if ((timer - entries[i].time) > max)
	{
		max = timer - entries[i].time
		oldest = i
	}
}

remove_block(entries[oldest])

It's really simple: you calculate how long each entry has been there, and if it's longer than what you have stored in "max", replace "oldest" with its index, otherwise just check the next one. After removing one entry, if there's still not enough room, the same code is run again, removing enough entries for the new entry to fit.

The code actually looks like this:

max = 0
oldest = 0

for (i = 0 to entries.count - 1)
{
	if ((timer - entries[i].time) > max)
	{
		max = timer - entries['''oldest'''].time
		oldest = i
	}
}

remove_block(entries[oldest])

The max value ("oldest") that is used as a reference will always be lagging one behind, which is reason one why the algorithm can fail.

Reason number two why the algorithm can fail is it uses Timer 1, which can occasionally revert to a previous time. Because of this, the time differences can turn into negative values, which are interpreted as large positive ones. A large positive value will cause an entry to be removed even if it's the last one cached.

SAVING/LOADING

  • Saving and loading is mostly perfectly implemented and not a lot of information goes missing. Some things will be recalculated during the loading process though. A sample of things saved in the save file:
    • current room
    • current floor
    • current camera
    • current camera target
    • current music
    • current object in hand
    • inventory objects
    • inventory allowed flag
    • shake screen flag
    • light status flag
    • game over flag
    • Timer 1 (but not Timer 2)
    • all vars
    • all cvars
    • all objects and their properties
    • all actors and their properties
    • There is a complete list in the objects worksheet.
  • When you reload, the music is reset.
  • The view the focused actor should be in is recalculated during reloading and so you might end up in a different view. More under "cameras".
  • The "game over" flag is only used right as the game starts fading back into the main menu after the game has ended, and set back to 0 when a new game is started. Thus it didn't really have a need to exist inside save files at all, because it will always have a value of 0.
  • Some things depend on what Timer 2 happens to be when the game has reloaded (Timer 2 is not saved in the save files).
    • More under "timers".
  • Loading a save file sends all ANIMs back to the start of the current keyframe, thus delaying things from happening quite as quickly. The BODY is visually frozen until it's caught up with how far into the ANIM the actor was before saving. This can help avoid taking hits from enemies like the knight by giving you just a tiny bit more time to move away (since the hitbox is tied to the hotpoint vertex position, more under "fighting"). It also means you'll generally lose some time whenever saving and loading on a frame that's not the first in a given keyframe.
  • S/l-ing can also prolong the death animation of for example the nightgaunts causing them to block the way for a longer time.
    • When birds are crashing through windows loading and saving sending them further back can prevent them from getting through the wall at all. Specifically the E1 bird.
  • You can preserve running through a s/l by just buffering up arrow before and after.
  • When you s/l during walking, it sends you back to where the keyframe started just like running. However, soon after, you'll continue walking forwards a little ways because it seems you can't control the first several frames at all (could just be global lag?). This is true almost every time. While the extra movement is happening, the SPEED goes from 4 (during loading) to 3 to 2 to 1 to 0.
    • On the second load, you won't necessarily be sent all the way back at all, instead it could be 15 units less. It can be as far as 100+ units further ahead. The exact starting position will vary from load to load, probably owing to different amounts of lag.
    • There's an intermediate position you're placed at during the loading before the correct keyframe and subframe are set. This might apply to all loading? Also, after the save has finished, you might be sent back or forwards a little bit with the wrong keyframe/subframe (which could partially be the Viewer's limitations). There's usually or always a frame of ANIM 4 before it's switched for anything else.
  • S/l-ing causes the smoke to disperse in E3R13 giving you more time to pass through unharmed.
  • When you s/l while opening doors inwards, you can end up being inside the door object.
  • The first time reloading a save file coming from the main menu has a fade-out fade-in.

PAUSING

  • Pausing seems to be perfectly implemented with no anomalous effects noted when using it.
  • Frame advance: You can get (near) frame advancing if you hit and hold 'p', then tap SPACE, then tap and hold pause again and alternate. Make sure to hold SPACE for a little bit before releasing each time in order for any potential loading lag or such not to disrupt the process.
    • Pausing in the middle of running with the lamp out, releasing all binds, tapping and holding 'p' again, then tapping space doesn't interrupt running.
    • Should also be able to move the game just one frame (or so) ahead even if you don't want any lag to happen by hitting pause immediately while coming from the load menu.
    • Can also hold a movement key, then hit pause to make it unpause automatically when pause is released, but it's not possible to go frame-by-frame that way. The upside is you're not interrupting running by hitting space. If you have a null action (lamp or after using the jug), hitting space doesn't interrupt it though.
    • Sometimes the frame advance really is one frame at a time, but this is not guaranteed. Not sure what determines this.

LIFE SCRIPTS

  • LIFE is what the game calls its scripts (presumably because they bring the actors to life). There are 563 LIFEs all contained in the LISTLIFE.PAK file, which you can extract using LIFEDISA. The scripts have no comments and are difficult to read without unless the names for VARs, ANIMs etc. are replaced (see "LIFEDISA" for instructions).
    • Some LIFEs are tied to one actor's behaviour (acting as a state machine), some act as room scripts or floor scripts which are multi-purpose and relate to events inside some room or floor.
  • Each actor can have up to two different LIFEs, the other one being called the FOUNDLIFE. The FOUNDLIFE is executed when an actor is either picked up, used or equipped, or given via a FOUND command in a LIFE. Almost all actors have either just a FOUNDLIFE (if they're inventory objects) or just a LIFE, with object 2 being the exception.
  • Every active actor that has a LIFE script field with a value other than -1 is causing the game to execute all the code in the script sequentially until reaching an ENDLIFE or RETURN instruction. Then the next actor's (in increasing order of their memory slot numbers) code is executed. Only when all LIFEs have been cycled through will the game draw the next frame and accept more inputs.
    • When a script calls for a different LIFE, it just updates the actor's LIFE field and proceeds normally with the current LIFE until the next frame, when the new LIFE gets executed instead. Thus if two LIFE instructions were issued on the same frame, only the latter one makes any difference.
    • Even though the code execution order may vary based on the exact memory slots for each actor, the game is coded in such a way that this should, in principle, never result in differences in its behaviour. This isn't really true in practice: when two contradicting instructions have been given on the same frame, the latter is what's left in effect.
#510
xxx          //frame 1, 2, 3, 4
yyy          //frame 1, 2, 3, 4
IF END_ANIM  //frame 1, 2, 3, 4 
    BODY 7   //frame          4
    LIFE 521 //frame          4
ENDIF        //frame 1, 2, 3, 4
zzz          //frame 1, 2, 3, 4

#521 
xxx          //frame 5, 6, 7, ...
yyy          //frame 5, 6, 7, ...
zzz          //frame 5, 6, 7, ...
  • The order of execution every frame:
    1. Using/selecting something in the inventory (FOUNDLIFE, only one possible)
    2. Collecting an object off the floor (FOUNDLIFEs in order of increasing actor ID, can be multiple)
    3. LIFEs (in order of increasing actor ID, any FOUND commands cause the respective actor's FOUNDLIFE to be executed as a subroutine to the LIFE in question, which resumes after the player has made their choice of picking the item up or leaving it)
  • In some LIFEs there's missing cases in switches to look out for. One of the most obvious ones is there's no case for BODY 268 (flask) in LIFE 39 if VAR 29 is 1, so death by falling never happens.
  • The actors called "alone_in_the_dark" are dummies used to send the camera into a new view during cutscenes, and also to calculate the distance from Pregzt to make the fireballs disappear when they're getting too far.
  • The following explains some of the less obvious commands used in LIFEs. Note that if you used vars.txt, some of the number parameters were replaced with words:
  • OBJECT(...) == 1 means the object in question has been collected at least once. ISFOUND means it's currently in the inventory.
  • DEFAULT refers to a default case when no matching case exists in a switch.
  • DEF_ZV: Defines a new bounding box for the actor. The six parameters are X1 X2, Y1 Y2 and Z1 Z2.
  • DO_CARRE_ZV: Resets the actor's bounding box using default values stored in the current BODY.
  • DO_ROT_ZV: The same except the box is rotated based on the actor's angle (making a different orthogonal rectangle).
  • DO_REAL_ZV: Calculates the bounding box from the actor's current 3D-vertices directly, taking into account the effects of rotation, translation and scaling. Very CPU-intensive and so not used very much.
  • ANIM_ONCE; ANIM_ALL_ONCE: These both have two parameters which are ANIMs. The second one gets stored in NEXT_ANIM. If the first ANIM is interrupted, the second one gets flushed and replaced.
    • ANIM_ONCE: Plays two ANIMs once through that can be interrupted.
    • ANIM_ALL_ONCE: Plays one ANIM once through that cannot be interrupted, then another that can.
  • ANIM_REPEAT: Gets one parameter. Plays an ANIM on loop until interrupted.
  • ANIM_MOVE: If VAR 0 is 1 and MOVE is MANUAL, hitting arrow keys causes ANIMs to be played from the list given as the parameters for this command, accompanied by a potential change in the player's SPEED. Only found in LIFEs 549 and 550. The rotation (change in the angle field) is an event separate from the rotation ANIMs though and only depends on MOVE MANUAL.
    • ANIM_MOVE is not a value that's stored somewhere, it has to be executed every frame for basic movement to be available.
  • END_ANIM: A test for the current ANIM having just finished. This could be any ANIM, not just the one it is expected to be based on the context.
  • ANIM_SAMPLE: A sound sample (from LISTSAMP) is cached and played if the parameters given match the current ANIM and keyframe and the ENDFRAME flag is set. (So it's played at the very start of the keyframe)
  • DO_MOVE: Causes a TRACK to advance.
  • POSREL: Evaluates the position of the current actor (the one that executes the script) relative to another actor specified in the parameter. Note that the angle of the current actor is considered, not only the position.
    • The possible values are: 0 (any), 1 (left), 2 (right), 4 (front) and 8 (back).
  • PUT_AT: Differs from DROP by being forced regardless of room constraints.
  • SPECIAL: Three kinds of particle effects, where 0 is bubbles when a monster dies, 1 is blood and 4 is smoke from the ashtray.
  • CHANGEROOM: Sets actor floor and room (in that order). Does not change the 3D position.
  • SET_ALPHA/BETA: Rotation. Parameters are the angle to rotate to, and how much time this should take.
  • MARK: MARK is used to monitor what part of its TRACK the actor has reached. It's set by the engine when it's reading the TRACK file and encounters a MARK command there, and read by the scripts, often to change the actor's ANIM to the appropriate one.
  • MOVE: Sets an actor's movement mode. The second parameter is called TRACKNUMBER.
    • 0 = NONE. This is often used to lock the player position before doing something.
    • 1 = MANUAL. Left and right arrows are mapped to rotating the actor. This is obviously just for the PC. Forward and backward movement (and playing rotation ANIMs) require an ANIM_MOVE command to be looped and VAR0 to be 1.
    • 2 = FOLLOW. Follow another actor given in the TRACKNUMBER. The code used is the same as for MOVE 3 except the target point is another actor and thus can move around.
    • 3 = TRACK. Follow a TRACK given in the TRACKNUMBER. More under "tracks".
  • HIT_OBJECT: Defines the size of a hitbox cube around a particular vertex of an actor's BODY and a HITFORCE (damage value) for hitting any actor within the hitbox. Sets ACTIONTYPE to HIT_OBJ.
  • STOP_HIT_OBJECT: Cancels out HIT_OBJECT.
  • HARD_COLLIDER: Returns the ID of the first collider touching the actor. Only colliders with flag 0001 set affect this.
  • ACTOR_COLLIDER: Returns the ID of the first other actor touching the actor.
  • TRIGGER: Returns the ID of the first trigger the actor is inside.
  • GET_HARD_CLIP: Returns the bounding box of the first hard collider an actor is colliding with. Used for rendering the Vagabond: when rendering the individual pixels, any pixel which is inside that bounding box won't be rendered (it will get "clipped"). Because of this the Vagabond will progressively disappear when entering a wall, and then progressively reappear on the other side. The function is specific for the Vagabond. Without that special trick the vagabond would produce weird rendering glitches, similar to when the player is OOB.
  • END_SEQUENCE: It's assumed what this does is to suspend the script and show all 320x200 backgrounds located in END_SEQ.PAK file. This is the animation with Pregtz burning. When the animation is done, it resumes the script. It doesn't necessarily do anything else (like changing some game internal variables).
  • WATER 0: set water height at 1000 (below the ground), WATER 1: set water height at -600 (a little higher than the ground). The water level is only used for clipping the bottom half of the player when they're in water. It's not used for playing the wading sounds.
THROW parameters:
1) ANIM when throwing
2) ANIM keyframe index when the object should be spawned
3) hotpoint index (indicates which 3D point of the actor model the object is spawned at)
4) object to throw
5) boolean (if 0, rotate the object to be throw by 90 degrees in the pitch direction to make it stand up)
6) HITFORCE
7) ANIM after throwing

HIT parameters:
1) ANIM while attacking
2) ANIM keyframe index when the hitbox should be created
3) hotpoint (indicates which 3D point of the actor model to use as the center of the attack)
4) hit range
5) HITFORCE
6) ANIM after attacking
POSREL

0 any
1 left
2 right
4 front
8 back

MOVE

0 none
1 manual
2 follow
3 track

KEYBOARD INPUT

0 nothing
1 up
2 down
4 left
8 right

SPECIAL

0 bubbles
1 blood
4 smoke

IMPORTANT/SPECIAL LIFES

  • LIFE 11: Handles dropping items. Can send the player to the damage processing LIFE 553. The last clause that refers to the throwing_or_using_jug VAR isn't actually used.
  • LIFE 39: the death manager. The player is taken here at times when they're supposed to die. There is no way to escape it other than hitting a transition (taking you to #550) or if you had or got back INV.
  • LIFE 59: entered when drinking a flask. You can stay in this LIFE indefinitely if you had an action that is activated through hitting SPACE, and you hit SPACE during the ANIM. There is no way to get hurt while in LIFE 59.
  • LIFE 522, stuff that gets deleted when you defeat Pregzt:
    • E0 zombie, bird
    • E1 2 zombies, bird, 2 nightgaunts
    • E2 Vagabond, knight, ghost, bird
    • E3 jelly, pirate, 3 dancers, 5 spiders, kitchen zombie, 5 dining room zombies, ashtray
    • E4 3 rats
    • E5 Cthonian, bird, 2 wasps, white spider, purple spider, Deep One
    • E6 Deep One (through LIFE 517)
    • Doesn't delete the two portraits nor the crack. Note that it doesn't matter if the ghost/dancers are in their first form or second.
  • LIFE 549 is the one the PC normally has. It does the following:
    • IF player_hitpoints are ever <1, go to LIFE 39 (death manager) without doing anything else.
    • IF SPACE is not held and VAR 0 == 1:
      • INV 1 and ANIM_MOVE and ANIM_SAMPLEs according to which BODY the player has (flask BODY is missing). Also set player_moving_backwards == 1 if the player is taking steps backwards.
    • IF SPACE is not held and VAR 0 == 0:
      • INV 0
    • IF BODY == normal AND player_pushing_something == 1
      • IF ANIM is something other than pushing, or if END_ANIM, set player_pushing_something 0.
      • ANIM_SAMPLE for pushing.
    • IF ANIM == Necronomicon_effect, play ANIM_SAMPLEs in different parts of it.
    • IF ANIM == jumping:
      • IF it's the last keyframe, set flags 0141 (gravity on), otherwise, if not END_ANIM, flags 0041 (gravity off).
      • ANIM_SAMPLE for jumping according to which character was chosen.
    • IF ANIM == dying:
      • Go to LIFE 39 (death manager).
    • IF ANIM == getting hit and END_ANIM, set player_moving_backwards 0.
    • IF ANIM == throwing, play correct ANIM_SAMPLE.
    • IF FALLING == 1:
      • IF player is in E5 on top of one of the death pits, remove control and inventory, set MOVE 0, set type of death 1, go to death_manager, play the right sound effect, set flags 0041 (aside from the first tier, the fall is cosmetic, so gravity is switched off).
      • Otherwise just ANIM falling, take away control and inventory but don't set MOVE NONE, go to LIFE 551 (player_falling). Also set correct fall height based on player's Y-coordinate.
    • IF colliding with a climbable collider, ANIM is not jumping, player_moving_backwards == 0 and there is a space to climb into:
      • control off, inventory off, LIFE player_climbing, play climbing ANIM
    • IF hit by something, spawn blood, go to LIFE 553 (player_hit_by_something).
    • IF throwing or using jug and END_ANIM:
      • control 1, throwing_or_using_jug 0, allow inventory. This is also done in LIFE 11 the exact same way so this is probably just a failsafe.
  • LIFE 550 gives the instructions on how to handle floor transitions and trigger 18 in E3R1 (outside the front doors). The game automatically changes the player's LIFE to this when they've hit any floor trigger. The lower part of the LIFE has instructions for each individual trigger and the upper part extra instructions for the TRACKs the player will be put on as a result.
  • LIFE 553: the hit manager. It's where hitpoints are subtracted and a knockback ANIM is played.
  • LIFE 561 is about the actions you can select in the inventory. "actions" is actually just an actor like all the others you can pick up. It gets "equipped" like any weapon or such with the effect when hitting SPACE being based on the player_current_action VAR. It's initially "collected" in LIFE 562 (the TAKE command).
  • LIFE 562 has initial preparations at the start of a new game right after the intro has finished.
  • The majority of rooms have what we call room scripts. These are scripts that are loaded in only when the view is in that room that contain the code for the player hitting various triggers and colliding with or searching special colliders. The actors they're executed by can exist without a BODY or bbox so you can't see them in the RV at all necessarily.


VARS, CVARS, AND OTHER VARIABLES

  • All the variables are 16-bit and thus can hold values between −32768 and 32767.
  • VARs are only read and set in scripts. CVARs can also be read or set by the engine.
  • Most VARs are boolean flags, and a majority of those are for doors being closed or open.
  • Most CVARs are important constants(hence the name, "constant variable") but a few of them are actually used as flags during gameplay.
    • Changing CVARs can easily result in instability.
  • VAR 0 (player_has_control) being 1 is closely tied to the concept of the player being in-control of their actions. All SPACE-operated actions (e.g. searching, pushing, firing weapons) are locked behind this VAR, as is ALLOW_INVENTORY, which is matched with it every frame of LIFE 549 unless you're either holding SPACE which delays it, or are not in LIFE 549.
    • By contrast PLAYER.MOVE is a command that can be found in the code somewhere. It governs whether or not your basic movement is available, while LIFE 549 governs which ANIMs are played when the player hits different movement keys.
    • The two are usually tied together but only because the coders kept setting both to 1 or 0 at the same time. There are ways to desync them, though this probably isn't terribly useful since there's no advantage to having less options or being stuck.
    • If PLAYER.MOVE is NONE but VAR 0 is 1, you can still move if you have an action like pushing selected.
    • LIFE 550 (transitions) sets VAR 0 to 0 on every frame.
  • If you take a hit at any point when not having control, it will be returned to you immediately (VAR 0 == 1).
  • VAR 10 is set to 1 when throwing something or using the jug, and it causes control and INV to be restored in LIFE 549 afterwards.
  • VAR 20 (active monster count) is only used to control when scary noises and certain music tracks are played.
  • VAR 24 is set to 1 when you're moving backwards to differentiate between collisions with objects ahead of you and behind you. Mainly used for doors so you can only open them when facing them, but also for whether a climb should be started. It's erroneously left at 0 when shooting the rifle meaning your are able to open doors during that ANIM. If you rotate yourself to face the collider you're attempting to climb, you can also climb colliders after taking rifle shots.
    • Also set to 1 very briefly during knockback.
    • VAR 24 is possible to manipulate by holding SPACE just after changing your ANIM. Its value doesn't change if you timed it right, thus allowing to have the wrong value whether you're moving forwards or backwards.
      • This means you can open doors while facing away from them, or have them not open while you are facing them. The easiest way to do this is to just walk backwards into a door and tap SPACE and down arrow until it happens.
        • You can't seemingly get into a state where you're running but have VAR 24 be 1. For the ANIM to change from walking to running, you have to pass through the ANIM_MOVE command in LIFE 549 but this is also the same clause that will update VAR 24. Then again, if you can get walking with VAR 24 being 1, why can't you get running?
          • After a lot of trials, I couldn't make this happen. Could possibly use it for clipping through a door instead of opening it. E.g. the front doors, though there isn't room behind the front doors for clipping OOB like there would be if you first opened them.
        • You can get a very fast rotation of over 90 degrees by opening a door while facing away from it.
        • If you just needed to open some door outwards and keep moving, you could maybe save a bit of time by opening it while facing the direction you wanted to go. This could tie in with the idea of opening a door outwards in advance in case you later return to the same spot but have to open it inwards.
  • VAR 25 is 1 if you're in the intro. This is mainly used to suppress the scary noises or music changing, but also to avoid the player falling through the E1R1 crack. It is also used in a conditional clause completely unnecessarily.
  • VAR 33 is Pregzt being alive (0) or dead (1), affecting multiple areas in the game, most notably the front doors. CVAR 12 is also set when he dies.
  • VAR 105 is never set to other values than 1. If you use the Viewer to set it to 0 before opening the front doors, the jelly never attacks you and the doors never close.
  • VAR 205 is unused. It is set to 1 when the player is in E5 or E6 and 0 when they leave.
  • CVAR 11 is for reversing the direction of the lantern flying through the air so it bounces off Pregzt, presumably so it doesn't get lost. More precisely, it gives the ID of the actor that causes this to happen, but it's only used with Pregzt.
  • CVAR 12 is set to 1 when Pregzt dies. It governs whether or not dark rooms are actually rendered dark and if the related message should be shown, and also changes the backgrounds that have the Pregzt tree in them.
  • CVAR 14 governs the smoke in E3R13 (see LIFE 427).
    • 0 : if player is in E3R13, create a special smoke actor using "SPECIAL 4" command
    • 1 : smoke animation
    • 2 : if player is in E3R13, play player cough sound and deduce health points
    • 3 : destroy smoke, then go back to 0
  • The CVAR 14 transitions are hard-coded in the game engine:
    • 0->1 happens immediately
    • 1->2 happens after 8 seconds
    • 2->3 happens immediately
    • 3->0 happens after 11 seconds
  • LIGHT is what controls whether the game draws the current room or not. Drawing the little light circle is done separately. In E6, its position is determined by CVAR 13 which can be -1: not drawn, 1: on the player, 13: on the lamp (if it was dropped).
  • Other VARs etc. are discussed in specific parts of the guide.


INTERRUPTS

  • Under some conditions, executing a part of a script can be skipped in an unintended way. This generally involves there being a waiting time for some condition to have been met without the player having lost control completely, or something else happening on the same frame when control is lost. These conditions could be:
    • IF END_ANIM : every ANIM takes time to finish, if they get interrupted, this condition being met is delayed
    • IF FRAME : ANIMs take time to reach a given kf
    • IF MARK : reaching a particular part of a track
    • IF ALPHA/BETA/(GAMMA) : waiting for a rotation to finish, GAMMA rotations aren't really used
    • IF CHRONO : waiting for a timer to reach some value
  • ANIMs themselves can be interrupted if the command used to set them was ANIM_ONCE or ANIM_REPEAT, or if it's the second ANIM given in an ANIM_ALL_ONCE command.
  • The following examples give a general idea, though there are too many potential interrupts to list out completely – in fact a lot of the unusual occurences mentioned in other parts of the guide can be explained by similar means.
  • The hover trick: When the player goes to LIFE 11 as they're trying to drop something, after the jump has finished, NEXT_ANIM is idling. There is a case in LIFE 11 for that ANIM that causes it to return straight to the normal LIFE 549 (which is why nothing is dropped either). The condition for jumping FRAME >= 7 isn't ever met in LIFE 549 and so the gravity flag isn't ever returned.
    • If the player passes between E5 and E6 during the jump, and only drops something after the transition, the following will happen:
      • LIFE 561 queues jumping ANIM then idle ANIM.
      • LIFE 549 sets gravity flag off.
      • Any of the triggers forces LIFE 550, which sets ALLOW_INVENTORY 0 (but does not remove control) and sends the player on the other side while also sending them back to LIFE 549.
      • Because the player has control, LIFE 549 sets ALLOW_INVENTORY 1 again.
      • Dropping anything sets INV and control 0 (in that object's LIFE). Also causes the player to go to LIFE 11. If not HIT_BY or throwing_or_using_jug, LIFE 11 does nothing until ANIM goes to idling. Then ALLOW_INVENTORY 1, player_has_control = 1, and sent back to LIFE 549.
      • Gravity flag is not returned because both ANIM == jumping and FRAME => 7 were not true at the same time. Player is left with control.
    • If the dropping happens BEFORE the transition:
      • LIFE 561 queues jumping ANIM then idle ANIM.
      • LIFE 549 sets gravity flag off.
      • Dropping anything sets INVENTORY and control 0 (in that object's LIFE). Also causes the player to go to LIFE 11. If not HIT_BY or throwing_or_using_jug, LIFE 11 does nothing.
      • Hitting the transition forces LIFE 550, which sets ALLOW_INVENTORY 0 (was already 0) and sends the player on the other side while also sending them back to LIFE 549.
      • The jump finishes, so gravity is set back on. No part of LIFE 549 can restore control or INV in this situation. The player is completely stuck unless something hits them.
  • The reason holding SPACE while descending or rising up stairs can result in being left in the wrong ANIM is because it doesn't allow the part of LIFE 549 to be accessed where ANIM_MOVE is called, and thus e.g. SPEED 0 goes into the idle ANIM 4 instead of whatever is appropriate for the current BODY. It requires you to have had a null SPACE action before or that action (and related ANIMs) get played instead.
    • The ANIM you're left with depends on the SPEED you're left with. Only going up and down between E3 and E5 doesn't set your SPEED to 0 right at the end, and so you're sometimes left with SPEED 4 instead. This corresponds to walking up/down the stairs.
    • The transitions from E3-E2 and E4-E3 both end (in LIFE 550) with ANIM_ONCE walking idling. This seems to be why holding SPACE as they're ending causes exactly one cycle of the walking ANIM. Again, only works if the SPACE action is null.
    • There are details here that are not understood, like why the infinite walk between E3-E5-E3 doesn't work consistently.
  • Why is the player left with the flask body after trying to drink the flask while also entering a transition?
    • This only seems to happen if there was a frame or more between starting to drink and hitting the transition. If there is none, LIFE 58/161 sets PLAYER.LIFE to 59 but it gets overwritten on the same frame by LIFE 550 and so no code from 59 is executed. Only the hitpoints are added.
    • With a frame in-between, the BODY is changed and the ANIM starts to play out but is obviously interrupted.
  • When you're falling during vertical desyncing, you don't enter the falling ANIM because you're in LIFE 550. LIFE 549 is supposed to do all of this: set falling ANIM, player control 0 and inventory 0 (already 0), LIFE player_falling (which also sets falling ANIM and sends it to LIFE player_landing after FALLING = 0), set fall height. Because this stuff doesn't happen immediately, if you lag it so you fall to the ground instantly, it may never have time to happen. Hence there's no landing ANIM and you don't take damage.
  • There should always be a one-frame window after doing something has set VAR 0 to 0 but not removed the inventory access before the inventory actually becomes unavailable, at least if LIFE 549 was executed before whatever set VAR 0 to 0 in the frame.



GAME WORLD

  • The game world is a cube of size 65536 (-32768 to 32767) that wraps around in all directions.
  • Coordinates – X: West-East, Y: vertical (inverted), Z: North-South.
  • The three kinds of coordinates are:
    • ROOM: Local coordinates relative to the center of the room the actor is in.
    • WORLD: Coordinates relative to the center of the room the view is currently in (usually the PC's room).
    • ZV: Bounding box coordinates relative to the center of the room the actor is in. Generally 880 units higher up than the ROOM coordinate (for Emily).
    • ROOM and WORLD coordinates are at the actor's feet while ZV is the centerpoint of their bbox, and thus in the air, for almost all actors (there's a few exceptions which are most likely erroneous).
  • Because of some kind of rounding, sometimes positions will be one off from what you'd expect. In the guide, this has sometimes been rounded back up or down to the nearest round number in contexts where the difference is not permanent (so 1699, 1700 and 1701 could all amount to the same thing).
  • The rooms aren't really connected in the way suggested by how they're displayed in the Viewer. The room the PC is in is always placed in the middle of the plane (its center at the origin). If an actor's ROOM coordinates hit a room trigger, it causes the game to stop checking for collisions with things in the previous room and start checking for those in the new room. Thus the whole floor (the rest of the colliders, triggers and most actors) effectively doesn't exist all at once, and for this reason moving around OOB, you still have to pass through every individual room along the path to make the final destination reachable.
    • Most but not all actors are loaded in on a basis of whether they could be seen from the present camera view or not. This usually roughly translates to being in the same room as the view or any adjacent one. What determines this is the actor's LIFEMODE. More under "actors".
    • Actor-actor collisions and hit/fire collisions are checked regardless of which room each actor is in.
    • Dropped or thrown actors cannot move between rooms even if they end up inside room triggers.
  • Floors: The game has several areas that are completely zoned out from each other. They're referred to as "etages" in the game's files.
    • E0: loft
    • E1: 3rd floor
    • E2: 2nd floor
    • E3: 1st floor
    • E4: cellar
    • E5: caverns
    • E6: end
    • E7: outside (only used in cutscenes)
    • When a new floor is entered, the game loads in all of the colliders at once but only checks for collisions in the actor's current room.
  • What your relative position to another actor or collider is (left, right, top, bottom) depends on your orientation as well as position.
  • All bounding boxes etc. are axis-aligned, i.e. they're rectangles with orthogonally aligned sides. The only exception is camera triggers.
  • The three angles for actors (alpha/beta/gamma) correspond to their pitch/yaw/roll, so the commonly used one is the "beta", the yaw.
  • The actor being followed is referred to as CURRENT_TARGET in the code and the focused actor in this guide.
  • There's no real reason for the room triggers to be as big as they generally are.
  • If you enter a room trigger that causes another trigger to load in where you're stood, you instantly trigger that one as well without being able to do anything in-between. If you stand inside two room triggers at once, the same one always takes preference.
  • The compass directions (South, West, North, East) are shown correctly by the Room Viewer's default view which also corresponds to the map given in one of the books (Story of a Louisana Plantation). Thus the stairs down from the loft are on the E side of the room etc.
  • Every time the game has some kind of proximity check, it seems it uses a primitive method of summing the X-difference and Z-difference (and presumably Y-difference) between the coordinates instead of calculating the real distance by Pythagora's.
  • There's a few rooms cut from the shipped versions of the game:
    • E2R9 – some kind of connecting passage between R7 and R10 that also has two camera views, neither of which is fully drawn-out. One of these can be reached in-game. Instructions under "Camera views".
    • E3R6 – a room in which the staircase leading to the cellar turns towards the South.
    • E4R1 – what looks like another, perhaps hidden, stairwell exit.
    • In addition, E5R2 has a partially blocked-off Eastern branch that's still accessible by running through what looks like a part of the tunnel wall in R5. You can clip out the other end to get back to the worm tunnels.
  • Some rooms have colliders in the corners whose sole purpose is to prevent the player from entering a blind area where they can't see themselves in any camera view. That or to prevent clipping into the walls.
  • An actor reaching the edge of the plane causes some of its polygons to be stretched out because some vertices that are meant to be connected are on opposite ends of the world. More under "3D wrap-around".
  • The walls are 3750 units tall inside the house and 2000 units underground. If you're exactly 3750 units above the floor level inside the house, you can still trigger triggers but can pass over the colliders.
  • When you enter a new room, if a door is loaded in around you but you landed inside the room trigger exactly with no further movement, you can avoid the door opening, or more generally colliding with the thing you're inside or right next to.
  • Most wall colliders overlap at the corners. This might have simply been the easiest way to edit them in but it does have the effect of preventing sideways clipping through them. More under "sideways clipping".

COLLIDER FLAGS

  • Flag 0001 and 0008 are required for the game to set the HARD_COLLIDER variable with the ID of the collider in question. Flags 0001 and 0002 (climbable) being set cause the HARD_COLLIDER to be set to 255. If 0001 isn't set, colliding with any collider does not alter the HARD_COLLIDER value, though actors are still ejected from it. This is probably a somewhat redundant implementation but flag 0001 could still be described as "should this collision affect HARD_COLLIDER".
  • The 0004 flag is unused.
  • There are colliders with the 0008 flag set that aren't really intended for the player to interact with them. Instead, they seem to be used for instantiating actors that have the room scripts for that room.
    • The two ways the game instantiates actors are:
  1. Actor position will be set as given in OBJETS.ITD and the size will be the same as the BODY bounding box.
  2. Size and position are instead set to match those of a particular collider.
    • The zvType value determines which option the game goes for.
      • 1-2-3: use values from OBJETS.ITD. The difference is that some of these adjust the bounding box after copying in from BODY in some way.
      • 4: match a collider. There is another field (not shown in OBJETS.ITD) which specifies which collider ID to use as the reference.

TRIGGERS

  • Shown in the Viewer in red (room triggers), yellow (floor triggers), orange (effect triggers) and a mosaic of camera triggers.
  • Room trigger IDs are unique per floor and correspond with which room the trigger sends an actor into. Floor triggers all have unique IDs and their effects are determined by LIFE 550. Effect triggers are unique per room and their effects are defined in the room's script[s]. Camera trigger IDs are unique by floor.
  • The effects of floor triggers (0-18) are defined in LIFE 550, which the player automatically enters after hitting any such trigger.
    • If you hit a floor trigger, and a LIFE other than your own is polling for PLAYER.TRIGGER_COLLIDER, if the floor trigger happens to have the ID the LIFE is looking for, it will have the same effect as standing in an effect trigger with that ID. This only seems to be relevant in E6 where leaving the floor through the E5R11 side can cause a fireball to be fired (more under "Pregzt"). There are no floor triggers anywhere else that can trigger anything other than a transition.
    • Hitting a camera trigger doesn't affect PLAYER.TRIGGER_COLLIDER.
  • All the triggers are activated based on the actor's ROOM (not WORLD or ZV) coordinates.
  • The internal tags for the three kinds of triggers are: 0 (room triggers), 9 (effect triggers) and 10 (floor triggers).

CAMERA TRIGGER TAG?

  • The player is usually the only actor that can trigger non-room triggers. However, camera triggers are triggered by whichever actor the game is following (not always the player).
  • If an actor hits multiple room triggers at once, the priority is dictated by the order of those triggers in the ETAGE game data file (not based on their IDs).
  • The actor 0040 flag is what determines if collisions with room, floor and effect triggers can occur. This is set to 0 during all transitions based on an instruction in the TRACK in question. Camera triggers can still be entered.
    • The related code is completely skipped. There is no special usage of the HARD_DEC (trigger collision variable) field like with the HARD_COL field when collider collisions have been disabled. HARD_DEC is simply -1 if trigger collisions are disabled.
    • The 0040 flag is never changed directly by the engine.
  • Room triggers have no flags set. Effect triggers have flags 1 and 8. Floor triggers have flags 2 and 8.
    • It seems flag 8 the one that causes the game to change the player's TRIGGER_COLLIDER.
  • Looks like the game ignores collisions with other floor triggers during a floor transition (MOVE TRACK) specifically even after the step where "enable triggers" has been called. This was tested by making the PC fall down due to gravity and hit another floor trigger (in E3R5) while also having hit the target position for being sent up to E2.
    • Alternatively the game didn't have time to react to the new TRACK calls.

TRACKS

  • The file called "LISTTRAK.PAK" contains all the so-called TRACK instructions which guide actors moving along a set path. This covers things like birds crashing in through windows and the player moving up and down stairs. The Viewer shows the actor's TRACK and TRACKPOSITION. The latter tells you which instruction is being executed.
  • The numbers on the left in the TRACK file are byte offsets for each instruction. Some instructions require extra parameters, which is data stored in the next few bytes. This is why some numbers are skipped. The game also reads the track instructions based on byte offset numbers.
  • TRACK scripts require calls to DO_MOVE to move to the next step. Some commands are executed in one frame, others (like rotating) happen bit by bit on every DO_MOVE call. Multiple commands are never executed on the same frame, unlike LIFE scripts, which causes TRACKS to be a bit "sluggish" and allows potential exploitations of this slowness.
  • Some of the less obvious commands:
    • disable triggers (disable the 0040 flag): disables being able to hit triggers other than camera triggers so things like entering staircases don't happen multiple times.
    • disable collision (TEST_COL 0): makes sure the actors don't get caught on things (except they can still be caught by lightweight pushables).
    • mark X: a marker that associated LIFEs can make use of to know when the TRACK has reached a certain position (via an IF MARK == n clause or such). Has no other function.
    • rewind: starts the TRACK again from step 0. Used for creating patrol paths and the dancers' endless dancing.
    • walk stairs on X/Z: explained below.
    • rotate: these commands are absolute and use the same 360-degree circle as the Viewer, e.g. "rotate 90" means the actor turns to face due East, 180 is due North etc.
      • if the command has one parameter, it happens slowly, if it's three parameters, it's instantaneous.
    • speed: sets the actor's SPEED parameter (only used with the PC), used to get them into the right ANIM. More under "speed".
    • store position: records the actor's current coordinates for use with walk stairs commands.
  • "goto" istructions use normal forwards movement and rotation (same as MOVE MANUAL) to guide the actor into a new position (after LIFE 550 has changed the ANIM_MOVE array). The actor can either turn left, turn right, or do nothing if it's already facing the target point, with a threshold of about 4 units (1.4 degrees) on either side within which no rotation will happen. This is to prevent the actor from shaking left and right on every frame in some cases.
    • This means if you want an actor following you (which uses almost exactly the very same code) to face a particular angle, you might not have to be in the very most exact position. The error margin is tan(4/1024*360 deg) * 1000 = 24.5486 units per 1000 units of distance from the actor in question.
  • Indecision bug: An actor will also end up not rotating at all if it's facing directly away from the next target point of a TRACK or target actor of MOVE FOLLOW. This is easiest to see if you enter E3R2 from R1 with the pirate in its initial position and with you being at or near X 100 in R1, then waiting until the pirate is around Z 2000, then pulling back to R1. This should cause the pirate to go straight to step 4 of TRACK 6 and because it's facing exactly South while the target point is due North, it won't rotate at all and instead walk out of the room. The same can be done with actors that are facing non-orthogonal angles, however due to the granularity of positions, the bug tends to end quickly, unless the angle is a precisely diagonal one.
      • It may be possible to make a non-orthogonal or interorthogonal angle work despite the tangent function only having 8 rational solutions within a 360 rotation (i.e. only 8 pairs of integer X- and Z-displacements, and their multiples, give a rational tangent function and thus a rational angle, these pairs being (1, 0) for 0 degrees, (1,1) for 45 degrees, (0, 1) for 90 degrees etc.). There is still the possibility the game will systematically round the actor's position down or up in just the right way so some angles near those 8 could also work. This has not been verified.
  • "walk stairs on X/Z" is the same as goto, but the actor's Y-position is being interpolated between wherever they were when the TRACK's "store position" command was executed and the point indicated in the walk stairs command itself. Except it only looks at the X- or Z-distance between the points, depending on which command was used.
    • The same indecision bug works with this command. This can be seen if you walk backwards into the N stairs in E1R7 with Z-position being 3674 (or the S stairs with -4326). The other transitions will all first rotate you and so this is the only one where this works, unless you've managed to lag or otherwise bypass the target point (Y-threshold) completely in which case the situation becomes analogous.
    • More under "stairs".
  • The "rotate" command doesn't have the same indecision bug if the actor was facing directly away from the target angle.
  • The warp/goto commands don't interrupt an uninterruptable ANIM like a knockback or jumping so the player can "cheat" on the supposed starting positions.
  • There is exactly one instance of a warp command that has five parameters. The fifth one is time (in frames) that the warp should take, i.e. it's not really a warp. This is done with the zombie in E0 as it's rising from the floor. Other similar cases are handled through playing ANIMs but ANIMs can't cause actors to rise or fall.
  • When determining whether target locations have been reached for the goto command, the primitive underlying maths look at the combined X- and Z-difference between the actor's position and the target one (the sum must not exceed 400). Thus it counts if the actor's actual position (i.e. ROOM coordinates, not taking MOD values into account, more under "movement") is within a square that has been turned 45 degrees, has a diagonal of 800 units and is centered on the target coordinates. This is why warp commands are often used to ensure the position ends up being exactly right at the end.
  • After a TRACK is finished, TRACKPOS remains at its last value, but this shouldn't make any difference for the next TRACK.

STAIRS/TRANSITIONS

  • Stairs/transition movement is based on instructions given in the LISTTRAK file (see the section called "tracks"). Whenever the player has entered a floor trigger, the engine sets the player's LIFE to 550. This LIFE returns camera focus on the player and removes inventory access. It also contains further instructions for each individual trigger on which TRACK to send the player into and what else needs to be done.
  • "Goto" istructions use normal walk and rotate movement to guide the player into a new position, only the target position is not landed on exactly. This is why warp commands are often used to ensure the position ends up being exactly right.
  • If you're already facing the right exact direction entering stairs, this skips the slow "rotate" command if there was one.
    • This also works if you were turning at the time when you enter, landing on the right angle right as you hit the trigger, or if you finish turning the quadrant after hitting the stairs.
  • Stairs and transitions have a lot of subtleties going into their exact workings. These stem from the order of execution of TRACK commands and other phenomena. The gist is there's ways to manipulate your position after hitting a stairs trigger that may make it a bit faster to complete the TRACK, or potentially allow further exploitation. Multiple phenomena play into the mechanics. Here are some common denominators.
    • You can lag into a transition trigger to get closer to the destination with faster movement, since the transition ANIMs are all relatively slow (slower than walking). This may be worthwhile if you can combine it with an inventory action.
    • You can also use lag right at the start of a transition, but this has to be done with the menu method. This way you can get another full keyframe of running, in theory. Any such movement fails if there are colliders in the way and collisions have not yet been switched off.
      • You can also get a keyframe of walking directly following this, if your SPEED is still 5, since the SPEED 5 ANIM in transitions is the walking ANIM. This might relate to the game being unable to end an ANIM short (and thus prevent the movement) when your SPEED is 4 or 5, but this is not clear. If you're walking backwards (SPEED -1), this will not work since the new ANIM_MOVE has the idling ANIM for that SPEED.
      • Whenever your SPEED is set from 4 or 5 to 0, there is a small bit of extra movement (e.g. 15 units). Thus the total lag snap distance can exceed the keyframe offsets. A snap of 370 for kf0 of walking has been observed (346 + 24).
      • If you walk into the stairs instead, SPEED 4 means the ANIM_MOVE goes to the walk_stairs ANIM (or crawling) and thus the snap will be even smaller (e.g. 222 + 15).
      • Can't for some reason get SPEED 5 snaps in E1R6 or E1R7 at all. This testing was done in E3R11 but the other TRACKs can behave differently by the looks of it.
  • When collisions are switched off, it doesn't seem to prevent picking things up, nor interacting with doors. It's not clear how this could be used to one's advantage. In theory, if there was some such interaction that affected the player's trigger collision flag, this could be used to regain the ability to move between rooms after abusing a transition to get vertical desync, but there is no such interactions as only the transitions themselves disable and enable the flag.
  • There are only a few TRACKS where in theory, there's a chance to interrupt it before it has finished by hitting another trigger. This is numbers 31, 32 (E0-E1-E0), 37 (E3-E2) and 39 (E4-E3). The first two have "enable collisions" and "enable triggers" in the opposite order and the latter two have a rotate command as the very last command. However, even if you somehow could enter another floor trigger during that frame, that would lead into another TRACK that re-enables collisions anyway. It's also not clear whether or not the TRACK can actually be interrupted this way. (After some tests it seems unlikely)
  • The steps in staircases are merely cosmetic. In reality, the game saves your starting position ("store position") and interpolates your Y-coordinate between that and the target value. The commands "walk stairs on X" and "walk stairs on Z" in the TRACK file determine whether the game interpolates the Y-value based on proximity to the next waypoint along the X or Z axis. This explains why you don't have to be very close at all to the actual waypoints along the other axis for them to trigger.
    • The walk stairs command ends when the player's WORLD-Y is within a 100-unit threshold of the target Y-position on either side. The X- and Z-positions don't matter at all at that point. There seems to be some leeway because there are often frames when the position is e.g. 704 or 896 with a target of 800 without the instruction ending.
  • In single-segmented runs especially, hitting approximately the center of a staircase might be fastest since it stops staggering left and right. At least if the staircase has a waypoint. The general "transition strategy" should be considered, though in AitD 1 only the E1R7 stairs seem to have a lot of variation.
  • Any time you're in the middle of a turn and you enter staircases, most of them will complete the turn before anything else happens. This is all the staircases where there's an initial slow rotation to face the right angle. It doesn't matter if you were turning in the right direction or wrong and whether or not you had the lamp out or were holding SPACE. There may be a small snap turn first before gradual turning resumes.
    • This means hitting a staircase at the right exact angle but being in the middle of a turn does not skip the rotation command because the rotation will have continued before getting to it.
      • This also applies if the turn was a delayed one (e.g. lamp turn).
    • Any time the current rotation ends at exactly the right angle, the rotation command will be skipped.
    • None of this works when turning to the right in E1R7 in either staircase. You can only turn to the left in E1R7 if your relative facing to the waypoint target (presumably) is on its right.
    • There's no evidence of manual lamp turns performed on the first frames after hitting a trigger. This seems to be impossible.
    • Can't get any kind of lamp turns to happen during the E1R6 transition.
  • The staircase rotate command takes 2 seconds to finish regardless of how large the angle to cover is. This means it's never faster than manual turning, unless you were using the push action to move.
  • You can speed up or revert the TRACK-governed turns with s/l manipulation like with rotating doors etc. More under "timers".
  • The PC always turns around the way that's faster when needing to rotate to go up or down stairs, after any preceding turns have finished.
  • The disabled collisions in stairs doesn't prevent collisions with pushable objects, meaning you could get stuck in E3R11 for example if you put a chair inside the stairwell. Doing that doesn't seem to have any interesting effects anyway.
  • Taking the north stairs or south stairs down from E2 has exactly the same effect.
  • When observing the Y-position at a given horizontal position when entering the staircase in the same way multiple times, slight differences are seen in the exact positions. Probably to do with lag.
  • Jumping into a staircase (and generally moving into them with uninterruptable ANIMs) makes the player move deeper in before assuming normal stair-climbing movement. This means you can jump through the E5R0 trigger to clear the stairs quickly (and without risk of getting turned back). The keyframe you were on when you hit the trigger is incremented and the movement resumes from the start of the next keyframe, meaning you're losing a bit of time if you don't skip most of any slow keyframe that you had just entered.
    • The same applies more broadly on any transition, but the other critical example is E5 going through to E4 which is also slow if you don't jump through.
  • Extra stairs movement from lag: If you lag the game on the last few frames right at the end of the transition, it causes you to move forwards further compared to no lagging. This is because of the last few commands in the TRACK normally being executed very quickly but this way you're drawing them out.
    • A difference of around 300 units has been observed, though this may vary.
  • If you're holding down right or left when jumping up the stairs from E5, the game rotates you cw at the top. This effect is the same if you're just walking up and getting a lamp snap or just starting to turn half-way through. The transition seems to always start this rotation right as you're reaching the end since you're not perfectly aligned with the target point, and holding the rotation bind just makes that turn continue.
    • If you try doing a slt during the erroneous turn, you can complete the quadrant by holding the same wrong (left) button down whereas holding the other one doesn't do anything.
  • Sometimes you'll be sent back down the E3R11 stairs after climbing them.
    • Sometimes you get a 30-unit offset from (850, 0, 50) to (820, 0, 49) before the climb has started when coming up the E3R11 stairs. This happens on the frame the TRACK advanced to position 1 (it has just disabled triggers). Because the start position is not stored until after this has happened, it in part explains why you'll end up at different positions at the end. There's probably things like small amounts of global lag also involved though, and possibly which SPEED you had when entering the staircase. Other staircases probably behave in a similar way, but E3R11 just happens to allow the climb to finish on (900, 0, 50) where you're inside the upper stairs trigger sending you back down.
    • You're sent back to E5 the more frequently the higher the framerate regardless of anything, since this means you're less likely to skip a position due to lag.
    • If the framerate is high enough, the E1R6 stairs can behave similarly.
  • There is a way to interrupt a transition. It's based on this: in the middle of a transition, you hit a door (use lag and Timer 2 manipulation to get to one). Collisions with actors can still happen and so it should cause the door to open. Afterwards, you are restored control and so MOVE changes. The TRACK is never completed. You're left with the wrong ANIM_MOVE and no INV but you might also be left without collisions. This is basically useless without triggers being active though, and only going between E0 and E1 are there transitions where triggers are re-enabled before collisions, meaning you could, in theory, interrupt the TRACK just before collisions are back on to no-clip around afterwards.
    • If you get past the target point to turn back around (especially doable with gravity on in many places), you can definitely reach nearby doors unless the falling prevents the right kind of collision from happening. After hitting the door, if you need to get back up or go further down to reach the target point just in time, you can just manipulate Timer 2 to prevent the door from fully opening too soon.
    • You can't do anything with this in E3R11 seeing as how are you going to get to E5 if the track doesn't complete? TRACKPOS -1 is what triggers the room warp.
    • The only other seemingly useful effect is being left higher up or down than usual. If you have triggers left on, you could then hit certain triggers like the E3R11 stairs trigger despite the desk being there, but this is about as good as it gets, unless you can get up to ROOM Y -3750 exactly (!) at which point you can pass over walls inside the house but still activate triggers.
    • The better approach to this is probably to start opening a door first, then get knocked back so you're freed. Now trigger the transition while delaying the door opening until you're on a suitable step of the TRACK. There are no TRACKs that disable collisions before triggers unfortunately so you can't noclip this way by interrupting the transition at the start.
    • If you could somehow get into this no-clipping state with triggers left on, because this is implemented in its strange way (see "TEST_COL"), you could at least make the game think you're hitting collider 0 and e.g. pick up the talisman this way.
  • Moving between E5 and E6 doesn't set your facing like the other transitions do.
  • If you have control but don't lose the TRACK movement in a staircase, you can sort of control your direction if you have a MAN_ROT action and hold space while a turn has just started.
    • To get into this kind of state without cheating is probably impossible. LIFE 550 sets INV and VAR 0 to 0 at the same time as well as switching to MOVE TRACK so you'd have to be able to affect just VAR 0 while in LIFE 550 without also setting MOVE. This doesn't seem to ever happen. Using the INV + control restoration after throwing in LIFE 549 is no good because then you're not in LIFE 550.
  • You can lag the game when you enter E5 through E4, before you've rotated S, you can get Emily to enter the wall on the side. If you move directly to the E, it seems you can get to X 125. This leaves you inside the trigger and sends you back to E4. However, if you could avoid being in the trigger (easy if you were facing an angle like 89 degrees) and also got to X 152, you could now run through the wall OOB, presumably acting as a shortcut compared to other routes.
    • The X-position always ends up being 125 at furthest (the offset is 425, on kf2 or kf3 of crawling). If SPEED was 5, the ANIM would be walking instead, but that ANIM's kf's all have a smaller offset anyway.
    • Several frames will pass between SPEED being set to 4 in TRACK 40, and the player getting to E5, thus you can't possibly be in your running ANIM after the transition. It doesn't look possible to get further into the wall. Going the other way around, the distances to the walls are even greater with similar code preventing having SPEED 5.
    • If you jump through to E4 instead, if you have kf 5 after the warp and an angle of 180 (+-3.2) degrees, you can lag the game to get to Z 5925. This isn't quite enough to run through the N wall, for which you'd need Z 5953. There seems to be no way to get any further as you're immediately turned to face the W afterwards.
    • What does work is if you first make sure the barrels have been moved, jump through to E4, start to rotate as soon as you can (kf 3 works), do two slt's to face E while keeping the same kf, and lagging the game once again. You may have to face due E as you go through but possibly not. Now you just lag after the transition and you should go far enough into the wall to get OOB. You can even drop something at the end of the jump to get the hover if desired.
  • After entering a staircase, if the warp is immediate, the residual movement from the previous ANIM can cause you to move sideways after the warp, which can in turn cause you to enter a rotation during the transition. This could enable you to end it OOB even if it otherwise wasn't possible. It might be better to walk into the trigger instead of running because more residual movement is kept this way as the SPEED rolls down to 3-2-1-0. The movement you get also depends on what part of the walking ANIM you were in at the time.
    • E0-E1: Because the stairs descent ANIM only has a speed of 238 (all kf's), the player can only just barely get (1-unit margin) far enough into the thick E wall to pass through if they start from a position right next to the wall. During the transition, even if you use the residual movement to get to X 15 (next to the wall), you now surely cannot turn to face the E during the transition without at some point being W of the target X point (0). Thus this should be impossible to do.
    • E1-E0: Because of the warp command at the foot of the stairs, your starting position seems to be set in stone more or less. So there should probably be no sideways movement available during the climb (SPEED 0 is even issued before the warp).
    • E1-E2: Doesn't seem to work because you're always put at Z 250 no matter what.
    • E2-R1: The target points seem too far away from the walls to end up OOB.
    • E2-E3: Can be done easily but there's nowhere to lag OOB to near the foot of the stairs.
    • E3-E2: No walk stairs command in E2, there's a rotation first, then warp, so no chance.
    • E3-E4: Here it IS possible to use a long series of lagging (and timer manipulation) to eventually end up at the foot of the stairs but outside the room.
    • E4-R3: No walk stairs command in E3, there's a rotation first, then warp, so no chance.
    • E3-E5: Can get some residual movement this way but seemingly only towards the SE.
    • E5-E3: Your position at the foot of the stairs is set.
    • E5-E6 (either exit): Collision flag is never switched off anyway.
    • E6-E5 (either exit): Collision flag is never switched off anyway.
  • In the E3-E5 transition, you could bypass the locked door. The method would involve using the natural rotation at the top of the stairs (since your position and angle are otherwise set), and just lagging and timer-reverting a lot of times so you keep moving directly N without the transition quite being able to finish. This seems extremely slow.
  • When running into the E1 stairs, if you save on the frame after the next floor has been loaded in, reload, and immediately lag the game, you can get a snap that wouldn't otherwise be possible. This isn't really useful since you just need a little bit of offset at the top of the stairs to manipulate turning to the side near the bottom, which is enough to get OOB (even if it wasn't possible otherwise).
    • Possible:
      • E2-E3 (don't even have to save)
      • E3-E4
      • E4-E5 (don't even have to save but doesn't get you far enough by itself)
    • Not possible:
      • E1-E2
      • E2-E1
      • E3-E5
      • E5-E3 (you're turned before the warp)
      • E5-E4 (don't even have to save but doesn't get you far enough)
  • If you could interrupt the transition from E4 to E5, you could probably get the gravity flag to stay on in E4 this way. Furthermore, this should result in jumping being possible inside the house. However, this should be impossible to do since there's no doors in E4 and seemingly no other code that could interrupt the transition.
  • You can use a lowered framerate to cause goto and walk stairs commands to end a bit further regardless of how quickly the last commands in the TRACK are executed afterwards (if the first position that could have cause this to happen is skipped due to lag).
    • The theoretical limit to the horizontal difference in the position you end up in going up or down stairs should be no greater than the horizontal movement that corresponds to a Y-difference that makes you completely miss the target point (past this, you'll simply turn back or walk forwards indefinitely due to the indecision bug). Of course you'd need the slope to be very steep for this to be possible. In practice a difference of around 350 has been observed after brief testing.
    • You shouldn't be able to do anything with this, presumably, that wasn't possibly by lagging the game at specific times, but this is difficult to prove.
  • Stairs don't use modX/Y/Z values, instead setting the coordinates directly. This suggests that any sudden [forwards] snap, such as a lamp snap, shouldn't be possible in them, at least not based on the same mechanism.
  • The stairs ANIMs have a "pulse" of about 80 frames so each step takes 0.75 seconds.

DOORS

FRONT DOORS/JELLY

CAMERAS

CAMERA VIEWS

CAMERA DEFOCUS TRICK

WRONG PICKUPS/WRONG TRIGGERS

ROOM/VIEW DESYNC

OBJECTS AND ACTORS

OBJECTS

ACTORS/ACTIONTYPES

ACTOR SERIALIZATION INTO OBJECTS/OBJECT FIELDS/ACTOR FIELDS

BODYS

ANIMS/ANIMATIONS (GENERAL, NOT MOVEMENT)

ACTOR FLAGS

PLAYER CHARACTER

EMILY AND EDWARD DIFFERENCES (ANIMS)

PLAYER STATE

BODY/IN_HAND

BODY/IN_HAND DESYNC

SPACE

MOVEMENT

MODX/MODY/MODZ

ANIMATIONS (MOVEMENT)

EMILY AND EDWARD DIFFERENCES

SPEED

CORNERING

ROTATION

ACTIONS

(SPACE)

PUSHING

JUMPING/HOVERING

CLIMBING

GRAVITY/FALLING

VERTICAL DESYNCING

ITEMS/INVENTORY/MENUS

INVENTORY/ITEMS

FLASKS

THROWING THINGS

BOW/FIRING ARROWS

FIRING A GUN

ENEMIES/FIGHTING

PREGZT/BOSS FIGHT

CTHONIAN (WORM)

E2 ARROWS/AXES

OTHER ENEMIES

= HITFORCE/DAMAGE MANIPULATION

[NOT] DYING

TIMERS/CHRONO/TIMER MANIPULATION

LAGGING/FRAMERATE

SNAPBACK

DELAY TURN/DELAY SNAP

PICKUP TURN/SNAP

PICKUP TURN/PICKUP SNAP

LAMP TURN/LAMP SNAP

SAVE/LOAD TURN (SLT)

QUICK ROTATION

OOB/CLIPPING

SIDEWAYS CLIPPING

CONVEX CLIPPING

OPENING CLIPPING

LAG MANIPULATION/LAG SNAP/LAG OOB

SNAPBACK CLIP

TRIGGER BOUNCE OOB

PUSHABLE OOB

CHAIN CLIPPING

PUSHABLE LAG OOB

PUSHABLE WEDGE OOB

PUSHABLE OOB OOB

PUSHABLE NARROW OOB

CLIMB OOB

FALL OOB

COLLISION OOB

PUSH CLIPPING/LIGHTWEIGHT CLIPPING

PRACTICAL TIPS/APPLIED

PRACTICAL TIPS/OPTIMIZATIONS

TIMING CERTAIN ACTIONS

THEORETICAL IN-BOUNDS/GLITCHLESS RUN

EXPERIMENTAL SPECULATION

MIGHT HELP IN AITD 2 OR 3

TAS-ONLY/GLITCHING/CRASHING/SOFTLOCKING/MEMORY CORRUPTION

GENERAL

THROWN OBJECTS SOFTLOCK

3D-WRAP-AROUND GLITCH

RENDERER/RENDER BUG/2D-WRAP-AROUND

POTENTIAL EXPLOITATIONS

MEDKIT RENDER BUG TRIALS

SOUND BUG

MISCELLANEOUS

MISCELLANEOUS/COMBINED TRICKS

TECHNICAL NOTES

(Probably) Pointless Trivia

UNANSWERED QUESTIONS

Alone in the Dark 2

Alone in the Dark 3

Jack in the Dark

Personal tools