Movement
- Using mouse is faster than keyboard, even running from keyboard.
- Using run button is not necessary with mouse. It archives full speed anyway.
- Mouse sensitivity just affects how much speed is needed, not how much can be achieved.
- Fastest method of motion is strafing forward and sideways from mouse (backward and sideways is slower).
- This produces motion at 45 degrees from view direction.
- This method of motion is fast regardless of angle, but zigzag from having wrong direction should be avoided.
- Only the main direction matters (except for turning).
- The subdirection value is weird: It can be negative.
Scale
- Each tile is 65536 units.
- Player radius (∞-norm) is 22528 units.
- There are 360 directions in full circle (degrees).
- There are 20 subdirections in each direction.
- There are 65 door positions.
Speed
- Forward: Max. 14999 units per frame.
- Backward: Max. 9999 units per frame.
- Sideways (strafe): Max. 14999 units per frame.
- Straferun (diagonal): Max. 21212 units per frame.
- Backwards straferun (diagonal): Max 18026 units per frame.
- Maximum turn is 5 units per frame (= 5 degrees per frame).
- Doors open/close at 1 position per frame.
- Example: Rectangle room might be 10 N, 15 W = 25 frames, but diagonal = 26 frames
Primary direction
Each direction has associated primary direction. This is the direction "use" command searches for object (door, elevator, secret door, etc...)
- For 45 degree direction (North-East), it is North.
- For 135 degree direction (North-West), it is West.
- For 225 degree direction (South-West), it is South.
- For 315 degree direction (South-East), it is South (not East).
- For every other direction, it is the nearest cardinal direction.
So for instance, if strafing West at 135 degree angle, you can open door pointing to West, but if strafing West at 225 degree angle, you can't open that door without turning.
Also, doors to East (like the normal elevator door and elevator in E1L1) can't be opened at either 45 degree angle suitable for straferunning East.
Weapons
Pistol
Has no rapid fire ability. Fires every 25 frames.
Machine Gun
While holding down the fire button, fires every 12 frames. Fires every 25 frames if the fire button is released and pushed again. As a result of this, it's slightly more efficient to hold down the fire button even if every other shot misses.
Chaingun
While holding down the fire button, fires every 6 frames. Acts like the machine gun, except with an involuntary second bullet, so each volley is an even number of bullets. Volleys start 25 frames apart from each other if the fire button is released and pressed again (or 19 frames after the second bullet of the last volley).
Player-to-enemy damage calculation
All random numbers are 0-255.
- Attacks where enemy hasn't "woken up" yet do double damage and wake up the enemy.
- If the attack connects at the same frame as enemy would wake up from seeing you, it still counts (your attack is evaluated first).
- With bad luck, attack can do 0 damage even if it hits.
- Knife attacks do random / 16 damage (max. 15).
- Gun attack damage depends on distance.
- The distance is calculated from differences in tile positions of player and enemy.
- The norm used is ∞-norm (maximum of x- and y-distances).
- If distance is 0-1, you hit for random / 4 damage (max. 63).
- If distance is 2-3, you hit for random / 6 damage (max. 42).
- If distance is 4-20, if random / 12 >= distance, you hit, and do random / 6 damage (max. 42), otherwise you miss. Maximum damage is 42.
- If distance is 21, the situation is the same as in 4-20, but due to RNG maximum hit damage is 39.
- From distance 22-, it is not possible to hit.
- These attack-related RNG throws are the only ones that are under player control.
The numbers are pulled from a table-based pseudo-random number generator. The table of values is (pulled from the
source):
0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66
74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36
95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188
52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224
149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242
145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0
175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235
25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113
94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75
136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196
135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113
80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241
24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224
145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95
28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226
71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36
17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106
197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136
120, 163, 236, 249
The RNG index is a value from 0-255. It increases at least once every frame and also whenever a random number is required, and wraps back around after it hits 255.
Enemy-to-player damage
- The chances of dodging an enemy bullet can be increased not only by running, but you also get a significantly higher dodge chance if the enemy is visible on the screen.
- The odds of dodging depend on the distance from the enemy.
- A point-blank shot against the player's back has a 0% chance of missing.
- Running while being shot at increases the odds of dodging by a flat 37.5%.
- If the enemy is visible, the odds of dodging increase by an additional 6.25% for each tile of distance between the player and the enemy. If the enemy isn't visible, this bonus is cut in half to 3.125% per tile.
- If running and the enemy is visible, the maximum distance they can hit from is 9 tiles.
- If running and the enemy is not visible, the maximum distance is 19.
- If not running and the enemy is visible, the maximum distance is 15.
- If not running and the enemy is not visible, the maximum distance is 31.
- The above values are different for SS guards and bosses, as they are hardcoded to be more accurate. The distance bonus of the dodging formula is cut by 1/3 and as a result their range also increases.
- If a shot hits, the damage depends on the distance.
- From a distance of 0-1, the damage is random >> 2 (maximum 63).
- From a distance of 2-3, the damage is random >> 3 (maximum 31).
- From a distance of 4 or greater, the damage is random >> 4 (maximum 15).
- Dog bites have a 70% chance of hitting and do random >> 4 damage (maximum 15).
- Schabbs' projectiles work under a different damage roll and there is no chance of missing if you are in the way. Each syringe does 20 + random >> 3 damage (range of 20 to 51).
- Rocket projectiles, such as the ones fired by Otto, do 30 + random >> 3 damage (range of 30 to 61).
- Fireballs from the fake Hitlers do random >> 3 damage (range of 0 to 31).
- Similar to the distance check for player damage, low RNG rolls are preferable for dodging.
Enemy AI
Enemies behave differently depending on if they can see you or not. Note that AI decisions are based on entire tiles, and the subposition of the player is not used as a tiebreaker if they line up with the enemy.
Enemy sees player
- List of enemy travel directions, in order of priority. If one direction is blocked, it will go down the list until something works.
- Diagonal towards the player. If their x tile is the same as the player, west will be the x component, and if the y tiles are the same, north will be the y component.
- Cardinal direction towards the player, randomly chosen between the two possibilities
- Other cardinal direction towards the player
- Cardinal direction away from the player, randomly chosen between the two possibilities. This is predetermined by the previous randomly chosen direction and does not use an extra RNG roll.
- Other cardinal direction away from the player
- If the enemy is less than 4 tiles away from the player, they will want more distance. In this case, use the above priority list but prioritize moving away from the player.
- An RNG roll is always used when determining the direction, even if the diagonal is free.
- If a door is blocking the enemy's preferred direction, they will open it even if it's locked.
- The odds of the enemy shooting the player decrease with distance.
- If the player is right up against the enemy, he's guaranteed to stop and shoot.
Enemy is awake but cannot see player
- List of enemy travel directions, in order of priority. If one direction is blocked, it will go down the list until something works.
- Cardinal direction towards the player with the largest difference in distance to the player. Skip if this requires turning around
- Other cardinal direction towards the player. Skip if this requires turning around. Also skip if the player is lined up directly behind.
- Direction previously traveled by the enemy
- Enemy will rotate until it finds a free direction. This includes diagonals and is the only way for enemies to move diagonally when they can't see the player. Any direction that involves turning around is skipped over. The direction of rotation (clockwise or counter-clockwise) is randomly chosen. The enemy will only check west, northwest, and north, which is possibly unintended but is what the code does. This RNG roll is not done unless this step is necessary.
- Turn around as a last resort
- If a door is blocking the enemy's preferred direction, they will open it even if it's locked.
Enemy reaction times
Enemies will react if they see you or if you fire a bullet within their floor code (enemies placed on deaf tiles will not react to bullets). Floor codes and deaf tiles can be viewed in the map editor. If a door is even slightly open between two floor codes, they will be considered conjoined and firing within one code will awaken enemies in both. Errors in floor code design can be exploited to awaken enemies behind locked doors and do some easy door tricks (see E3L3).
Different enemies have different reaction times once they're aware of your presence, with some of them incorporating randomness. All reaction times here are given in frames.
- Guard: 1 + random/4 (range of 1 to 64)
- SS and mutant: Both are 1 + random/6 (range of 1 to 43)
- Dog: 1 + random/8 (range of 1 to 32)
- Officer: Always 2, no randomness involved.
- Everything else (including bosses): Always 1.
Level editor
Memory addresses:
Domain | Address | Data Type | Signed | Endian | Description |
---|
System Bus | 288930 | Word | Signed | Little | Player health |
System Bus | 297006 | DWord | Unsigned | Little | Player X position |
System Bus | 297010 | DWord | Unsigned | Little | Player Y position |
System Bus | 297032 | Word | Unsigned | Little | Player heading (degrees) |
System Bus | 292836 | Word | Signed | Little | Player sub-heading |
System Bus | 296994 | Word | Unsigned | Little | Object types (150 entries, 60 byte stride) |
System Bus | 297034 | Word | Signed | Little | Object health (150 entries, 60 byte stride) |
System Bus | 271862 | Word | Unsigned | Little | Door openness table (64 entries) |
System Bus | 297007 | Word | Unsigned | Little | Object X (150 entries, 60 byte stride) |
System Bus | 297011 | Word | Unsigned | Little | Object Y (150 entries, 60 byte stride) |
System Bus | 297004 | Byte | Unsigned | Little | Object direction (150 entries, 60 byte stride) from 0 to 7, 0 being east and increasing 45 degrees counter-clockwise |
System Bus | 291294 | Word | Unsigned | Little | Level timer |
System Bus | 280712 | Byte | Unsigned | Little | Tile data (4096 entries) |
System Bus | 159344 | Byte | Unsigned | Little | RNG index |