Closed collinsmith closed 5 years ago
I guess I should explain why this is a problem and why the separation is needed. Technically single player has access to the character save file D2S
, and so far I've been using that as an argument in the constructor for constructing the Player
entity. The issue is that multiplayer never has access to this data, at least in its entirety, so I can't just download the D2S
onto every client -- which would create a stateful nightmare. So the goal should be that client's should be able to run with or without their character's D2S
, and that should exist on the server only for multiplayer.
I'm not 100% sure how I want to handle listen server games, I'm thinking other players would need to upload their D2S
to the host, or host updates would cause clients to write the changes to their D2S
, but I'm not sure how to handle the authoritative nature of this architecture. I.e., I don't know how much checking should be done if say a host sends updates which breaks a client's save file. It could also be that all client's in a listen server game are their own hosts and are sending updates to each other as if in a regular dedicated server multiplayer game.
D2S
should also support loading header only (170
or 765
bytes -- 171-765
contains map, merc, quest, waypoint, npc, stats which may not all be needed for character select screen and menus). Not loading after 765
alone would improve the loading time of these screens since the items aren't needed.
I implemented deferred loading of non-header data in D2S. Header data includes up to 0x14F
. Most of this data will be used in Riiablo.player
, whether loaded from a D2S
or received over the network. Connecting to your network account will transmit the headers for your characters so the client can render and either connecting or joining a game will transmit the remaining info.
I created CharData
(Riiablo.charData
) which will be a container for save data, either from a local D2S
or over the network. This class will also support generating a D2S
in the case of single player (multiplayer will generate the D2S
on the server and transmit to player). I had to disable some of the networking code temporarily, which is fine because that package is due to be replaced. Next step is to replace the coupling with gameScreen.player
with Riiablo.charData
for all of the save data accessors. I may also remove/refactor some of the Player
class stuff like Player.Stats
and Player.Skills
to support the other changes and prepare for things like items adding skills to players.
It also may be necessary to keep a reference to the local client's Player
entity easily available to do things like use warps or some skills.
I refactored in CharData
. Tests so far indicate success. I've decided to keep item details always based on the local player.
I wanted to note also, D2S.StatData
has been modified so that the float fields are just their unencoded int values. This is to keep these fields in line with the other stats.
Player has become a mess and some of the code needs to be rearranged. Save specific data like hotkeys, hireling and actions don't really belong in the
Player
entity class. Most of this data needs to be moved toGameScreen
or a new container class created similar toRiiablo.client
except theclient
in this case refers to the game client's active player (e.g.,Riiablo.player
).Player
should essentially just be the entity itself, so equipping an item would modify the player entity state to now draw that item, and the other classes likeInventoryPanel
andStashPanel
would use theRiiablo.player
reference instead of the game entity. The other benefit of doing this is that it would probably make implementing multiplayer players easier since only a subset of their info is ever sent to the other clients anyways, thus I could reduce the number ofPlayer
constructors and special considerations for non-local player entities.Additionally, I would really like to support doing something like viewing the items of the players in your current game (possibly of players not in your game from the lobby even). This would either mean that some of their data is downloaded to the client (so each client would contain a list of the other players' equipped items), or I separate this logic from the game code and make this it's own packet which returns the player's equipped items. I don't know how this would effect set bonuses though, so maybe those would need to be tacked onto the packet along with the player's level.