Jump to content

Smashup DST version showcase


Recommended Posts

I've mentioned multiple times that I wasn't going to make a DST version of this mod because I am absolutely terrible with this version of the game's code. But I got so many requests, and I just got curious to see if it could be done, so here it is. And dear lord this was a small nightmare. I am so bad with DST coding, the whole concept of host and client and RPCs and net variables and blah- I hate it. Nothing is real on the client side, everything is a lie. You will never know the lengths in which I have gone to try and get this stupid health number to show up on everyone's screen correctly. somebody please help me fix the huds

I don't think I've posted any of this mod's teasers on this side of the forums before, so maybe this is new to everyone here.

The lag is pretty bad. I expected nothing less, though. Don't Starve's net code isn't designed for this sort of stuff. But it fluctuates, and sometimes it actually feels alright, a little better than I thought it would be. It's still playable, though! And if my recording partner hadn't had lost their controller charger a week before the recording session, I would have been a pretty great fight.

 

I guess I can get more technical with it in this forum, can't I? I don't really get to talk about what's happening under the hood very often.

There is a LOT I had to re-do for the change from the single player version to the multiplayer version. Unlike the single player version, in this version, the player actually "is" their fighter. The fighter prefab replaces the old player_common prefab entirely, and they are created when logging on and removed when logged out.  Right now, players just drop in as Wilson and then pick from a character select screen when they die, but I don't plan to keep it that way. But I still have to work out how I'm going to do character spawning, because I have been really struggling with finding a way to de-spawn players and then re-spawning them as someone else. (right now, they just tp to the spawn point and change builds and stategraphs when changing character, but at some point I'd like to try and keep each character to their own prefab if at all possible)

Link to comment
Share on other sites

This looks very terrific! It's definitely quite a unique mod, the first like this I've seen.

On 29/08/2017 at 8:29 AM, pickleplayer said:

the whole concept of host and client and RPCs and net variables and blah- I hate it. Nothing is real on the client side, everything is a lie. You will never know the lengths in which I have gone to try and get this stupid health number to show up on everyone's screen correctly. somebody please help me fix the huds

If you want you display HUD elements for the client, the mod needs to be set to all_clients_require. And unfortunately, you are required to mess with netvars and sorts to be able to display HUD elements that show information. Also, you should be testing your mod with caves enabled to make sure it works properly for clients.

To simplify: The server and clients don't know what each other knows. This means they need to send information to each other via RPCs and netvars. (Note that I only know very basic stuff about these, I'm not too knowledgeable)

RPCs are for when you want the client to send information to the server. Be careful with this though, since clients can exploit this with console commands. I assume that your mod already makes use of RPCs, I think.

Net variables are for when you want the server to send information to the client. These are needed because a lot of data (like components, etc) are not available for the client. HUD elements like the health, hunger, and sanity badges display values from netvars. More information about netvars are available in data/scripts/netvars.lua:

Spoiler

--[[

    net_bool                1-bit boolean
    net_tinybyte            3-bit unsigned integer   [0..7]
    net_smallbyte           6-bit unsigned integer   [0..63]
    net_byte                8-bit unsigned integer   [0..255]
    net_shortint            16-bit signed integer    [-32767..32767]
    net_ushortint           16-bit unsigned integer  [0..65535]
    net_int                 32-bit signed integer    [-2147483647..2147483647]
    net_uint                32-bit unsigned integer  [0..4294967296]
    net_float               32-bit float
    net_hash                32-bit hash of the string assigned
    net_string              variable length string
    net_entity              entity instance
    net_bytearray           array of 8-bit unsigned integers (max size = 31)
    net_smallbytearray      array of 6-bit unsigned integers (max size = 31)

    * Arrays are expensive.  Avoid using them, especially if the values
      will change often.

    * net_hash can be set by a hash or string (automatically converted to
      hash), but only returns the hash value when read.  The network cost
      is the same as a 32-bit unsigned integer.

    * netvars must exist and be declared identically on server and clients
      for each entity, otherwise entity deserialization will fail.  Note
      that this means if a MOD uses netvars, then server and clients must
      all have the same MOD active.

    * Server and clients may register different listeners for dirty events.

    * netvar dirty events are triggered before lua update.

--]]

----------------------------------------------------------------------------

