Proposal: Remove glorified CHEATS

Here are another truth that I tried and tried and tried to get Unvanquished developers to accept but failed miserably. Maybe I’ll have better luck here. I think that CHEATS which have been somehow elevated to the legitimate advanced skill status should be removed from the game. I’m not even sure if they bring anything good at all into the game.

  1. Remove the floor head bite. It’s contrary to the common sense and if you don’t do it, you won’t be able to play aliens at all, since the starting alien pretty much requires to use of this CHEAT. Not good for new players.
  2. Remove stafejumping and make players accelerate simply by jumping without having to deal with the strafing shenanigans. This CHEAT might actually be discoverable, but I struggle to see what would be lost if it were simply to be replaced with plain acceleration.

I understand the thinking here, and I do agree that any non-obvious mechanics are problematic if their implementation and presentation is done poorly. For headbites, I proposed that altering the position of the dretch crosshair could indicate to players that they need to look up, and indeed my approach worked! I found that the lowered crosshair has improved my headbite aim, instantly! :slight_smile:

The problem with this is it’s functionally useless and wrong when you’re not on the ground… so, some solutions might be:

  • Have dretch crosshair move lower on the screen only when you’re on the ground, and return to center when you’re on walls/ceiling.
  • Do a normal crosshair color change on leg/torso/structure hits, and a ‘chomp down’ animation on headbite.
  • Have human’s head get knocked back/forward/side to side when he gets a headbite.
  • Show extra blood fly out of the player’s face (particle emitted from the tag_head or so)
  • Tutorial text telling Dretch to AIM HIGH since they are small so low to the ground.

Strafe jumping is actually a bug that has existed since Quake2, and was left in or added to Quake3 by popular demand of players. By now it’s probably second nature to some players, so I’m against removing it outright. However, I do think giving players some additional acceleration with multiple jumps while sprinting would work for people who aren’t good at strafe jump.


Another thing: the dreaded CONSOLE. I think it should be made unnecessary to use it, but not removed. Instead, we could have nice menus for pretty much every option, and a chat UI could be used. For a chat UI, the dropdown functionality of console could be re-purposed, and have multiple tabs, where “console” would be one tab, and things like game chat, team chat, custom chat “channels”, and private messages with players as other tabs.


If both interfaces can be kept, then it would be fine by me, but my original point was that if the console isn’t removed, then developers and contributors might not be able to gather the motivation to implement GUI counterparts for the commands that they already know. Good article on the topic. This does not directly apply to Tremulous console, but the main point still stands: people are more compelled to write proper solutions when there’s no way to jury-rig a quick hack instead.


Behold, the function that contains the source of the strafe jumping feature/bug, and included a hidden fix provided from Quake III (the fix is under the comment // proper way (avoids strafe jump maxspeed bug), but feels bad):


Handles user intended acceleration
static void PM_Accelerate( vec3_t wishdir, float wishspeed, float accel )
#if 1
  // q2 style
  int     i;
  float   addspeed, accelspeed, currentspeed;

  currentspeed = DotProduct( pm->ps->velocity, wishdir );
  addspeed = wishspeed - currentspeed;
  if( addspeed <= 0 )

  accelspeed = accel * pml.frametime * wishspeed;
  if( accelspeed > addspeed )
    accelspeed = addspeed;

  for( i = 0; i < 3; i++ )
    pm->ps->velocity[ i ] += accelspeed * wishdir[ i ];
  // proper way (avoids strafe jump maxspeed bug), but feels bad
  vec3_t    wishVelocity;
  vec3_t    pushDir;
  float     pushLen;
  float     canPush;

  VectorScale( wishdir, wishspeed, wishVelocity );
  VectorSubtract( wishVelocity, pm->ps->velocity, pushDir );
  pushLen = VectorNormalize( pushDir );

  canPush = accel * pml.frametime * wishspeed;
  if( canPush > pushLen )
    canPush = pushLen;

  VectorMA( pm->ps->velocity, canPush, pushDir, pm->ps->velocity );

First thing I’m thinking is adding a game side cvar for strafe jumping which would switch between the two approaches (so that masochists and sadists would still have the option for their server to have the classical strafe jumping bug for their servers).

Second thing is to have a simplified jump that would yield the same end results as the old strafe jumping, where there would be a bit of an acceleration after each jump forward. The question is should this occur from the first jump, or only on repeated jumps, or should it be enabled/disabled as @romdos suggested with sprint (which is probably what I’m leaning towards, but would also mean that aliens would have to make use of such a sprint as well).

The cvar could have multiple options, like at least: 0) No accelerated jumping, 1) Classical strafe jumping, 2) Simplified accelerated jumping. If it pays to have multiple kinds of simplified accelerated jumping to choose from, we could include them as options in the cvar as well.

Note that this has not been implemented on the GrangerLab server yet, but it is on the TODO, I think this is something worth exploring. Feel free to add any further thoughts/considerations/suggestions on this concept.


[spoiler]Here’s the initial implementation of cheat-free movement. I had to tweak the fixed Quake 3 code not to slow down players who are already going fast and introduce PM_AccelerateHorizontal because Marauder’s air acceleration was strong enough to counteract gravity.[/spoiler]

EDIT: obsolete.

@dGr8LookinSparky Here’s another version, with tweaks and bug fixes. Overall changes:

  • Removed strafe-jumping CHEAT. Simply jumping now has a similar effect.
  • Jumping is now automatic - just hold jump.
  • Marauders can now redirect their momentum in the air.
  • Made marauder wall-jump less obnoxious and not as easy to trigger by accident.
  • All aliens can now reliably jump out of water: falling into water as a dragoon is no longer a death sentence. This still requires a lot of tweaks though.
1 Like

