Alone in the Dark (1-3)/Game Mechanics and Glitches
From SDA Knowledge Base
Contents
- 1 Alone in the Dark 1
- 2 ABOUT THE GUIDE
- 3 META
- 4 GAME
- 5 GAME WORLD
- 6 CAMERAS
- 7 OBJECTS AND ACTORS
- 8 MOVEMENT
- 9 ACTIONS
- 10 ITEMS/INVENTORY/MENUS
- 11 ENEMIES/FIGHTING
- 12 = HITFORCE/DAMAGE MANIPULATION
- 13 TIMERS/CHRONO/TIMER MANIPULATION
- 14 OOB/CLIPPING
- 14.1 SIDEWAYS CLIPPING
- 14.2 LAG MANIPULATION/LAG SNAP/LAG OOB
- 14.3 SNAPBACK CLIP
- 14.4 TRIGGER BOUNCE OOB
- 14.5 PUSHABLE OOB
- 14.6 CHAIN CLIPPING
- 14.7 PUSHABLE LAG OOB
- 14.8 PUSHABLE WEDGE OOB
- 14.9 PUSHABLE OOB OOB
- 14.10 PUSHABLE NARROW OOB
- 14.11 CLIMB OOB
- 14.12 FALL OOB
- 14.13 COLLISION OOB
- 14.14 PUSH CLIPPING/LIGHTWEIGHT CLIPPING
- 15 PRACTICAL TIPS/APPLIED
- 16 TAS-ONLY/GLITCHING/CRASHING/SOFTLOCKING/MEMORY CORRUPTION
- 17 MISCELLANEOUS
- 18 UNANSWERED QUESTIONS
- 19 Alone in the Dark 2
- 20 Alone in the Dark 3
- 21 Jack in the Dark
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 | 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 |
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. |
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!"
- You might also find this Windows .bat file handy:
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:
- Create a new folder.
- Unpack all files of LISTLIFE.PAK to that folder with quickBMS.
- Search for a file named "OBJETS.ITD" (in AITD root folder) and copy it there as well
- 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.
- Copy LifeDISA.exe to the folder and run it.
- 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.
- 4 colliders have been changed (size+position):
- E3R2:
- 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
- enter/keypad enter for "menu" and "select"
- '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.
- Other things that are always cached:
- PRIORITY.ITD
- 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
PAUSING
LIFE SCRIPTS
IMPORTANT/SPECIAL LIFES
IMPORTANT/SPECIAL VARS, CVARS, AND OTHER VARIABLES
INTERRUPTS
RENDERER
PALETTE
GAME WORLD
COLLIDER FLAGS
TRIGGERS
TRACKS
STAIRS/TRANSITIONS
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)