--[[

    netvar:set(x)
    - Call on the server to set the value, which will be synced to clients.
    - Dirty event is triggered on server and clients (only if value has
      actually changed).

    netvar:value()
    - Call on the server or clients to read the current value.

    netvar:set_local(x)
    - Call on the server or clients to set the value without triggering
      a sync or dirty event.
    - NOTE: this results in the next server set(x) to be dirty regardless
            of whether the value changed, since we assume the client may
            have set_local(x) to any arbitrary value.

    * set_local is generally used in code paths shared between server and
      clients.  Clients may have enough information (such as elapsed time)
      to estimate and update the value locally.  Sharing the code path also
      allows the server to be aware that the value is being updated locally
      on clients.

    * Example usage of set_local(x) is to let clients update smooth timer
      ticks locally.  Server saves bandwidth by only needing set(x) to
      force a resync every now and then.

--]]

----------------------------------------------------------------------------

--[[

    net_event (as a wrapper over net_bool)
    net_event:push()

    * Use events for one-shot triggers such as a sound FX, but not state
      changes (which should use net_bool instead).

--]]

Also again, I might be wrong about these. There are people more knowledgeable about these stuff.

Link to comment
Share on other sites

@JohnWatson Thanks! I'm pretty proud of it thus far.

Yea, I think I'm finally getting the hang of RPCs. But net variables... man, everything just goes right over my head. I've gone through the forums and studied up on the posts that talk about it, I've been up and down that mod "the hunt" provided by the devs, and I've scoured existing mods in attempts to replicate anything similar, but heck I just couldn't get anything to work. 

Yea, It's because the player's health is stored server side, and the client's hud always displays 0% because it can't access the player's actual health stored on the server. (the huds show up, I just disabled them for the video because they only show 0%) Player's don't use the actual health component, I have a custom component called "percent" (which is basically just a slightly edited version of health) and I don't know if that has anything to do with my failures. But it's been months since my last attempt to fix them, so I don't even remember where I left off at the moment.

Say, would there be any workarounds to set each player's hud if we assume every player will be seeing the same set of huds? Players all see each others huds in the top part of the screen. The only time players wont be seeing the same screen is when using the character select screen, which already works fine.

Also, where did you get that list of netvar functions? I know I've seen that top section that lists the different types, but the sections under that don't look familiar to me.

 

Link to comment
Share on other sites

On 8/30/2017 at 9:33 PM, ZupaleX said:

Maybe if you explain what is your issue with the net_vars I could help? It's really not all that complicated :)

 

I've spent these last few days diving back into my netvars/hud system to try and find out where I left off and what the actual problem a was, but I managed to accidentally fix them. I don't think I really knew what I was doing with them in the first place, but I'm starting to suspect it was actually an issue with the way I had my health badges set up to not update properly, not the netvars.

But it was probably a little bit of both. 

So I guess they were much simpler than I thought, I think. I'm only using two at the moment, but I feel like I still don't understand them as well as I could. So I can just declare them anywhere, set them anywhere, and access their values anywhere? And whatever entity I put them on keeps their own version of it? Can clients access other client's netvar values? I think this is just stuff I'll have to figure out myself later, but they work fine for now and I've got other things to worry about like FINDING OUT HOW TO STOP THESE WAVES FROM MOVING AROUND ALREADY

Link to comment
Share on other sites

No, netvars need to be defined for both the client and the server before the deserialization happens. When an entity is created, for a short while the server and the client share the same information. That's why you have to create the netvars at the same time for server and client, during that small amount of time where the entity is "the same". You noticed that you pass the GUID of the entity as an argument to the netvar. If you do a small test by connecting to a dedicated server (you need admin rights) and selecting an entity, then typing in the console

c_select():GetGUID()

first in remote mode so executed by the server, then in local mode (press ctrl to make the "Remote" disappear in front of the console) to get it executed by the client, the very same entity will have different GUID. This is "the deserialization".

So you cannot add a netvar at any time, you have to do it while the entity is getting created and before the deserialization happens.

Also this should answer your question about each instance having it's own instantiation of the netvar => yes

Other clients cannot easily access the netvars which are not theirs, because this information in handled by the server. Basically it's a 2 way communication only.

Hope this helps.

PS: some of my explanations here are kind of simplified. I tried to put quotes symbols when I just used a shortcut.

 

Link to comment
Share on other sites

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
 Share

×
  • Create New...