mikesmullin 31 Report post Posted August 19, 2017 (edited) ## Client / Server Simulation Relationship Mods should use these always to be clear about which side you want code to run on; by default all Lua code runs on BOTH client and server side, and this can be very wasteful! ### Definitions: - client host: DST > Play > Host Game > Generate/Resume World - remote client: DST > Play > Browse Games > Join - dedicated: Steam > Tools > Dont Starve Together Dedicated Server | | client host | remote client | dedicated | ------------------------------------------------------------------ | TheWorld.ismastersim | true | false | true | | TheNet.GetIsServer() | true | false | true | | TheNet.IsDedicated() | false | false | true | | TheNet.GetIsClient() | false | true | false | `TheWorld.ismastersim` == `TheNet:GetIsServer()` // this is running on a computer hosting the game `not TheWorld.ismastersim` == `TheNet:GetIsClient()` // this is running on a computer joining a game `TheNet:IsDedicated()` // this is a headless dedicated server NOTICE client host means client and server share a single simulator; evaluating one instance of the logic for both client and server. ## Netvars (Network Variables) A collection of classes representing platform-agnostic data types; streamed change events synchronize their values over a networked machine cluster. The intended use case for netvars is to be exclusively `:set()` by the server, while `:value()` is read by the client(s). Although `:set_local()` can be used by any side, its most useful on the client-side for network lag interpolation between `:set()` values and subsequent dirty events. The interface for dirty event listeners is `f(e:Entity):Void`. Netvars must be defined on both sending and receiving sides before changing values will cause a sync or dirty event. fig. 1: `Entity:ListenForEvent()` will trigger | if listening from... | and `:set()` on... | | | client host | remote client | dedicated | |----------------------|-------------|---------------|------------| | client host | true | false | - | | remote client | true | false | true | | dedicated | - | false | true | fig. 2: `NetVar:set()` will always change local `NetVar:value()`, but it will only sync | `:value()` of... | if `:set()` on... | | | client host | remote client | dedicated | |----------------------|-------------|---------------|------------| | client host | true | false | - | | remote client | true | false | true | | dedicated | - | false | true | Its not an error to `:set()`, or `:set_local()` from the client, but realize it only changes it for that one local client instance. If you do it mistakenly, you will find the `:value()` is not the same on the server or other clients. If you bind a new netvar to an Entity GUID that only exists on the client, or an Entity that does not have an `:AddNetwork()` component attached to it, it will NOT sync or trigger, neither locally or remotely. Binding a netvar to an Entity GUID that does not exist on the client side will cause a hard crash on the client. Network protocol is an un-encrypted implementation of RakNet mainly udp/10999 http://raknet.com/raknet/manual/ ``` interface NetVar<T> { /** * Register event handler for network variable of a given name. * * @param guid - Entity GUID. * @param name - Network variable name. Must be unique per entity. * @param dirtyEventName - Can be bound by `Entity:ListenForEvent()`. See set() for details. */ public function constructor(guid:GUID, name:String, ?dirtyEventName:String):Void; /** * Unidirectional setter; * - Sets new value locally * - Triggers dirty event listeners (see fig. 1 above) * - Syncs new value from server to client(s) (see fig. 2 above) * * Will no-op unless one of the following is true: * * - given value is different than last value, or; * - `set_local()` used one or more times since last `set()`. */ public function set(value:T):Void; /** * Local-only setter; * Does NOT notify the cluster or trigger dirty event listeners. * * Recommended for frame-rate-dependant interpolation. * (e.g. client makes guesses locally until corrected by the server) */ public function set_local(value:T):Void; /** * Local-only getter; * Return last value received by network sync, :set(), or :set_local(). */ public function value():T; } /** * 1-bit boolean * * Default: false * * e.g., set_local(true); set(true); can be used on net_bool * to transmit event notifications without having to * toggle true on/off between each event. */ interface net_bool extends NetVar<Bool> {}; /** * 8-bit unsigned integer [0..255] */ interface net_byte extends NetVar<Int> {}; /** * array of 8-bit unsigned integers (max size = 31) * * Arrays are expensive; avoid if you will dirty them often. */ interface net_bytearray extends NetVar<Bytes> {}; /** * unsigned 64-bit integer containing entity network id * represents the entity instance */ interface net_entity extends NetVar<Entity> {}; /** * 32-bit float */ interface net_float extends NetVar<Float> {}; /** * 32-bit unsigned integer * * If value is a number, it is forwarded as the hash. * If value is a string, it is converted to a hash before sending. * * REMINDER: The hash algorithm is deterministic, so expect * clients to agree on output value regardless of platform. */ interface net_hash extends NetVar<Hash> {}; /** * 32-bit signed integer [-2147483647..2147483647] */ interface net_int extends NetVar<Int> {}; /** * 16-bit signed integer [-32767..32767] */ interface net_shortint extends NetVar<Int> {}; /** * Maps to an unsigned 32-bit integer. */ interface net_uint extends NetVar<Int> {}; /** * 16-bit unsigned integer [0..65535] */ interface net_ushortint extends NetVar<Int> {}; /** * 3-bit unsigned integer [0..7] */ interface net_tinybyte extends NetVar<Int> {}; /** * 6-bit unsigned integer [0..63] */ interface net_smallbyte extends NetVar<Int> {}; /** * array of 6-bit unsigned integers (max size = 31) * * Arrays are expensive; avoid if you will dirty them often. */ interface net_smallbytearray extends NetVar<Bytes> {}; /** * variable length string */ interface net_string extends NetVar<String> {}; /** * A convenience wrapper over net_bool. * does the set_local(true) set(true) trick for you. * * Use for one-shot triggers. */ interface net_event extends NetVar<String> {}; /** * Remote trigger. * * Like set() but no value is required. */ public function push(): Void; } ``` Edited August 19, 2017 by mikesmullin typo 5 3 Share this post Link to post Share on other sites