SDK Known Issues List: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(Add "Getting the SDK to work under -Wall -Werror")
Line 1: Line 1:
== Getting the SDK to work under -Wall -Werror ==
== Getting the SDK to work under -Wall -Werror ==
If you're a professional programmer with any familiarity with GNU then the first thing you probably did was attempt to compile the SDK with -Wall -Werror, and were then disappointed by all the violations in Valve's code out of the box.  Here's a list of fixes to make this work.  (This list is by no means complete - I fixed many problems before I realized this would be something worth wiki-ing.)
If you're a professional programmer with any familiarity with GNU then the first thing you probably did was attempt to compile the SDK with -Wall -Werror, and were then disappointed by all the violations in Valve's code out of the box.  Here's a list of fixes to make this work.  (This list is by no means complete - I fixed many problems before I realized this would be something worth wiki-ing.)
=== offsetof errors ===
Unfortunately, these are due to a bug in gcc, noted here: [http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16618 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16618].  It was fixed in 3.4.2, but I haven't tried upgrading to 3.4.2 yet, as it is likely to break the linkage to Valve's .so files.


=== Missing EOF linefeeds ===
=== Missing EOF linefeeds ===

Revision as of 23:09, 11 September 2005

Getting the SDK to work under -Wall -Werror

If you're a professional programmer with any familiarity with GNU then the first thing you probably did was attempt to compile the SDK with -Wall -Werror, and were then disappointed by all the violations in Valve's code out of the box. Here's a list of fixes to make this work. (This list is by no means complete - I fixed many problems before I realized this would be something worth wiki-ing.)

offsetof errors

Unfortunately, these are due to a bug in gcc, noted here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16618. It was fixed in 3.4.2, but I haven't tried upgrading to 3.4.2 yet, as it is likely to break the linkage to Valve's .so files.

Missing EOF linefeeds

First you'll need to `cvs rm -f mod/src/dlls/worker_scientist.h` since that file is blank, unused, and will make the script below not run. :)

Then run:

#!/usr/bin/perl -w

use strict;
foreach (`find mod -name *.cpp -or -name *.h`) {
    chomp;
    open(F, "+<", $_) or die "$! on $_";
    seek(F, -1, 2) or die "$! on $_";
    my $c;
    read(F, $c, 1) or die "$! on $_";
    if ($c ne "\n") {
        print "$_\n";
        print(F "\n");
    }
}

Garbage after #endifs

A common mistake in the SDK, obviously trivial to fix, but here for your conveniance:

diff -w -u -r1.3 ai_basenpc.cpp
--- dlls/ai_basenpc.cpp 2005/06/11 22:14:26     1.3
+++ dlls/ai_basenpc.cpp 2005/09/10 18:16:13
@@ -8450,7 +8450,7 @@

        return shotDir;
 }
-#endif HL2_DLL
+#endif // HL2_DLL

 //-----------------------------------------------------------------------------



diff -w -u -r1.1.1.1 npc_BaseZombie.cpp
--- dlls/hl2_dll/npc_BaseZombie.cpp     2005/02/18 04:45:52     1.1.1.1
+++ dlls/hl2_dll/npc_BaseZombie.cpp     2005/09/10 20:57:40
@@ -1582,7 +1582,7 @@

 #ifdef DEBUG_ZOMBIES
                        DevMsg("Wandering\n");
-#endif+
+#endif

                        // Just lost track of our enemy.
                        // Wander around a bit so we don't look like a dingus.



diff -w -u -r1.2 memalloc.h
--- public/tier0/memalloc.h     2005/02/19 18:24:26     1.2
+++ public/tier0/memalloc.h     2005/09/10 05:12:39
@@ -133,6 +133,6 @@
 #define MEM_ALLOC_CREDIT_CLASS()
 #define MEM_ALLOC_CLASSNAME(type) NULL

-#endif !STEAM && NO_MALLOC_OVERRIDE
+#endif // !STEAM && NO_MALLOC_OVERRIDE

 #endif /* TIER0_MEMALLOC_H */




snprintf strangeness

There are several conflicting snprintf defines and other snprintf porting bugs in the SDK, which need to be fixed for Werror compatibility:

