Jump to content

Adding new values to playerstate_s struct in q_shared.h?


Dusty

Recommended Posts

Posted

Seemed to be simple enough at first glance, however, trying to load a game or devmap results in errors.

 

After looking at the comments above playerstate_s, apparently msg.c needs to be modified whenever q_shared.h has new values/variables added to playerstate_s. I get a little lost after that, what needs to be modified exactly? Do I need to create more space for more variables somewhere? Do I need to modify some size limit on playerstate_s?

Posted

Unless you modify the engine as well, you can't add or remove fields from the playerstate_s struct. The engine needs to know exactly what fields are going to be networked and how many bits of each field will be networked. BUT! If you notice at the bottom of the struct:

//rww - spare values specifically for use by mod authors.
//See psf_overrides.txt if you want to increase the send
//amount of any of these above 1 bit.
int userInt1;
int userInt2;
int userInt3;
float userFloat1;
float userFloat2;
float userFloat3;
vec3_t userVec1;
vec3_t userVec2;

Raven were kind enough to add extra fields at the end of the struct so that modders could send new information without having to modify the engine. Note however, that the order of the fields must stay the same, you can only rename them. To tell the engine how many bits you want each field to use when being networked, you modify the ext_data/MP/psf_overrides.txt file - an example of this file is in one of the assets PK3 files (I can't remember which).

Posted

Would modifying the ext_data/MP/psf_overrides.txt work for SP coding? Also, I can't find those fields, are they in q_shared.h?

 

Also, how do I know how many bits I need? Should I just look at the bit usage of the other values compared to what size number or value they hold and guess based on those?

 

Actually, can't find those values anywhere in the SP source. Are they MP only?

 

 

EDIT: So I tried adding my own values in msg.cpp with their own bit amounts to correspond to the new variables in q_shared.h, game loads up new files fine now, but any save game no matter whether I just made it or not, cannot be loaded without the game crashing.

Posted

Those files are only for MP.

 

Having to edit ps/es basically means you are no longer making a mod fwiw.  The game crashes because you've changed the size of structures that are save-load affected.  So you would only be able to load new saves created with the change.  If at all.  I could not find any specific areas that actually load the ps/es directly though.  So they must only be written/read during the entity / client portions of save code.

 

No we will not be adding support for those files or similar files to OpenJK at this time so don't request it please.  The structs are non-POD too which makes it even more complicating to attempt it anyway.

Posted

^Is it possible to add values that can be tracked via a specific entity in some other way than modifying the PS? The main reason I got into this is because I realized I was using general values in my code and then I realized that the things I was doing needed to be/should be localized to specific entities (i.e. the player or an NPC).

 

Raven seems to go around this though sometimes from what I've already seen. For example, forceRageRecoveryTime is a PS value, however, it's not always used as ps.forceRageRecoveryTime, it exists in a general form in wp_saber... I'm also okay with save games being broken, the same thing is true for animation mods unfortunately so that's already a condition of my mod.

Posted

Add them to gentity_s or gclient_s or some other sub-struct to either of them same as you would in MP?

 

I have no idea what you mean regarding forceRageRecoveryTime.

Posted

^Maybe I'm remembering incorrectly and forceRageRecoveryTime is always PS, I'd have to double-check... anyway, I'll try that. I believe NPC->health may be something similar. It's a local variable to NPCs that is updated on the fly or at least seems to be.

 

I'm just wondering though, what's the purpose of the variables in PS? Is there some advantage that I'm missing out on if I don't modify it?

Posted

Playerstate variables are networked (MP)  And usable by the local player and stored within their snapshot.  (Concept still applies to SP even though there is no networking)  But raven does abuse this by being able to access the gentity in cgame since it is all 1 module.

 

I still don't see the point of just throwing out any old variables at me like NPC->health.  Its just a variable stored in a struct.  The ones that are off limits are ones which are shared between the engine and mod, as entitystate and playerstate are.

 

gentity_t and gclient_t are also semi save changers in SP as well.  But only if certain variables within them are being told to be read/written in g_savegame.cpp.  Should be lists at the top.

Posted

Note: playerState_s and entityState_s are both savegame structs. If you don't care about that, just store it in gclient_t. You can access it from cent->gent->client

Posted

^Would storing in gclient_t allow savegames to work correctly, as in, would those variables be the same as when the game is saved and when it is loaded, or will things "change"?

 

Okay, so on the whole, things seem to be working now, but now load checkpoint causes crashes, and any save game that used the checkpoint seems to inherit those crashes...

Posted

They will just be default value ie 0.  If stored in the ent or client structs upon loading.  They won't be explicitly saved iirc unless you tell it to save them in g_savegame.cpp

Posted

Are you saving a new game, or loading an old one?

 

I'm not that illogical haha. All loading up brand new saves made in the testing game session. I get rid of all the old ones. Anyway, I haven't been able to repeat a savegame inheriting crashing from a checkpoint loaded off of it, and with some of my code edits loading games doesn't seem to crash as often now. I guess what I'll do is try to isolate the conditions in which crashes are happening if possible.

Posted

Loading checkpoints never works. I haven't been able to figure out why savegames themselves stop working sometimes. Maybe it's that I was trying to load the same save file the checkpoint is using which is obviously corrupted?

Posted

So, in my code, I can't find any logic issues.

 

I've declared these variables in gentity_s in the file g_shared.h:


//Timing variables, counters and debounce times
	float		wait;
	float		random;
	int			delay;
	qboolean	alt_fire;
	int			count;
	int			bounceCount;
	int			fly_sound_debounce_time;	// wind tunnel
	int			painDebounceTime;
	int			disconnectDebounceTime;
	int			attackDebounceTime;
	int			pushDebounceTime;
	int			aimDebounceTime;
	int			useDebounceTime;
	//new variables
	int			saberReactivateTime; //time after something deactivates a saber for AI to turn it back on
	int			breakLimit;
	int			breakRecoveryTime; //how long left to recover a defense point
	int			breakCounter; //keeping track of how many strong attacks the defender blocks in a											//a short time period

(I just pasted the whole area so you could see where I was starting, at line 666 (yes section of evil), only the last 4 variables are new)

 

My variables only seem to need to be declared there as things like pushDebounceTime don't need anything to be referenced when it's used except simply having this line in g_shared.h

Posted

If it's a player-only variable, it should (logically) be in gclient_s, not gentity_s. I've never had issues putting variables at the end of it. Also, make sure you're up to date on your fork, and try and debug the issue.

  • 2 weeks later...
Posted

So per debugging apparently my crashes are caused by the fact that I dereferenced a null pointer somewhere... but am I really even using pointers? I know the "->" is a dereferencer but doesn't it also simply refer to struct values which is how I'm using it?

 

The curious thing is that these crashes only happen on trying to load checkpoints. Everything else by and large seems fine at the moment...

Posted

a->value is short-hand for (*a).value. There are no exceptions or corner cases to this rule*. It applies exactly the same to everything. So if you are using ->, then the variable to the left of it must be a pointer.

 

* At least this is true in the JKA source code.

Posted

If you're using ->, then yes, you're using a pointer. You're dereferencing the pointer (getting the address of where the pointer points to) and retrieving the value at the offset from the value of the pointer.

 

So let's take an example. Let's say you have a struct that's like this:

 

struct sampleStruct {
    float fDouble1;
    float fDouble2;
}

Generally we can work with it in three different ways:

  • Value (sampleStruct myVar;)
  • Pointer (sampleStruct* myVar;)
  • Reference (sampleStruct& myVar;)

Pointers are the only things which can be null, and if you try to dereference them (ie, get the address of where they're pointing to) you'll get an unhandled exception. Check with your debugger why they're null.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...