Best way to implement player stats?
by Flybynight Studios · in Torque Game Engine · 11/23/2006 (11:26 pm) · 3 replies
Alot of threads on this and amazingly not one real good explanitory resource. I just want to make sure my head is on the right line of thinking for this. Is there any benefits to making the stats part of the player data object?
IMO that seems to beg for headache, at least in my MMO application. Stats change constantly and I dont want to be updating a bunch of datablock info everytime someone takes off their "Sword of Thousand Truths". Wouldn't it be much simpler and far more bandwidth friendly to design the stat system as an array of this.player? For example the way I have it rigged now (which has been working fine but I havent done any real testing on it) is when a player connects they I take their client ID and assign a block of vars to it. I pull the values for the variables from the database based on the players login and voila.. Anytime that client needs something updated or changed their ID is used to call up whatever array value they need..
Is there a simpler/ more efficient way of doing this? IMO I can't see one but thats why Im asking =) If there are flaws in this please point them out. As far as I'm concerned I'm going to take this to the next level and put every var for the player into a 200 slot array. Bindpoints, skill levels, recipies, inventory, quests..
I mean really this makes it all simple as hell. Instead of having to send tons and tons of datablock overhead I would just send a pertinent array content.. for example: "Completed quests might be the content of array unit 17.. so the client pops up their "quests in progress" screen and the server streams down ID17 which contains the vlaue "1723,43,26,435,3426". Then on the client it looks up the descriptions for those quests and displays them..
Anyone want to weigh in on this?
Thanks
IMO that seems to beg for headache, at least in my MMO application. Stats change constantly and I dont want to be updating a bunch of datablock info everytime someone takes off their "Sword of Thousand Truths". Wouldn't it be much simpler and far more bandwidth friendly to design the stat system as an array of this.player? For example the way I have it rigged now (which has been working fine but I havent done any real testing on it) is when a player connects they I take their client ID and assign a block of vars to it. I pull the values for the variables from the database based on the players login and voila.. Anytime that client needs something updated or changed their ID is used to call up whatever array value they need..
Is there a simpler/ more efficient way of doing this? IMO I can't see one but thats why Im asking =) If there are flaws in this please point them out. As far as I'm concerned I'm going to take this to the next level and put every var for the player into a 200 slot array. Bindpoints, skill levels, recipies, inventory, quests..
I mean really this makes it all simple as hell. Instead of having to send tons and tons of datablock overhead I would just send a pertinent array content.. for example: "Completed quests might be the content of array unit 17.. so the client pops up their "quests in progress" screen and the server streams down ID17 which contains the vlaue "1723,43,26,435,3426". Then on the client it looks up the descriptions for those quests and displays them..
Anyone want to weigh in on this?
Thanks
#2
For stuff that has no bearing on physics, like inventory, quests, etc..., I only send the data for them to the client when the client wants to see it. When they push the key stroke for 'view quests' or inventory, I send a request to the server, which packs up the appropriate display data in a newline-separated block of text then sends it back to the client. When the client receives this packet, it pops up the dialog to view the inventory or quests and fills it with the data. I just have the 'quest ID' type identifier attribute as the last column, and don't display it in the dialog's list area.
In any case, I think it's best not to send any data that is unnecessary at any given time, so I only ever send what is either requested to be viewed on the client, or in the case of physics-relevant player attributes, what has changed. To me, it sounds like putting every player attribute into a single array, and sending the whole thing everytime you need to update something on the client would send more data than necessary.
11/24/2006 (6:55 am)
Well, the direction I've gone is to put most simple player attributes into the C++ player class. The ones that get used in any physics type calculations (strength, stamina, vehicle fuel), I've added to the list of ones streamed in 'pack/unpack Update' and read/write packetData methods. I did this because it seemed that if the physics are calculated both on the client and the server, that I would need to have any data I used in methods like 'updateForces' or 'updateMove' in sync on both, or they would think the player was running different speeds on client and server, etc... To be honest, I'm not entirely clear on the different purposes of the 'packUpdate' and 'writePacketData' methods, but I couldn't get my vehicle fuel attribute (which is like another type of 'energy' attribute that is depleted while driving the vehicle) working right until I'd added it to both sets of methods.For stuff that has no bearing on physics, like inventory, quests, etc..., I only send the data for them to the client when the client wants to see it. When they push the key stroke for 'view quests' or inventory, I send a request to the server, which packs up the appropriate display data in a newline-separated block of text then sends it back to the client. When the client receives this packet, it pops up the dialog to view the inventory or quests and fills it with the data. I just have the 'quest ID' type identifier attribute as the last column, and don't display it in the dialog's list area.
In any case, I think it's best not to send any data that is unnecessary at any given time, so I only ever send what is either requested to be viewed on the client, or in the case of physics-relevant player attributes, what has changed. To me, it sounds like putting every player attribute into a single array, and sending the whole thing everytime you need to update something on the client would send more data than necessary.
#3
I didnt explain the array properly.
Example: CLientID[1-200]
so player id1045 race would be 1045[1]. His class would be id1045[2], his max HP might be id1045[17]..
When the player needs that data they are sent only the data required not the whole id1045[1-200].
The actual player data is stored in the database. When the player connects to a server their data is parsed into the id1045[1-200] variable setup. Then issued to the client as required. I am sure there are many ways to handle this but I see nothing wrong with the way I've started doing it so I'm going to keep on keepin on ;)
Thanks again everyone.
Mark
11/24/2006 (12:27 pm)
Thanks for the feedback guys.I didnt explain the array properly.
Example: CLientID[1-200]
so player id1045 race would be 1045[1]. His class would be id1045[2], his max HP might be id1045[17]..
When the player needs that data they are sent only the data required not the whole id1045[1-200].
The actual player data is stored in the database. When the player connects to a server their data is parsed into the id1045[1-200] variable setup. Then issued to the client as required. I am sure there are many ways to handle this but I see nothing wrong with the way I've started doing it so I'm going to keep on keepin on ;)
Thanks again everyone.
Mark
Torque Owner Stefan Lundmark
You can not make it part of the datablock since there is only one instance of it and all players share it.
Simpler yeah, but absolutely not more bandwidth friendly since you need to send the changes for each object now rather than for a global one. Doing this in script is a good start and alot simpler than doing it in the engine.