[FTE] .customphysics in CSCQ

Discuss CSQC related programming.
Post Reply
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

[FTE] .customphysics in CSCQ

Post by toneddu2000 »

I'm trying to understand custom physics in FTE though CSQC but I'm stuck.

Definition

Code: Select all

.void() customphysics;	/* Called once each physics frame,
 overriding the entity's .movetype field and associated logic.
 You'll probably want to use tracebox to move it through the world. Be sure to call .think as appropriate. */
So, If I set

Code: Select all

player.customphysics = Util_Null;//Util_Null() is a simple function that does nothing
when player is spawned, as Spike did in his purecsqc mod, and then in CSQC_Input_Frame() I simply write

Code: Select all

player.velocity_z -= 800 * input_timelength;
Player stands at mid air, doing nothing.
But, if I include pmove.qc from purecsqc mod and I launch

Code: Select all

PM_Run(player);
Player will fall and walk and stuff..

No need to mention that I tried, re-tried and tried again to understand why that pmove.qc is so special but, honestly, it's too much complicated for me.
Inside PM_Run, it launches Acceleration, run commands and acceleration again, but I didn't understand why.

Since pmove.qc it's GPL licensed and overcomplicated (at least for me) I'd like to start from basics: make player fall down.

If I change code to

Code: Select all

player.origin_z -= 50 * input_timelength;
It works. Same story for velocity_x and velocity_y. They seem blocked somehow.

Any suggestions, folks?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE] .customphysics in CSCQ

Post by toneddu2000 »

Ok, I have to admit it, I'm surprised. Taking a further look to pmove.qc code I understood that
1) Adding PM_Run_Acceleration before and after is needed only for multiplayer because, as Spike writes, "reduces framerate dependance";
2) PM_Run_Acceleration() manages velocity and movetypes, while PM_Run_Move() moves only origin, not velocity! It creates a tracebox with entity mins/maxs, sets the trace_endpos to old origin + velocity multiplied by input time, and moves every frame new origin to that trace_endpos! :shock:
In fact, if we create a very super simple move function like this

Code: Select all

void SimplePhysics(entity subject)
{
	local vector destinationpoint;//destination vector moved frame by frame
	
	//set velocity and direction
	makevectors(subject.angles);
	subject.velocity = v_forward * 100;
	subject.velocity *= input_timelength * 10;
	//move origin to destination point
	if(input_timelength > 0){
		destinationpoint = subject.origin + subject.velocity*input_timelength;
		tracebox(subject.origin, subject.mins, subject.maxs, destinationpoint, FALSE, subject);
		subject.origin = trace_endpos;
	}
}
And launch in CSQC_Input_Frame()

Code: Select all

SimplePhysics(player);
Player moves!

And, even more strange, if I print player velocity with

Code: Select all

cprint(vtos(player.velocity));
Player velocity actually increases!
Didn't know that velocity and origin were related somehow..here some words from Spike could help understanding this stuff! :)
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTE] .customphysics in CSCQ

Post by Spike »

the .customphysics method completely replaces the logic normally performed according to the entity's movetype field.
be warned that this includes calling the think function.
movetypes being ignored means that the only friction, acceleration, and movement performed is that which you do yourself. So yes, you'll need to update both the velocity and origin.
tracebox will of course trace a box from a start position by some distance and tell you both where you hit and the angle(plane normal) of the surface that you hit. This provides you with a way to move your entity forwards, and to bounce or slide or whatever instead of re-impacting the surface the next frame too.
note that my code calls tracebox a few times between clipping the velocity. this ensures that the entity slides along cracks where multiple planes might be blocking the entity (especially if gravity is pushing you against them too).

