doom2.exe distance and motion calculation

Discuss anything ZDoom-related that doesn't fall into one of the other categories.
Post Reply
nogame4me
Posts: 3
Joined: Thu Jul 21, 2005 9:18 am
Location: Southern California

doom2.exe distance and motion calculation

Post by nogame4me »

I'm trying to understand how doom2.exe handles player and projectile speed. Here is some info I've been able to gather.

Gamestate is updated 35 times per second.

Normal forward run speed is 50. Rocket speed is 20. But these speeds must be on different scales, because rockets travel faster than a player running straight forward (no strafe run).

Also, the player has a width of 32 and height of 56, but horizontal and vertical scales must be different because the player looks to be about twice as tall as he is wide (on the screen), yet 56/32 = 1.75.

So how do these distances and speeds relate to each other? Perhaps if I can get answers to two questions, I can figure the rest out:

1. How does doom2.exe translate a player speed of 50 into horizontal units per second? It seems to be about 410 horizontal units per second, but I'm not sure about this.

2. How does doom2.exe translate a rocket speed of 20 into horizontal units per second? It seems to be about 520 horizontal units per second, but I'm not sure about this.

I downloaded the game source code, but it's a lot to sift through for someone who doesn't know C. Still, if anybody can point me to the relevant file(s)/routine(s), I'd appreciate that as well.

Thanks,

nogame
User avatar
Caligari87
Admin
Posts: 6236
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him
Contact:

Post by Caligari87 »

I think for projectiles, the speed might be how many Horiz. Units per tic, not second. A tic, like you mentioned, is 1/35 of a second.

Player speed might be different, I don't know.

Hope that helps a little.

8-)
User avatar
randi
Site Admin
Posts: 7749
Joined: Wed Jul 09, 2003 10:30 pm
Contact:

Post by randi »

Missile speed is straight speed. Player speed is actually an acceleration. The player's speed is added to their current velocity every tic, but they are also subjected to friction every tic to slow them down. Eventually, the player reaches an equilibrium between acceleration and friction, and they move at a constant speed. I would have to look in the source, which I don't have handy right now, to get the amount of friction.
User avatar
Phobus
Posts: 5984
Joined: Thu May 05, 2005 10:56 am
Location: London
Contact:

Post by Phobus »

That sounds confusing...

I won't be delving further into that for a while then. :?
nogame4me
Posts: 3
Joined: Thu Jul 21, 2005 9:18 am
Location: Southern California

Eureka??

Post by nogame4me »

Thanks for the help, people. After poring over the source code and learning lots of C++ along the way, I think I may have figured something out. Here's an explanation and a list of relevant files/modules.

The maximum user input for forwardmove is 0x32 (50 base 10). forwardmove is then multiplied by 2^11 and added to momentum. Momentum is broken into x and y components. The same calculation is done for sidemove, which normally has a maximum user input of 0x28 (40 base 10), except for a bug that allows a user input of 0x32 when SR50 is activated. However, for this explanation, I'll assume only forward run entirely in the x direction.

In an open field going at full forward run, the game attempts on every tic to advance the player by a number of units equal to the momentum, which is subject to a maximum value that is never reached under normal running conditions. After advancing the player, the game simulates drag by multiplying momentum by the fraction 0xe800/2^16 (29/32 base 10).

To get the cruising speed, in units per tic, use the sequence

s_0 = 0
s_k = 50 * 2^11 + (29/32) * s_k-1

Solving the sequence gives s_k = V * [ 1 - (29/32)^k ], where V = 50 * 2^11 * 32 / 3 ~= 1092267 is the limiting value of the sequence. This is how many units a player advances per tic going at full forward run. It takes about 4.57 seconds to technically reach full speed, but for all intents and purposes, full speed is reached in under one second, e.g. at one second, the player is at about 97% of full speed.

Multiplying V by 35 (b/c there are 35 tics per second) and dividing by 2^16 (b/c player and object dimensions are expressed in FRACUNITs, where FRACUNIT = 2^16) gives a player forward run speed of 583.3 units per second. From this, one may also compute other speeds, e.g. strafe running is about 747 units per second.

These speeds agree with rocket and plasma speeds. Rockets have a speed value of 20, so rockets advance 20*35 = 700 units per second. Plasma has a speed value of 25, so plasma advances 25*35 = 875 units per second. Of course, in Doom2, it's possible to catch up to a rocket by strafe running, but not plasma, i.e. these numbers seem reasonable. I also did a few trial runs using Dwango 5 Map 5, and the results were in the same ballpark. So, I feel somewhat confident about these numbers, except for two things...

First, this model predicts it takes 160 units (5 player diameters) and 1.6 seconds to come to halt from a full run after releasing the forward button. This seems too high. I'm hoping that I've simply overlooked something in how doom2.exe handles coasting to a stop. Also, the numbers I get do not agree with the following article:

http://www.doomworld.com/10years/demos/demos07.php

In the article, the author states: "Moving forward + run + strafe_left + strafe_on + turn_left makes you move about 580 units per second."

In other words, his SR50 speed is slightly less than my SR40 speed. I'm hoping it was a typo. I e-mailed the author, but so far no response.

Here are the source code files/modules I used:
g_game.c: G_BuildTiccmd
info.c: MT_ROCKET, MT_PLASMA
local.h: constants
m_fixed.c: FixedMul
m_fixed.h: constants
p_mobj.c: P_MobjThinker, P_XYMovement,
p_user.c: P_Thrust, P_MovePlayer
tables.h: angles and trig functions

Well, that's some of what I know. I also figured out that damn binary angle measurement, but meh, wasn't much help. Okay, any corrections here are welcome.

nogame
Kles
Posts: 32
Joined: Thu Jan 06, 2005 7:46 am

Post by Kles »

All I know is that with perfect SR50 you can jump the exit bridge on E1M4 and there is no shot in hell that you can do it with SR40 so it must be faster. Besides, I can see a difference in SR50 when I do it.
nogame4me
Posts: 3
Joined: Thu Jul 21, 2005 9:18 am
Location: Southern California

Eureka??

Post by nogame4me »

Yes, SR50 is faster than SR40. By my calculations, forward run ~= 583 units per second, SR40 ~= 747 units per second, and SR50 ~= 825 units per second. I'm hoping that the discrepancy with the doomworld.com article is due to a typo, i.e. that the author intended to say normal run, not SR50, makes you move about 580 units per second. This would be in line with the results I got.
User avatar
Nash
 
 
Posts: 17501
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Post by Nash »

o_O

You, sir, are a genius.

I wish I was even at least half as clever as you are. I suck at maths!!!
Post Reply

Return to “General”