diff -w -u -r1.1.1.1 interface.h
--- public/tier1/interface.h    2005/02/18 04:45:58     1.1.1.1
+++ public/tier1/interface.h    2005/09/10 06:09:25
@@ -33,8 +33,6 @@

 #define HMODULE void *
 #define GetProcAddress dlsym
-
-#define _snprintf snprintf
 #endif

 // TODO: move interface.cpp into tier0 library.



diff -w -u -r1.1.1.1 interface.cpp
--- tier1/interface.cpp 2005/02/18 04:45:59     1.1.1.1
+++ tier1/interface.cpp 2005/09/10 21:18:20
@@ -191,7 +191,7 @@
                Q_snprintf( str, sizeof(str), "%s.dll", szAbsoluteModuleName );
                hDLL = LoadLibrary( str );
 #elif _LINUX
-               _snprintf( str, sizeof(str), "%s_i486.so", szAbsoluteModuleName );
+               Q_snprintf( str, sizeof(str), "%s_i486.so", szAbsoluteModuleName );
                 hDLL = dlopen(str, RTLD_NOW);
 #endif

Broken comments

Ending a // comment with \ is just begging for trouble...

diff -w -u -r1.1.1.1 collisionutils.cpp
--- public/collisionutils.cpp   2005/02/18 04:45:56     1.1.1.1
+++ public/collisionutils.cpp   2005/09/10 23:59:09
@@ -2299,7 +2299,7 @@

        return true;
 }
-
+/*
 //--------------------------------------------------------------------------
 // Purpose:
 //
@@ -2314,7 +2314,7 @@
 //    0-----2
 //
 //--------------------------------------------------------------------------
-
+*/
 //-----------------------------------------------------------------------------
 // Purpose: find the minima and maxima of the 3 given values
 //-----------------------------------------------------------------------------

BotPutInServer linker failures

Various BotPutInServer lines will fail to link in DEBUG mode. Commenting the BotPutInServer lines out works just fine. It may have some negative affect on bots. I quite frankly have not looked into that stuff at all, other than to see that it breaks the build.

Fix: A better way would be adding hl2mp_bot_temp.h and hl2mp_bot_temp.cpp to the HL project under the Source Files->HL2MP folder. hl2mp_bot_temp.h and hl2mp_bot_temp.cpp can both be found in yourmod/src/dlls/hl2mp_dll folder.

Server: Host_Error: SV_PackEntity: SendTable_Encode returned false (ent %d).

Here %d will be replaced by whatever the entity number is that caused the error. No single entity is allowed to write more than 2KB to the network stream. This error happens when an entity overflows that buffer.

Fix: If you need an entity to occasionally transmit more than 2K of data, you will need to split it up into multiple entities, each transmitting part of the data. You should ensure of course that no entity -consistently- transmits 2K of data, as it would bog down your network. Some entities might want to send a large amount on map initialization etc, however. Another possible workaround for some situations (may not always be possible), is to update data a little bit each frame, so that no one frame has a big change.

Server: The client's health variable is pointlessly sent across the wire twice.

Fix: Diff And Patch

--- mod/src/cl_dll/c_baseplayer.cpp     2005/06/30 05:54:09     1.6
+++ mod/src/cl_dll/c_baseplayer.cpp     2005/07/16 21:33:33
@@ -1888,3 +1888,7 @@
    BaseClass::SetGroundEntity(ground);
}

+
+int C_BasePlayer::GetHealth() const {
+    return g_PR->GetHealth(entindex());
+}



--- mod/src/cl_dll/c_baseplayer.h       2005/07/11 03:28:41     1.9
+++ mod/src/cl_dll/c_baseplayer.h       2005/07/16 21:05:31
@@ -103,7 +103,7 @@

        // Data handlers
        virtual bool    IsPlayer( void ) const { return true; };
-       virtual int             GetHealth() const { return m_iHealth; };
+       virtual int             GetHealth() const;

        // observer mode
        virtual int                     GetObserverMode() const;