We do already have a version of that feature, (the spitfire and the jet can’t currently use it though), if you jump off the ground, and then press and hold jump before you land, you will generally keep jumping until you release.

Yet another version. Changes:

  • Added wall coasting: when moving against a wall, you will get the full speed even if you don’t move perfectly in parallel with it.

  • Fixed marauder wall-jumping and made it quite powerful (perhaps too powerful).

  • Limited automatic jump frequency to prevent stair glitches.

  • Fixed jumping out of the water to not activate when there’s no land to jump to.

1 Like

Yet another commit.

Changes since the previous commit I posted on forum:

  • Made the transition from one direction to the opposite when wall coasting not so sudden.

  • Added wall acceleration: moving along walls is now faster than moving normally. Looking along the wall increases the effect.

Changes made since @dGr8LookinSparky last reviewed the patch:

  • Reduced the number of traces when checking for proximity to walls.

  • Fixed ground trace not being set after stepping down. Not sure if it cause any problems though.

  • When walking, any slopes too steep to walk on are now treated as vertical walls.

1 Like

Yet another commit.


  • Use the method used for steps for determining if jumping out of the water is possible. This should reduce both false positives and false negatives, but greater vertical clearances are now required. There are some obvious fixes that could be applied, like sliding along the ceiling if a ceiling is found, but they are probably not be needed.

  • Allow jumping out of the water when wading. Tyrant can now jump out of the water in Citadel.

1 Like

Should a check for not having the PMF_TIME_KNOCKBACK flag be a requirement for that too? Also perhaps a check for not walking on slick surfaces? Not rhetorical questions.

Yes, but I’ll hold off making any more commits until you sort through and implements what I’ve already made, otherwise it will take forever. You should probably add these checks yourself.


@dGr8LookinSparky Another commit.

  • Reverted to the old acceleration mechanic (with a fix for strafe-jumping of course). This makes the movement feel less stiff. Pressing forward together with left and right at high speeds does not decelerate you anymore.

  • Marauders now receive extra air acceleration when going against their current velocity.

  • Because the new acceleration mechanic is essentially a weak form of air control, explicit drag mechanic had to be created for Marauders. Essentially, the special Marauder air physics are handled by 3 separate functions: PM_RedirectMomentum, PM_RudderDrag and PM_BoostBraking. I don’t know how computationally expensive this is, and these functions can probably be comibined, but for now I want to keep them separate for clarity. Maybe these mechanics can even find use somewhere else in the future.

  • Marauder walljump is now easier to activate. If you release the jump before you touch the wall and press it when you do, you will jump away even if the automatic jump time limit hasn’t run out yet.

  • Air control is reduced after walljumping for longer, allowing new players to discover that it can actually kick you away from walls.

  • Marauder walljump now breaks your fall. Starting a climb after falling for a fair amount of distance is no longer a problem.

  • Made Maraudes faster on the ground.

  • Made Dretches and Basilisks more extra speed from jumping.

  • Fixed the problem where wall coasting prevented you from swimming or flying down when touching a wall.


Also, strafe-jumping has nothing to do with jumping: without the ground friction, you’d be able to strafe-slide. Therefore, I suspect that this thing called “dancing” is also a form of exploitation of this CHEAT, allowing for the maximum speed to be exceeded, even if for brief periods of time before the friction cancels any gains. Adjustments to player speeds may be required to balance this.


@dGr8LookinSparky I need an advice badly. When I need both the origin of the attacker and the target for locational damage calculation, should I use client->unlaggedCalc.origin of the attacker AND the target or just the target? Also, another commit.

  • Initial implementation of the new locational damage system.

  • Partially refactored g_combat.c.

  • Moved most of the new constants into tremulous.h for easy tweaking.


I’m not 100% sure, but try using client->unlaggedCalc.origi for both and see what happens.


I already do, and seem to get 0.0 for precision (as opposed to eg. 0.1 or 0.2) pretty often…

Also I noticed that I accidentally changed the dretch bite range. This might be OK (was still possible to hit humans when testing with @romdos), but revert this if players complain.

I was thinking that perhaps both the new acceleration studd, and the new locational damage should be available in all three game modes (chocolate, vanilla, and swirl) via cvars, along with the “traditional” ways as options. Some server owners may prefer having the old way for at least some servers, simply because there are players who are use to the old feel, but alsothese changes might be generally better even on the vanilla and chocolate modes.

  • To do this, create new game cvars for both by adding the appropriate cvar lines in g_local.h and in g_main.c. (this is enough for creating the locational damage cvar since that would only be needed game side, but you will need to do the aditional steps for the acceleration cvar since the cgame will need to use it as well).

  • Then add a new configstring inside the configstring enum someplace below the CS_WARMUP configstring, perhaps call it CS_PHYSICS (this config string would be used to communicate those settings to the client, which would be essential since bg_pmove.c is used by both the server and the client for client predictions, and if there are going to be any other game side cvars that set the “physics”, you can append those cvar values into the CS_PHYSICS configstring and parse).

  • Then set that configstring with the value of those two cvars in two spots in g_main.c: inside G_InitGame(), and in case the cvars are modfied during the match inside CheckCvars().

  • Add a variable inside the cg_t structure in cg_local.h that would store the acceleration setting.

  • Then parse out the value in CG_ConfigStringModified() and in CG_ConfigStringModified() which is located in cg_servercmds.c to that new variable in cg_t.

  • Add a new variable inside the pmove_s structure in bg_public.h for the physics setting, you will be directly using this variable inside bg_pmove.c inside PM_Accelerate().

  • Set that new variable accordingly before all instances of PMove() inside cg_predict.c and g_active.c

Is that a problem?

What was the reason for changing that range? (if it is a good change, I would probably only include it in the swirl game mode to not mess with the balance of the other game modes).