using customphysics is NOT the same as custom prediction. custom prediction is quite specific in its needs, specifically, custom prediction needs to apply each input frame which is still pending to the player's entity, with the expectation that the next packet received from the server will snap it back again to where it used to be requiring you to reapply everything.
the only reason my csqc used an empty customphysics function was to ensure that the player's movetype_walk/etc value was ignored, so that the only thing affecting the player was the prediction code (unlike ssqc with its SV_RunClientCommand function, player entities are not special in csqc).
the prediction code needs to be shared between client and server, so that both are guarenteed to obtain the same results. The server's copy is run from SV_RunClientCommand, while the client's copy is re-run for each pending input frame. This means that the code CANNOT use time or even frametime, but MUST use input_* as the only inputs beyond those fields which you're networking (like velocity and origin). Even the use of tracebox can result in prediction misses (as it depends on the position+size+etc of other entities), but you should normally be able to get away with it when other entities are not moving around too much (unless you were somehow predicting those too, which gets really really messy), the problem comes when prediction misses are present in every single packet, those are the ones that will result in significant problems (read: juddering, whereas snapping is easier to hide).
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE] .customphysics in CSCQ

Post by toneddu2000 »

the .customphysics method completely replaces the logic normally performed according to the entity's movetype field.
be warned that this includes calling the think function.
Well, tried call

Code: Select all

player.customphysics = Physics_CustomPhys;
Then

Code: Select all

void Physics_CustomPhysThink()
{
	makevectors(input_angles);
	self.velocity = v_forward * 20000;
	self.velocity *= 20;
	self.origin_x += 100;
	self.nextthink = time + 0.5;
	self.think = Physics_CustomPhysThink;
}

void Physics_CustomPhys()
{
	makevectors(input_angles);
	self.velocity = v_forward * 20;
	self.velocity *= 20;
	self.nextthink = time + 0.5;
	self.think = Physics_CustomPhysThink;
}
But no differences whatsoever
movetypes being ignored means that the only friction, acceleration, and movement performed is that which you do yourself. So yes, you'll need to update both the velocity and origin.
Got it
tracebox will of course trace a box from a start position by some distance and tell you both where you hit and the angle(plane normal) of the surface that you hit. This provides you with a way to move your entity forwards, and to bounce or slide or whatever instead of re-impacting the surface the next frame too.
I guess I'll need to create some sort of debug visual helper to test tracebox/traceline because, every time I check collisions on a stepped surface, trace_fraction doesn't reset when I stepped over, so no new check is performed. I guess it's something related to player hull bbox but not sure
note that my code calls tracebox a few times between clipping the velocity. this ensures that the entity slides along cracks where multiple planes might be blocking the entity (especially if gravity is pushing you against them too).
yeah I noticed but not sure what you did. Your code is A LOOT better than mine but it's not perfect. If I in fact try to step over a SOLID_BBOX static mesh entity in the editor, sometimes player can just walk, sometimes he sinks into the mesh and falls down. Making perfect static mesh walkable floors is not easy task in fte :sad:
using customphysics is NOT the same as custom prediction. custom prediction is quite specific in its needs, specifically, custom prediction needs to apply each input frame which is still pending to the player's entity, with the expectation that the next packet received from the server will snap it back again to where it used to be requiring you to reapply everything.
the only reason my csqc used an empty customphysics function was to ensure that the player's movetype_walk/etc value was ignored, so that the only thing affecting the player was the prediction code (unlike ssqc with its SV_RunClientCommand function, player entities are not special in csqc).
the prediction code needs to be shared between client and server, so that both are guarenteed to obtain the same results. The server's copy is run from SV_RunClientCommand, while the client's copy is re-run for each pending input frame. This means that the code CANNOT use time or even frametime, but MUST use input_* as the only inputs beyond those fields which you're networking (like velocity and origin). Even the use of tracebox can result in prediction misses (as it depends on the position+size+etc of other entities), but you should normally be able to get away with it when other entities are not moving around too much (unless you were somehow predicting those too, which gets really really messy), the problem comes when prediction misses are present in every single packet, those are the ones that will result in significant problems (read: juddering, whereas snapping is easier to hide).
No problem about that..I have some plan about it.. muhahaha :twisted:
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTE] .customphysics in CSCQ