--- mod/src/dlls/player.cpp     2005/07/12 07:38:04     1.33
+++ mod/src/dlls/player.cpp     2005/07/22 00:45:48
@@ -58,6 +58,8 @@
 #include "nav_mesh.h"
 #include "env_zoom.h"

+#include "player_resource.h"
+
 #ifdef HL2_DLL
 #include "combine_mine.h"
 #include "weapon_physcannon.h"
@@ -4295,6 +4297,9 @@
        m_lastx = m_lasty = 0;

        m_lastNavArea = NULL;
+
+    // update now so that our new health gets sent with the respawn notice
+    g_pPlayerResource->SetPlayerHealth(entindex(), m_iHealth);

        /// @todo Do this once per round instead of once per player
        if (TheNavMesh)



--- mod/src/dlls/player_resource.cpp    2005/06/19 02:54:04     1.5
+++ mod/src/dlls/player_resource.cpp    2005/07/22 00:44:35
@@ -85,6 +85,13 @@
 }

 //-----------------------------------------------------------------------------
+// Purpose: Sets health value for a particular client (used to set on spawn so the data will be sent synchronously)
+//-----------------------------------------------------------------------------
+void CPlayerResource::SetPlayerHealth(int entindex, int health) {
+    m_iHealth.Set(entindex, health);
+}
+
+//-----------------------------------------------------------------------------
 // Purpose: The Player resource is always transmitted to clients
 //-----------------------------------------------------------------------------
 int CPlayerResource::UpdateTransmitState()



--- mod/src/dlls/player_resource.h      2005/06/18 21:16:29     1.3
+++ mod/src/dlls/player_resource.h      2005/07/22 00:42:57
@@ -26,6 +26,8 @@
        virtual void UpdatePlayerData( void );
        virtual int  UpdateTransmitState(void);

+    void SetPlayerHealth(int entindex, int health);
+
 protected:
        // Data for each player that's propagated to all clients
        // Stored in individual arrays so they can be sent down via datatables

Then you can remove the SendPropInt and RecvPropInt for CBasePlayer::m_iHealth. (However, I don't have a patch for that yet since it's not a backwards-compatible change. Will post a patch once I've done so, if no on else beats me to it.)

Server: weapon_citizensuitcase Assert on startup

Fix: Install copy of the SP SDK, then copy the scripts/ directory over

Server: Some bullet weapons set to do 0 damage.

Fix: Need to edit their AddAmmoType which are strangely set to 0 for some reason.

Server: Some projectile weapons set to do 0 damage.

Fix: Need to edit their source files and set a damage.

Client: --- Missing Vgui material vgui/steam/games/icon_cz

Fix: These files are used in the currently inaccessible Friends IM client. Create 4 vmts in their places of any design to remove the error.

  • materials\VGUI\steam\games\icon_cs.vmt
  • materials\VGUI\steam\games\icon_dod.vmt
  • materials\VGUI\steam\games\icon_hl2mp.vmt
  • materials\VGUI\servers\icon_secure_deny.vmt

Here's a patch to create files for the first three. (I don't see the icon_secure_deny.vmt error, so didn't create anything for it.)

--- materials/VGUI/steam/games/icon_cs.vmt      1969-12-31 18:00:00.000000000 -0600
+++ materials/VGUI/steam/games/icon_cs.vmt      2005-07-28 01:54:17.000000000 -0500
@@ -0,0 +1 @@
+"UnlitGeneric" {}
--- materials/VGUI/steam/games/icon_dod.vmt     1969-12-31 18:00:00.000000000 -0600
+++ materials/VGUI/steam/games/icon_dod.vmt     2005-07-28 01:54:19.000000000 -0500
@@ -0,0 +1 @@
+"UnlitGeneric" {}
--- materials/VGUI/steam/games/icon_hl2mp.vmt   1969-12-31 18:00:00.000000000 -0600
+++ materials/VGUI/steam/games/icon_hl2mp.vmt   2005-07-28 01:54:15.000000000 -0500
@@ -0,0 +1 @@
+"UnlitGeneric" {}

Fix2: Add clear to your rc file in cfg (extract from gcf if non-existant)

Server: The crossbow causes an assertion failure.

Fix: Comment out ai_activity.cpp line 53. This doesn't appear to be something that can be fixed in code?

Server? Client?: RL explosion invisible

Per http://www.chatbear.com/board.plm?a=viewthread&t=970,1107153392,30132&id=786504&b=4991&v=flatold ==

Fix: No known workaround.

Server: util.cpp (531) : Assertion Failed: !"UTIL_GetLocalPlayer"

Occurs when taking damage to yourself from tossing a table straight up into the air.

Fix: The following patch fixes the Assert, and appears to be more functionally correct as well. Validation from Valve that the patch is correct would be appreciated. Diff And Patch

Index: mod/src/dlls/player.h
===================================================================
--- mod/src/dlls/player.h 2005/02/19 22:20:29 1.2
+++ mod/src/dlls/player.h 2005/02/24 00:35:30
@@ -459,6 +459,7 @@
     // mass/size limit set to zero for none
     static bool CanPickupObject( CBaseEntity *pObject, float massLimit, float sizeLimit );
     virtual void PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {}
+    virtual bool IsHoldingEntity( CBaseEntity *pEnt );
     virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {}
     virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject );

Index: mod/src/dlls/player.cpp
===================================================================
--- mod/src/dlls/player.cpp 2005/02/21 00:05:42 1.3
+++ mod/src/dlls/player.cpp 2005/02/24 00:35:33
@@ -7447,3 +7447,7 @@
     return cmd;
 }

+bool CBasePlayer::IsHoldingEntity( CBaseEntity *pEnt )
+{
+    return PlayerPickupControllerIsHoldingEntity( m_hUseEntity, pEnt );
+}

Index: mod/src/dlls/physics_impact_damage.cpp
===================================================================
--- mod/src/dlls/physics_impact_damage.cpp 2005/02/18 04:45:50 1.1.1.1
+++ mod/src/dlls/physics_impact_damage.cpp 2005/02/24 00:42:24
@@ -417,12 +417,22 @@
     else if ( pEvent->pObjects[index>GetGameFlags() & FVPHYSICS_PLAYER_HELD )
     {
     // if the player is holding the object, use it's real mass (player holding reduced the mass)
-    CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
-    if ( pPlayer )
-    {
+    CBasePlayer* pPlayer = NULL;
+    {for (int i = 1; i <= gpGlobals->maxClients; i++) {
+        CBasePlayer *temp_player = UTIL_PlayerByIndex(i);
+        if (temp_player
+            && temp_player->edict()
+            && temp_player->IsHoldingEntity(pEvent->pEntities[index])
+        ) {
+            pPlayer = temp_player;
+            break;
+        }
+    }}
+    Assert(pPlayer && "object with FVPHYSICS_PLAYER_HELD but no player holding it");
+    if (pPlayer) {
     float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] );
-    if ( mass > 0 )
-    {
+        Assert((mass > 0) && "player was holding object so mass should be non-zero");
+        if (mass > 0) {
             invMass = 1.0f / mass;
         }
     }

Note: Instead of iterating all players, why not consider adding a m_pHolder var and GetHolder and SetHolder functions to CBaseEntity

(You could, though it's unlikely to impact performance much since this is not a frequently called function. Bloodykenny 17:55, 19 Jul 2005 (PDT))

Assert !"UTIL_GetLocalPlayer" when using combine ball

Fix: Diff And Patch

diff -u -r1.1.1.1 prop_combine_ball.cpp 
--- mod/src/dlls/hl2_dll/prop_combine_ball.cpp 2005/02/18 04:45:52 1.1.1.1 
+++ mod/src/dlls/hl2_dll/prop_combine_ball.cpp 2005/02/24 01:34:21 
@@ -788,9 +788,9 @@ 
     pPhysicsObject->GetPosition( &vecPosition, NULL ); 
     pPhysicsObject->GetVelocity( &vecVelocity, NULL ); 

-    CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); 
-    if ( pPlayer ) 
+    if (gpGlobals->maxClients == 1) 
     { 
+    CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); 
     Vector vecDelta; 
     VectorSubtract( pPlayer->GetAbsOrigin(), vecPosition, vecDelta ); 
     VectorNormalize( vecDelta );

Note: This really is a dirty fix because the combine ball always has to face the player because the model was design without a back side

Server: CreateEvent: event 'break_prop' not registered

Fix: This was implemented before breakable props were finished clientside

I'm not sure what you're saying the fix is here. Or is that just a statement explaining why the bug exists in the SDK? Bloodykenny 17:57, 19 Jul 2005 (PDT)

HL2.exe mysteriously segfaults if you forget to put the client.dll and server.dll in your mod's bin directory

Fix: Don't do that.

Server: If you leave a server online on a certain map for roughly 12-24 hours straight, it begins using 100% CPU.

Possibly a core srcds.exe bug, not an SDK bug?

I suppose there could be some array or something inside the HL2 core that grows over time, and must be iterated over each frame?

I haven't run the long-running map scenario in a long time. The alpha server for my mod is full most of the day and players frag out so the map is always changing.

That said, I seem to recall that the move from the usual 5% cpu to 100% cpu was fairly drastic and immediate. I never saw an intermediate stage where the server used 25% cpu or 50% cpu etc. I would expect to see those intermediate levels if it was a memory leak.

Fix: Ensure you have mp_timelimit set to something nonzero, but less than 12 hours or so.

Server/Client: Negative entitygroundcontact crash.

The implications of this SDK bug are not at all clear, but in debug mode you'll get an assert, and in release mode it will presumably segfault. Update: count < 0 isn't enough - I've changed it to also check > 128 or so.

Fix: Diff And Patch

--- mod/src/game_shared/usercmd.cpp 2005/02/18 04:45:54 1.1.1.1
+++ mod/src/game_shared/usercmd.cpp 2005/03/23 02:24:00
@@ -290,7 +290,12 @@
 #if defined( HL2_DLL )
     if ( buf->ReadOneBit() )
     {
-        move->entitygroundcontact.SetCount( buf->ReadShort() );
+        int count = buf->ReadShort();
+        if (count < 0) {
+        Msg("Ignoring strange entitygroundcontact count: %d\n", count);
+        return; // why can this be less than 0, Valve? change to ReadWord()???
+    }
+    move->entitygroundcontact.SetCount( count );

     int i;
     for (i = 0; i < move->entitygroundcontact.Count(); i++)

Client: Spinning around quickly with the Stun Baton as your active weapon causes the screen to flash white

It's worth noting that recent updates to HL2DM have fixed this. However there has not yet been an SDK code update to show what the fix is. Basically Valve seems to have made the glow fade out completely in between swings.

Fix: Fix unknown

Assert on line 866 of mod/src/game_shared/basecombatweapon_shared.cpp

Fix: I haven't been able to determine exactly why this is an assert. It's just "Assert(0);" with no accompanying explanation, but commenting it out results in no problems it seems. Diff And Patch

--- mod/src/game_shared/basecombatweapon_shared.cpp     2005/02/18 04:45:53     1.1
+++ mod/src/game_shared/basecombatweapon_shared.cpp     2005/03/04 03:45:36     1.2
@@ -863,7 +863,7 @@
        CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
        if ( vm == NULL )
        {
-               Assert( false );
+               //Assert( false );
                return false;
        }

Client: The mod can appear to have frozen on initial startup

Originally posted by Garry here: http://www.chatbear.com/board.plm?a=viewthread&b=4991&t=234,1117553034,6915&s=0&id=868372

Fix: Issue a "progress_enable" command just before "map <mapname>".

engine->ClientCmd("progress_enable");

engine->ClientCmd("map test");

This should fix local servers. For connecting to a remote multiplayer server, the only issue appears to be that you can't switch to another window and then switch back to HL2. Doing so causes HL2 to never render progress info until load is fully complete. That seems to be an HL2 core bug unrelated (though very similar in appearance) to the fix above.

Other info and links

See also this nice general HL2 bug list on the steam forums. Many of the issues seem imbedded down inside the closed-source side of things, so they are outside the scope of this SDK Known Issues list.

There's also this Patch HL2 petition where users sign their name to beg Valve to fix the aforementioned bugs.