Jump to content

[HTML]Any one can explain 'ThePlayer', 'ismastersim', and related net issues?


Recommended Posts

Tons of questions when trying to bring my original version of mod into DST...

 

1. I saw the code below almost in every prefabs after AddNetwork:

 
    inst.entity:SetPristine()    if not TheWorld.ismastersim then        return inst    end
What exactly does that mean? When reading it I understand that it should quit when it's not a MASTER Sim. Does that mean on all my clients there won't be components added (as they all seem to appear after this return) to that prefab? Like the 'health' component, if not added (on client), an error would be triggered whenever I'd like to use it.
 
2. Just like I mentioned in the code for 1). Suppose I'm having something like this:
AddPrefabPostInit("frog", function(inst)    inst.components.combat.onhitotherfn = function(inst, other, damage)      // whatever here    endend)

It turned out to be an error saying "inst.components.combat is a nil pointer" or something like that, obviously it's true because the components('combat') never added in client side. What does that mean? That's totally wrong and is definitely not what I'm expecting, I'd like the function be added for all "frogs" no matter it's on the MASTER or on CLIENT. How can I do it?

 

3. In my current version, I can add something to the inst (even it might not be recommended):

inst.SomeFunction = function(whatever)  // whateverend

Or:

inst.status = false; // would be used or changed in some a event handler like on 'attacked'

And I found something like a net_bool there defined. Under what circumstance should I add a variable to be a 'net_XXX' version instead of a simple local one? What about functions?

 

4. I'm using 'ThePlayer' in many places of my code. However for most of the time it would told as a 'nil'. I don't understand, for example I'm having a pet dog and when I'm doing this:

inst.components.trader:IsTryingToTradeWithMe(ThePlayer)

For most of the case, I'd got an broken error for the 'nil' ThePlayer, and I have to change the logic to find all possible players around the inst to check. So, What on earth is 'ThePlay' used for? What can it be used for?

 

I'm attaching 2 of my working copy that's running very well on the local version however having tons of problems on DST... one of them is simply adding some extra functions and got broken for 1mins/times, the other one is a mod for pet dogs and got broken every time I wanna to build my added stuff.

 

Any suggestions might help,

 

Thank you all guys!

mods.zip

Edited by yarmyarch
Link to comment
Share on other sites

Well, all your questions stem from a not understanding how the game works in multiplayer. The server is the only one that runs all world simulation code. And the client has as little information available as required to see the result of the servers simulation.

 

Like you want to spawn an item when you hit a frog? Well that only needs to run on the server, the server will spawn a networked item so the client can see and interact with it. Running it on both would turn out badly because then the client will spawn an item the server knows nothing about so you won't be able to interact with it.

 

ThePlayer only makes sense on code that runs purely on clients. All simulation code runs on the server; and the server isn't a player (unless you are playing non dedicated) so that's why ThePlayer is nil.

 

I'm terrible at explaining this stuff, but once you get your head around how it works it's just as easy as non networked code, just... logic... :p.

Link to comment
Share on other sites

@yarmyarch:

SetPristine (which should only be called on the host) tells the engine that everything set up for the entity so far will also be set up identically on clients. It also seems that all engine level components (Transform, AnimState, Physics, etc.) must be added before a call to SetPristine. It's just a matter of reducing network usage. For example, tags added on the host after SetPristine (or added without SetPristine being called at all) are transmitted to all clients, but tags added before it are not. Most networked entities have 'inst.entity:SetPristine()' called at some point, the only exception seems to be some FX entities which need to have some engine level components set up dynamically (such as FX entities with a 'inst.entity:AddFollower()' call).

 

The TheWorld check is precisely for

all my clients there won't be components added (as they all seem to appear after this return) to that prefab? Like the 'health' component, if not added (on client), an error would be triggered whenever I'd like to use it.

not having all components on the client side.

 

It turned out to be an error saying "inst.components.combat is a nil pointer" or something like that, obviously it's true because the components('combat') never added in client side. What does that mean? That's totally wrong and is definitely not what I'm expecting, I'd like the function be added for all "frogs" no matter it's on the MASTER or on CLIENT. How can I do it?

 

The function you want is this?

    inst.components.combat.onhitotherfn = function(inst, other, damage)         if other.components.inventory then             inst.components.thief:StealItem(other)         end     end

This isn't needed client side. Server side, the frog will hit a player, and steal an item. The inventory change will manifest itself through the networked variables.

 

Under what circumstance should I add a variable to be a 'net_XXX' version instead of a simple local one? What about functions?

 

Look at netvars.lua to see how many of them you have. You want a net variable when you want info coveyed to the client. You have a mod added stamina number? Then you want the client to see it, so you setup a say, net_byte, and when the server updates net_byte with net_byte:set(x), the change will propagate to clients. Then you make clients change react to the number change.

 

No networked functions. The function can either run in the server or in the client.

If you want it to run in both, then you use a net_bool like

inst.netvar = net_bool(inst.GUID, -- the id that links them"player.runfunc", -- a unique string name"functiondirty") -- the event name that gets pushed when the function gets dirty-- dirty means that the netvar value changed-- ANY set after set_local will trigger the dirty state
For most of the case, I'd got an broken error for the 'nil' ThePlayer, and I have to change the logic to find all possible players around the inst to check. So, What on earth is 'ThePlay' used for? What can it be used for?

 

ThePlayer is a reference to the character entity on your game.

The game that runs the code is ThePlayer.

As Sarcen said, on dedicated servers, the computer won't have a character, thus, ThePlayer is nil for code running server side.

 

ThePlayer is used for client side code. Since you can pretty much get the player entity context wise in most stuff you will touch, you won't use it. But for example, a potion where a side effect is that the player HUD disappears. You will use ThePlayer.HUD:Hide() on the client machine you want to change. And you will need a netvar to trigger this with a dirty event.

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...