Post by Spike »

when I said that customphysics replaced logic including think functions, what I meant was that think functions on the entity will no longer happen, meaning you need to call them yourself if you still want them to happen.

trace_fraction not resetting:
not entirely sure what you mean. note that tracebox does NOT bounce or slide itself. if your start position is directly next to a wall or something and the direction that the box is traced in points even slightly towards that wall, then the tracebox will of course hit that wall instantly, making no progress.
you MUST clip/bounce the velocity according to the trace_plane_normal value reported by tracebox.
velocity += -1 * dot(velocity, trace_plane_normal) * trace_plane_normal;
the dot says how fast the velocity is travelling towards the plane, the negate swaps the direction, and the multiply pushes it away in the correct direction.
scale it by 2 and the player will bounce instead (quake's grenades use 1.5, allowing them to lose momentum).
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE] .customphysics in CSCQ

Post by toneddu2000 »

Spike wrote:when I said that customphysics replaced logic including think functions, what I meant was that think functions on the entity will no longer happen, meaning you need to call them yourself if you still want them to happen.
Thanks a lot Spike, now I get it! For those wondering what customphysics does, but to lazy to test it

Code: Select all

void myplayerspawn()
{
player.customphysics = physnow;
player.nextthink = time +2;
player.think = thinknow;
}
In thinknow you can increase for example a foo var

Code: Select all

void thinknow()
{
foo +=5;
self.nextthink = time +5;
self.think = thinknow;
}
Now, without calling customphysics, if you cprint foo, you'll see 5...10...15...etc every 2 seconds. Instead, calling customphysics, the var will remain set to 0.
To make thinknow
function make its work, call thinknow directly in .customphysics function

Code: Select all

void physnow()
{
thinknow();//this will make think function work again
}
Thanks a lot Spike, now I now how customphysics work. Practically, if I understood well, .customphysics field is just needed to tell the engine to stop using legacy physics and do physics on your own, instead custom physics function (physnow() in example above) is needed to call think functions that, otherwise, wouldn't be called. It doesn't do any physics at all(only CSQC_Input_Frame() does), right?

--------------------
Spike wrote:note that tracebox does NOT bounce or slide itself
No, I know that. It only traces a bbox using a mins/maxs hull box and check trace_fraction,trace_plane_normal and trace_ent accordingly,right?
Spike wrote:if your start position is directly next to a wall or something and the direction that the box is traced in points even slightly towards that wall, then the tracebox will of course hit that wall instantly, making no progress.
Clear. Basically, if I understood correctly, I have to move every frame tracebox end vector a little further to check if player is not stuck.
Spike wrote:you MUST clip/bounce the velocity according to the trace_plane_normal value reported by tracebox.
velocity += -1 * dot(velocity, trace_plane_normal) * trace_plane_normal;
Thanks, probably this is the part where I fail. I did this

Code: Select all

subject.velocity += -1 * (subject.velocity * trace_plane_normal) *trace_plane_normal;
Is that correct?
But no difference at all. Now I manage to make player falls down, and walk on static meshes, but 1) movements are jerky 2) with thin meshes it falls through them (with static mesh box player walks over it ok)
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTE] .customphysics in CSCQ

Post by Spike »

if you ever did integrals in maths, then you should recognise speed(read: 1d velocity) as a line on a graph against time, and the distance travelled(read: 1d origin) as the area under it. the only real difference from highschool is that your velocity is known/relevant only for a really small time interval, and of course that walls might block you...
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE] .customphysics in CSCQ

Post by toneddu2000 »

ok, let's take my old dusty math books out! :biggrin:
Thanks Spike, I'll post every update here.
First step is now create traceline / tracebox debug visual helpers. I should have done ages ago...
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Post Reply