Skip to content

feat: better gibs - #65

Open
WofWca wants to merge 32 commits into
ec-:masterfrom
WofWca:baseq3a-all-gibs-mrs
Open

feat: better gibs#65
WofWca wants to merge 32 commits into
ec-:masterfrom
WofWca:baseq3a-all-gibs-mrs

Conversation

@WofWca

@WofWca WofWca commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

This MR includes (and thus supersedes) the following MRs:

I have also created a separate repo for all these changes: https://github.com/WofWca/quake3-better-gibs-mod.

When this is tentatively approved, I'll need to double check whether I documented all the new CVARs.

As requested in https://github.com/ec-/baseq3a/pull/63#issuecomment-3726169552, I'm submitting all my gibs improvements in one MR.
I recommend not doing a squash merge.

@WofWca
WofWca force-pushed the baseq3a-all-gibs-mrs branch 4 times, most recently from f67e43c to ff43b62 Compare January 15, 2026 10:50
@WofWca
WofWca force-pushed the baseq3a-all-gibs-mrs branch 2 times, most recently from a46bf96 to 774d842 Compare January 25, 2026 14:30
@WofWca
WofWca force-pushed the baseq3a-all-gibs-mrs branch 2 times, most recently from d40ef7f to 8e5636d Compare February 7, 2026 14:51
@WofWca
WofWca force-pushed the baseq3a-all-gibs-mrs branch from 6138028 to 3c1414c Compare February 21, 2026 13:03
WofWca added 21 commits March 4, 2026 14:36
This is a follow-up to
ad81db1
("fix: shotgun not gibbing unless aiming at feet")
(https://github.com/ec-/baseq3a/pull/49).
This brings the game balance closer to the original game.
For discussions, see
OpenArena/gamecode#349.
From the research conducted in
ioquake/ioq3#794
we can probably conclude that the `self->r.maxs[2] = -8;`
in `player_die()` is related to `pm->maxs[2] = -8;`
in `PM_CheckDuck()`. Let's make this clear with a named constant.
Resulting in things like players absorbing more lightning gun shots
on death than they should have at low `sv_fps 1`.

Closes WofWca/quake3-better-gibs-mod#12.

Bug reproduction steps:
1. `\devmap q3dm1; addbot crash; set bot_pause 1;`,
   `give quad damage; give speed`.
2. `\set sv_fps 1`.
3. `\set timescale 8` for better reproduce-ability.
4. Aim at the Crash's torso (not the feet).
5. Shoot.

Sometimes Crash would get gibbed. Which is not the case
in the original game.

The bug has been introduced recently, in
"fix: shotgun not gibbing unless aiming at feet".
This is in preparation to some gibs improvements.
In the original game, all gibs start flying from one single point
(i.e. `playerOrigin`), which is sometimes noticeable.
Let's position the gibs closer to where they are supposed to be
anatomically. That is, legs go lower, head goes higher.
The previous commit added proper initial positions
to each individual gib.
And now it's time to also make sure
that they're facing the right direction.
To be more precise, preserve the player velocity,
most importantly, including the velocity they get from knockback.
It's more "physically accurate" to decide whether to leave a mark
based on velocity.
This allows gibs to leave multiple marks,
should they keep high velocity after the first impact.
Allow playing the gib sound more than once,
and keep leaving the blood trail even if the gib
already hit something.
This makes the gibs feel more "dead" and less frog-like.
This will let us handle non-0 pitch values.
Before this commit we positioned gibs
close to where the player model's part are located,
but only assuming that the body is in an upright position.
That resulted in dead bodies' gibs getting launched
from pretty far away from where the model is actually located.
This commit fixes that.
WofWca added 11 commits March 4, 2026 14:36
This increases memory usage by 216 kB,
but makes blood marks not forcefully disappear as new ones are made.
Note that this changes the network protocol.
But it's still compatible with vanilla.
See new comment in `g_combat.c`.

We had to move the code that resets
`damage_blood`, `damage_armor`, `damage_knockback`
because otherwise they would stop getting reset
when the player dies,
because `P_DamageFeedback` early-returns when `PM_DEAD`.
This is, as usual, compatible with vanilla, both servers and clients.

The bug that this fixes:
WofWca/quake3-better-gibs-mod#3.

We also increase the default `cg_gibsExtraVerticalVelocity`
because with direct hit weapons the knockback is usually directed
a bit towards the ground, because in order to aim at the center
of a player your pitch needs to be a little below the horizon.
@WofWca
WofWca force-pushed the baseq3a-all-gibs-mrs branch from 3c1414c to e94a2b1 Compare March 4, 2026 10:38
@WofWca

WofWca commented May 24, 2026

Copy link
Copy Markdown
Contributor Author

I haven't updated this MR for a while. The latest state is in https://github.com/WofWca/quake3-better-gibs-mod. Let me know when you're interested and I'll rebase it.

WofWca added a commit to WofWca/baseq3a that referenced this pull request Jul 15, 2026
This saves ~0.34% (~1KiB), of traffic and demo size
for a ~3-minute match with 4 players,
by sending less data when a player or a dead body
is seen by another player for the first time in a while.

This will increase the size of the initial connection message
(`svc_gamestate`, which now needs to send the entities
for which we set the baseline state),
but it pays off in the long run.

How to test this change:
1. `./quake +set cg_autoRecordDemo 1 +set jorunal 1`
   to record a jorunal file and a demo.
2. Play a game.
3. Build the mod with this patch and install the mod.
4. `./quake +set cg_autoRecordDemo 1 +set jorunal 2`
   to play back the journal file and record another demo
   given the very same inputs.

Then compare the demo sizes.

One can also utilize `cl_shownet 3`.
Below is an example of how the "delta from baseline" entries look
on vanilla Quake. First two player entries,
then two body queue entries:

```
 50:  baseline: 2
 51: ec-#2   pos.trBase[0]:1024 pos.trBase[1]:1000 pos.trBase[2]:24 apos.trBase[1]:27 eType:1 torsoAnim:11 legsAnim:22 groundEntityNum:1022 pos.trType:1 eFlags:4 weapon:2 clientNum:2 angles[1]:90 apos.trType:1 solid:4200463  (418 bits)

 70:  baseline: 5
 71: ec-#5   pos.trBase[0]:216 pos.trBase[1]:1328 pos.trBase[2]:24 eType:1 torsoAnim:11 legsAnim:22 groundEntityNum:1022 pos.trType:1 eFlags:4 weapon:2 clientNum:5 angles[1]:360 apos.trType:1 solid:4200463  (398 bits)

 23:  baseline: 65
 24: ec-#65  pos.trBase[0]:678 pos.trBase[1]:1446 pos.trBase[2]:24 apos.trBase[1]:135 eType:1 torsoAnim:3 legsAnim:3 groundEntityNum:1022 eFlags:1 clientNum:3  (278 bits)

 46:  baseline: 66
 47: ec-#66  pos.trBase[0]:894 pos.trBase[1]:832 pos.trBase[2]:-15 apos.trBase[1]:225 eType:1 torsoAnim:5 legsAnim:5 groundEntityNum:1022 eFlags:1 clientNum:1  (279 bits)
```

As you can see, basically every field is transmitted,
including e.g. `eType`, which is almost always `ET_PLAYER`
for players and dead bodies.
Now let's see how this patch makes it look:

```
 33:  baseline: 3
 35: ec-#3   pos.trBase[0]:1024 pos.trBase[1]:1000 pos.trBase[2]:24 apos.trBase[1]:90 eventParm:10 legsAnim:22 angles[1]:90  (255 bits)

 84:  baseline: 5
 86: ec-#5   pos.trBase[0]:1028 pos.trBase[1]:1094 pos.trBase[2]:24 apos.trBase[1]:107 angles2[1]:7 legsAnim:22 eFlags:4 angles[1]:90  (284 bits)

 23:  baseline: 64
 24: ec-#64  pos.trBase[0]:698 pos.trBase[1]:1460 pos.trBase[2]:24 apos.trBase[1]:135  (149 bits)

 22:  baseline: 65
 24: ec-#65  pos.trBase[0]:471 pos.trBase[1]:807 pos.trBase[2]:-15 apos.trBase[1]:315 torsoAnim:3 legsAnim:3  (208 bits)
```

This is much shorter. Sometimes we even don't transmit
anything but coordinates and angles.

I have tested this on Quake3e and ioq3 engine.
The latter still has a bug in `SV_CreateBaseline`
which never sends entity numbered 0.
But this doesn't cause anything game-breaking,
only that this optimization will not be applied to entity 0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant