@dcl/protocol 1.0.0-28974105118.commit-a598406 → 1.0.0-28980486989.commit-1e80e43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -0
- package/out-js/decentraland/kernel/apis/restricted_actions.gen.d.ts +19 -0
- package/out-js/decentraland/kernel/apis/restricted_actions.gen.js +54 -1
- package/out-js/decentraland/kernel/apis/restricted_actions.gen.js.map +1 -1
- package/out-js/decentraland/kernel/comms/rfc4/comms.gen.d.ts +21 -0
- package/out-js/decentraland/kernel/comms/rfc4/comms.gen.js +124 -4
- package/out-js/decentraland/kernel/comms/rfc4/comms.gen.js.map +1 -1
- package/out-js/decentraland/sdk/components/avatar_shape.gen.d.ts +8 -0
- package/out-js/decentraland/sdk/components/avatar_shape.gen.js +35 -1
- package/out-js/decentraland/sdk/components/avatar_shape.gen.js.map +1 -1
- package/out-ts/decentraland/kernel/apis/restricted_actions.gen.ts +56 -0
- package/out-ts/decentraland/kernel/comms/rfc4/comms.gen.ts +166 -2
- package/out-ts/decentraland/sdk/components/avatar_shape.gen.ts +34 -0
- package/package.json +9 -6
- package/proto/decentraland/common/options.proto +51 -0
- package/proto/decentraland/common/quantization_example.proto +164 -0
- package/proto/decentraland/kernel/apis/restricted_actions.proto +5 -0
- package/proto/decentraland/kernel/comms/rfc4/comms.proto +11 -0
- package/proto/decentraland/pulse/pulse_client.proto +79 -0
- package/proto/decentraland/pulse/pulse_server.proto +142 -0
- package/proto/decentraland/pulse/pulse_shared.proto +57 -0
- package/proto/decentraland/sdk/components/avatar_shape.proto +5 -0
- package/proto/decentraland/sdk/components/light_source.proto +1 -1
- package/proto/decentraland/sdk/components/virtual_camera.proto +2 -0
- package/protoc-gen-bitwise/generator_csharp.js +248 -0
- package/protoc-gen-bitwise/options.js +139 -0
- package/protoc-gen-bitwise/plugin.js +87 -0
- package/protoc-gen-bitwise/runtime/cs/BitReader.cs +112 -0
- package/protoc-gen-bitwise/runtime/cs/BitWriter.cs +117 -0
- package/protoc-gen-bitwise/runtime/cs/Quantize.cs +70 -0
- package/protoc-gen-bitwise/wire.js +239 -0
- package/proto/buf.yaml +0 -47
- package/proto/google/LICENSE +0 -27
- package/proto/google/README.md +0 -1
- package/proto/google/api/annotations.json +0 -83
- package/proto/google/api/annotations.proto +0 -11
- package/proto/google/api/http.json +0 -86
- package/proto/google/api/http.proto +0 -31
- package/proto/google/protobuf/api.json +0 -118
- package/proto/google/protobuf/api.proto +0 -34
- package/proto/google/protobuf/descriptor.json +0 -739
- package/proto/google/protobuf/descriptor.proto +0 -286
- package/proto/google/protobuf/source_context.json +0 -20
- package/proto/google/protobuf/source_context.proto +0 -7
- package/proto/google/protobuf/type.json +0 -202
- package/proto/google/protobuf/type.proto +0 -89
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package decentraland.common;
|
|
4
|
+
|
|
5
|
+
import "decentraland/common/options.proto";
|
|
6
|
+
|
|
7
|
+
// High-frequency player state messages sent on Channel 1 (unreliable sequenced).
|
|
8
|
+
//
|
|
9
|
+
// Every message below uses the protoc-gen-bitwise annotations to minimise
|
|
10
|
+
// wire size. Wire costs are listed per-message so the trade-offs are clear.
|
|
11
|
+
//
|
|
12
|
+
// Annotation cheat-sheet:
|
|
13
|
+
// [(decentraland.common.quantized) = { min: F, max: F, bits: N }]
|
|
14
|
+
// → stores a float as a uint32 quantized to N bits over [min, max].
|
|
15
|
+
// → protobuf encodes the uint32 as a varint: values ≤ 2^14-1 cost 2 bytes,
|
|
16
|
+
// values ≤ 2^21-1 cost 3 bytes; the generated partial class adds a
|
|
17
|
+
// float {Name}Quantized accessor that encodes/decodes transparently.
|
|
18
|
+
// [(decentraland.common.quantized_power) = { max: F, pow: F, bits: N }]
|
|
19
|
+
// → stores a signed float over [-max, max] as an (N-1)-bit linear unorm
|
|
20
|
+
// magnitude (high bits) plus a sign (LSB), reconstructed as sign·max·u^pow.
|
|
21
|
+
// Zero is exact, and pow>1 buys fine resolution near zero at the cost of
|
|
22
|
+
// coarse near ±max. Putting the sign in the LSB keeps a small |value| of
|
|
23
|
+
// either direction in one varint byte. Same generated float {Name}Quantized
|
|
24
|
+
// accessor as the linear option.
|
|
25
|
+
// [(decentraland.common.bit_packed) = { bits: N }]
|
|
26
|
+
// → documents that this uint32 uses at most N bits; protobuf encodes it
|
|
27
|
+
// as a varint (same savings, no generated accessor needed).
|
|
28
|
+
// (no annotation)
|
|
29
|
+
// → standard protobuf encoding (bool/double/etc. at natural width).
|
|
30
|
+
//
|
|
31
|
+
// Varint byte costs at worst-case (all bits set):
|
|
32
|
+
// ≤ 7 bits → 1 byte (max 127)
|
|
33
|
+
// ≤ 14 bits → 2 bytes (max 16 383)
|
|
34
|
+
// ≤ 21 bits → 3 bytes (max 2 097 151)
|
|
35
|
+
// Proto3 omits fields equal to their default value (0), so average cost is lower.
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// PositionDelta — Δ position relative to last acknowledged full snapshot.
|
|
39
|
+
//
|
|
40
|
+
// Sent every client tick (~10 Hz) on Channel 1.
|
|
41
|
+
//
|
|
42
|
+
// Field | Type | Range | Q bits | Wire worst-case
|
|
43
|
+
// ------------|--------|----------------|--------|-----------------------
|
|
44
|
+
// dx | uint32 | [-100, 100] | 16 | tag 1B + varint 3B = 4B
|
|
45
|
+
// dy | uint32 | [-100, 100] | 16 | tag 1B + varint 3B = 4B
|
|
46
|
+
// dz | uint32 | [-100, 100] | 16 | tag 1B + varint 3B = 4B
|
|
47
|
+
// entity_id | uint32 | [0, 1 048 575] | 20 | tag 1B + varint 3B = 4B
|
|
48
|
+
// sequence | uint32 | [0, 4 095] | 12 | tag 1B + varint 2B = 3B
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Worst-case: 19 B (vs. 20 B raw: 3×float + 2×uint32)
|
|
51
|
+
// Step: dx/dy/dz ≈ 0.003 units
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
message PositionDelta {
|
|
54
|
+
uint32 dx = 1 [(decentraland.common.quantized) = { min: -100.0, max: 100.0, bits: 16 }];
|
|
55
|
+
uint32 dy = 2 [(decentraland.common.quantized) = { min: -100.0, max: 100.0, bits: 16 }];
|
|
56
|
+
uint32 dz = 3 [(decentraland.common.quantized) = { min: -100.0, max: 100.0, bits: 16 }];
|
|
57
|
+
uint32 entity_id = 4 [(decentraland.common.bit_packed) = { bits: 20 }];
|
|
58
|
+
uint32 sequence = 5 [(decentraland.common.bit_packed) = { bits: 12 }];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// PlayerInput — client input snapshot for server-side reconciliation.
|
|
63
|
+
//
|
|
64
|
+
// Sent every client frame (~30 Hz) on Channel 1.
|
|
65
|
+
//
|
|
66
|
+
// Field | Type | Range | Q bits | Wire worst-case
|
|
67
|
+
// ------------|--------|----------------|--------|-----------------------
|
|
68
|
+
// move_x | uint32 | [-1, 1] | 8 | tag 1B + varint 2B = 3B
|
|
69
|
+
// move_z | uint32 | [-1, 1] | 8 | tag 1B + varint 2B = 3B
|
|
70
|
+
// yaw | uint32 | [-180, 180] | 12 | tag 1B + varint 2B = 3B
|
|
71
|
+
// buttons | uint32 | bitmask | 8 | tag 1B + varint 2B = 3B
|
|
72
|
+
// sequence | uint32 | [0, 4 095] | 12 | tag 1B + varint 2B = 3B
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Worst-case: 15 B (vs. 20 B raw: 3×float + 2×uint32)
|
|
75
|
+
// Step: move_x/move_z ≈ 0.008; yaw ≈ 0.088°
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
message PlayerInput {
|
|
78
|
+
// Normalised joystick axes in [-1, 1].
|
|
79
|
+
uint32 move_x = 1 [(decentraland.common.quantized) = { min: -1.0, max: 1.0, bits: 8 }];
|
|
80
|
+
uint32 move_z = 2 [(decentraland.common.quantized) = { min: -1.0, max: 1.0, bits: 8 }];
|
|
81
|
+
|
|
82
|
+
// Horizontal look direction in degrees.
|
|
83
|
+
uint32 yaw = 3 [(decentraland.common.quantized) = { min: -180.0, max: 180.0, bits: 12 }];
|
|
84
|
+
|
|
85
|
+
// Bitmask of active buttons (see ButtonFlags below).
|
|
86
|
+
uint32 buttons = 4 [(decentraland.common.bit_packed) = { bits: 8 }];
|
|
87
|
+
|
|
88
|
+
// Rolling input sequence number used by the server for reconciliation.
|
|
89
|
+
uint32 sequence = 5 [(decentraland.common.bit_packed) = { bits: 12 }];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// VelocityState — per-axis velocity, demonstrating the power-law quantizer.
|
|
94
|
+
//
|
|
95
|
+
// Velocity needs an exact zero (a stopped avatar must read 0, not a quantization
|
|
96
|
+
// residual, or it drifts) and fine resolution at locomotion speeds, but only
|
|
97
|
+
// coarse resolution near the ±50 m/s extremes. The linear quantizer can give
|
|
98
|
+
// none of these from 8 bits: its codes straddle zero (±0.196) and spend uniform
|
|
99
|
+
// resolution on speeds that never occur. quantized_power solves all three.
|
|
100
|
+
//
|
|
101
|
+
// Field | Type | Range | pow | bits | Wire worst-case
|
|
102
|
+
// -------|--------|------------|-----|------|-----------------------
|
|
103
|
+
// vx | uint32 | [-50, 50] | 2 | 8 | tag 1B + varint 1–2B = 2–3B
|
|
104
|
+
// vy | uint32 | [-50, 50] | 2 | 8 | tag 1B + varint 1–2B = 2–3B
|
|
105
|
+
// vz | uint32 | [-50, 50] | 2 | 8 | tag 1B + varint 1–2B = 2–3B
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Step: ≈ 0.003 m/s near zero, ≈ 0.78 m/s near ±50 (vs. 0.392 uniform linear)
|
|
108
|
+
// Wire: sign in the LSB, so |v| ≲ 12.5 m/s (magnitude code ≤ 63) costs a single
|
|
109
|
+
// varint byte regardless of direction; only faster axes spill to 2 bytes.
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
message VelocityState {
|
|
112
|
+
uint32 vx = 1 [(decentraland.common.quantized_power) = { max: 50.0, pow: 2.0, bits: 8 }];
|
|
113
|
+
uint32 vy = 2 [(decentraland.common.quantized_power) = { max: 50.0, pow: 2.0, bits: 8 }];
|
|
114
|
+
uint32 vz = 3 [(decentraland.common.quantized_power) = { max: 50.0, pow: 2.0, bits: 8 }];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Bitmask values for PlayerInput.buttons.
|
|
118
|
+
enum ButtonFlags {
|
|
119
|
+
BF_NONE = 0;
|
|
120
|
+
BF_JUMP = 1; // bit 0
|
|
121
|
+
BF_SPRINT = 2; // bit 1
|
|
122
|
+
BF_INTERACT = 4; // bit 2
|
|
123
|
+
BF_EMOTE = 8; // bit 3
|
|
124
|
+
BF_CROUCH = 16; // bit 4
|
|
125
|
+
// bits 5-7 reserved
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// AvatarStateSnapshot — full authoritative state, sent on Channel 0 (reliable)
|
|
130
|
+
// or on resync requests. Demonstrates wider ranges and mixed encodings.
|
|
131
|
+
//
|
|
132
|
+
// Field | Type | Range | Q bits | Wire worst-case
|
|
133
|
+
// -----------------|--------|------------------|--------|-----------------------
|
|
134
|
+
// x | uint32 | [-4096, 4096] | 16 | tag 1B + varint 3B = 4B
|
|
135
|
+
// y | uint32 | [-256, 256] | 14 | tag 1B + varint 2B = 3B
|
|
136
|
+
// z | uint32 | [-4096, 4096] | 16 | tag 1B + varint 3B = 4B
|
|
137
|
+
// pitch | uint32 | [-90, 90] | 10 | tag 1B + varint 2B = 3B
|
|
138
|
+
// yaw | uint32 | [-180, 180] | 12 | tag 1B + varint 2B = 3B
|
|
139
|
+
// entity_id | uint32 | [0, 1 048 575] | 20 | tag 1B + varint 3B = 4B
|
|
140
|
+
// animation_state | uint32 | [0, 63] | 6 | tag 1B + varint 1B = 2B
|
|
141
|
+
// is_grounded | bool | — | — | tag 1B + varint 1B = 2B
|
|
142
|
+
// timestamp | double | — | — | tag 1B + fixed64 8B = 9B
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// Worst-case: 34 B (vs. 45 B raw: 5×float + 2×uint32 + bool + double)
|
|
145
|
+
// Step: x/z ≈ 0.125 units; y ≈ 0.031 units; pitch ≈ 0.176°; yaw ≈ 0.088°
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
message AvatarStateSnapshot {
|
|
148
|
+
// World-space position.
|
|
149
|
+
uint32 x = 1 [(decentraland.common.quantized) = { min: -4096.0, max: 4096.0, bits: 16 }];
|
|
150
|
+
uint32 y = 2 [(decentraland.common.quantized) = { min: -256.0, max: 256.0, bits: 14 }];
|
|
151
|
+
uint32 z = 3 [(decentraland.common.quantized) = { min: -4096.0, max: 4096.0, bits: 16 }];
|
|
152
|
+
|
|
153
|
+
// View angles.
|
|
154
|
+
uint32 pitch = 4 [(decentraland.common.quantized) = { min: -90.0, max: 90.0, bits: 10 }];
|
|
155
|
+
uint32 yaw = 5 [(decentraland.common.quantized) = { min: -180.0, max: 180.0, bits: 12 }];
|
|
156
|
+
|
|
157
|
+
// Identity and animation state.
|
|
158
|
+
uint32 entity_id = 6 [(decentraland.common.bit_packed) = { bits: 20 }];
|
|
159
|
+
uint32 animation_state = 7 [(decentraland.common.bit_packed) = { bits: 6 }];
|
|
160
|
+
|
|
161
|
+
// Un-annotated fields — encoded at their natural width.
|
|
162
|
+
bool is_grounded = 8;
|
|
163
|
+
double timestamp = 9; // server epoch milliseconds
|
|
164
|
+
}
|
|
@@ -63,6 +63,8 @@ message CopyToClipboardRequest {
|
|
|
63
63
|
|
|
64
64
|
message EmptyResponse { }
|
|
65
65
|
|
|
66
|
+
message StopEmoteRequest { }
|
|
67
|
+
|
|
66
68
|
service RestrictedActionsService {
|
|
67
69
|
// MovePlayerTo will move the player to a position relative to the current scene.
|
|
68
70
|
// If 'duration' field is used in the request, the success response depends on the
|
|
@@ -93,4 +95,7 @@ service RestrictedActionsService {
|
|
|
93
95
|
|
|
94
96
|
// CopyToClipboard copies the provided text into the clipboard
|
|
95
97
|
rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {}
|
|
98
|
+
|
|
99
|
+
// StopEmote will stop the current emote
|
|
100
|
+
rpc StopEmote(StopEmoteRequest) returns (SuccessResponse) {}
|
|
96
101
|
}
|
|
@@ -94,6 +94,14 @@ message PlayerEmote {
|
|
|
94
94
|
uint32 incremental_id = 1;
|
|
95
95
|
string urn = 2;
|
|
96
96
|
float timestamp = 3;
|
|
97
|
+
optional bool is_stopping = 4; // true means the emote has been stopped in the sender's client
|
|
98
|
+
optional bool is_repeating = 5; // true when it is not the first time the looping animation plays
|
|
99
|
+
optional int32 interaction_id = 6; // identifies an interaction univocaly, established when the start animation is triggered
|
|
100
|
+
optional int32 social_emote_outcome = 7; // -1 means it does not use an outcome animation
|
|
101
|
+
optional bool is_reacting = 8; // to a social emote started by other user
|
|
102
|
+
optional string social_emote_initiator = 9; // wallet address of the user that initiated social emote
|
|
103
|
+
optional string target_avatar = 10; // wallet address of the user whose avatar is the target of a directed emote
|
|
104
|
+
optional uint32 mask = 11; // mask for which bones an animation applies to.
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
message SceneEmote {
|
|
@@ -126,6 +134,9 @@ message ProfileResponse {
|
|
|
126
134
|
message Chat {
|
|
127
135
|
string message = 1;
|
|
128
136
|
double timestamp = 2;
|
|
137
|
+
// Extension: optional forwarded_from to identify the original sender when
|
|
138
|
+
// messages are forwarded through an SFU
|
|
139
|
+
optional string forwarded_from = 3;
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
message Scene {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package decentraland.pulse;
|
|
4
|
+
|
|
5
|
+
import "decentraland/pulse/pulse_shared.proto";
|
|
6
|
+
import "decentraland/common/options.proto";
|
|
7
|
+
|
|
8
|
+
message HandshakeRequest {
|
|
9
|
+
bytes auth_chain = 1;
|
|
10
|
+
int32 profile_version = 2;
|
|
11
|
+
optional PlayerInitialState initial_state = 3;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Describes the initial state of the player if (re-)connected in the middle of the session
|
|
15
|
+
message PlayerInitialState {
|
|
16
|
+
PlayerState state = 1;
|
|
17
|
+
optional string emote_id = 2;
|
|
18
|
+
optional uint32 emote_duration_ms = 3;
|
|
19
|
+
// Indicates how many milliseconds ago the emote was started
|
|
20
|
+
optional uint32 emote_start_offset_ms = 4;
|
|
21
|
+
// Non-empty realm identifier. Rejected if empty.
|
|
22
|
+
string realm = 5;
|
|
23
|
+
optional int32 emote_mask = 6;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Similarly to the LiveKit pipeline, a peer announces the version of its profile but
|
|
27
|
+
// it only does it when it's changed as it's sent reliably and stored on the server for other peers
|
|
28
|
+
message ProfileVersionAnnouncement {
|
|
29
|
+
int32 version = 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Since the server doesn't simulate the scenes state, it trusts the values from the client
|
|
33
|
+
message PlayerStateInput {
|
|
34
|
+
PlayerState state = 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Client sends resync request if it has a gap in the known sequences and, thus, can't apply a delta.
|
|
38
|
+
// It's sent reliably to prevent further desynchronization
|
|
39
|
+
message ResyncRequest {
|
|
40
|
+
uint32 subject_id = 1;
|
|
41
|
+
// highest seq the client actually has for this subject
|
|
42
|
+
uint32 known_seq = 2;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Client → Server. Client requests to start an emote.
|
|
46
|
+
message EmoteStart {
|
|
47
|
+
string emote_id = 1;
|
|
48
|
+
optional uint32 duration_ms = 2;
|
|
49
|
+
PlayerState player_state = 3;
|
|
50
|
+
optional int32 mask = 4;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Client → Server. Client requests to stop a looping emote.
|
|
54
|
+
// One-shot emotes are terminated by the server timer.
|
|
55
|
+
message EmoteStop {
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Client → Server. Also announces the peer's realm; peers in different realms never see each
|
|
59
|
+
// other. Must be the first gameplay message after handshake. Same-realm re-teleports are valid.
|
|
60
|
+
message TeleportRequest {
|
|
61
|
+
int32 parcel_index = 1;
|
|
62
|
+
uint32 position_x = 2 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
63
|
+
uint32 position_y = 3 [(decentraland.common.quantized) = { min: 0, max: 200, bits: 13 }];
|
|
64
|
+
uint32 position_z = 4 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
65
|
+
// Non-empty realm identifier. Rejected if empty.
|
|
66
|
+
string realm = 5;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
message ClientMessage {
|
|
70
|
+
oneof message {
|
|
71
|
+
HandshakeRequest handshake = 1;
|
|
72
|
+
PlayerStateInput input = 2;
|
|
73
|
+
ResyncRequest resync = 3;
|
|
74
|
+
ProfileVersionAnnouncement profile_announcement = 4;
|
|
75
|
+
EmoteStart emote_start = 5;
|
|
76
|
+
EmoteStop emote_stop = 6;
|
|
77
|
+
TeleportRequest teleport = 7;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package decentraland.pulse;
|
|
4
|
+
|
|
5
|
+
import "decentraland/common/options.proto";
|
|
6
|
+
import "decentraland/pulse/pulse_shared.proto";
|
|
7
|
+
|
|
8
|
+
message HandshakeResponse {
|
|
9
|
+
bool success = 1;
|
|
10
|
+
optional string error = 2;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
message PlayerProfileVersionsAnnounced {
|
|
14
|
+
uint32 subject_id = 1;
|
|
15
|
+
int32 version = 2;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
message PlayerStateDeltaTier0 {
|
|
19
|
+
uint32 subject_id = 1;
|
|
20
|
+
|
|
21
|
+
// Between two consecutive server simulation ticks, the subject may have sent multiple inputs, each incrementing Seq by 1. So
|
|
22
|
+
// the delta's NewSeq will naturally jump by more than 1 compared to the previous delta — even with zero packet loss.
|
|
23
|
+
// Without the "BaselineSeq" the client has no way to detect the package loss
|
|
24
|
+
uint32 baseline_seq = 2;
|
|
25
|
+
uint32 new_seq = 3;
|
|
26
|
+
uint32 server_tick = 4;
|
|
27
|
+
|
|
28
|
+
// While the player doesn't cross the parcel, this field is omitted from diff
|
|
29
|
+
optional int32 parcel_index = 5;
|
|
30
|
+
|
|
31
|
+
// X position inside the parcel
|
|
32
|
+
optional uint32 position_x = 6 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
33
|
+
|
|
34
|
+
// Y position
|
|
35
|
+
optional uint32 position_y = 7 [(decentraland.common.quantized) = { min: 0, max: 200, bits: 13 }];
|
|
36
|
+
|
|
37
|
+
// Z position inside the parcel
|
|
38
|
+
optional uint32 position_z = 8 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
39
|
+
|
|
40
|
+
// Power-law quantized: a sign bit + 7-bit magnitude curve over [-50, 50]. Zero is exactly
|
|
41
|
+
// representable (a stopped peer reports an exact 0 instead of the linear quantizer's ±0.196
|
|
42
|
+
// residual that drove foreign-avatar drift), and pow=2 concentrates resolution at the low speeds
|
|
43
|
+
// where avatars actually move, leaving only the visually-irrelevant extremes coarse.
|
|
44
|
+
optional uint32 velocity_x = 9 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
45
|
+
optional uint32 velocity_y = 10 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
46
|
+
optional uint32 velocity_z = 11 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
47
|
+
|
|
48
|
+
optional uint32 rotation_y = 12 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
49
|
+
optional uint32 movement_blend = 13 [(decentraland.common.quantized) = { min: 0, max: 3, bits: 5 }];
|
|
50
|
+
optional uint32 slide_blend = 14 [(decentraland.common.quantized) = { min: 0, max: 1, bits: 4 }];
|
|
51
|
+
optional uint32 head_yaw = 15 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
52
|
+
optional uint32 head_pitch = 16 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
53
|
+
|
|
54
|
+
optional uint32 state_flags = 17;
|
|
55
|
+
optional GlideState glide_state = 18;
|
|
56
|
+
|
|
57
|
+
optional int32 jump_count = 19;
|
|
58
|
+
|
|
59
|
+
// Absolute world hit position the player is pointing at.
|
|
60
|
+
// Only meaningful when POINTING_AT is set in `state_flags`.
|
|
61
|
+
//
|
|
62
|
+
// X/Z use 17 bits over the world span (~±3000m, covers GenesisCity + border +
|
|
63
|
+
// raycast cutoff) which yields ~0.046m steps — at least as fine as the player's
|
|
64
|
+
// own parcel_index + position_x/z combined precision (0.0625m), so no separate
|
|
65
|
+
// parcel index is needed for point-at.
|
|
66
|
+
//
|
|
67
|
+
// Y uses 7 bits over the player altitude range (matches position_y), step ~1.6m.
|
|
68
|
+
// Point At is not supposed to change frequently so the wire overhead should be minimal
|
|
69
|
+
optional uint32 point_at_x = 20 [(decentraland.common.quantized) = { min: -3000.0, max: 3000.0, bits: 17 }];
|
|
70
|
+
optional uint32 point_at_y = 21 [(decentraland.common.quantized) = { min: 0.0, max: 200.0, bits: 7 }];
|
|
71
|
+
optional uint32 point_at_z = 22 [(decentraland.common.quantized) = { min: -3000.0, max: 3000.0, bits: 17 }];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Full State is sent to the client when it is out of sync, and can't recover with a diff only
|
|
75
|
+
message PlayerStateFull {
|
|
76
|
+
uint32 subject_id = 1;
|
|
77
|
+
uint32 sequence = 2;
|
|
78
|
+
uint32 server_tick = 3;
|
|
79
|
+
PlayerState state = 4;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Notification to the client, that a peer has joined, it can mean connection or entering the area of interest, it's up to the server to decide
|
|
83
|
+
message PlayerJoined {
|
|
84
|
+
string user_id = 1;
|
|
85
|
+
int32 profile_version = 2;
|
|
86
|
+
PlayerStateFull state = 3;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Notification to the client, that a peer has left, it can mean disconnection or leaving the area of interest
|
|
90
|
+
message PlayerLeft {
|
|
91
|
+
uint32 subject_id = 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
enum EmoteStopReason {
|
|
95
|
+
COMPLETED = 0; // one-shot timer expired on the server
|
|
96
|
+
CANCELLED = 1; // client sent EmoteStop (looping emotes)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Server → All Observers
|
|
100
|
+
// Full player state is piggybacked to ensure the emote is played in the right place.
|
|
101
|
+
// Observers use server_tick to scrub animation forward by transit latency.
|
|
102
|
+
message EmoteStarted {
|
|
103
|
+
uint32 subject_id = 1;
|
|
104
|
+
uint32 sequence = 2;
|
|
105
|
+
uint32 server_tick = 3;
|
|
106
|
+
string emote_id = 4;
|
|
107
|
+
PlayerState player_state = 5;
|
|
108
|
+
optional int32 mask = 6;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Server → All Observers
|
|
112
|
+
// Client resumes MovementInput only after receiving this.
|
|
113
|
+
// Carries full PlayerState so the client can snap to the correct position on resume.
|
|
114
|
+
message EmoteStopped {
|
|
115
|
+
uint32 subject_id = 1;
|
|
116
|
+
uint32 server_tick = 2;
|
|
117
|
+
EmoteStopReason reason = 3;
|
|
118
|
+
uint32 sequence = 4;
|
|
119
|
+
PlayerState player_state = 5;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Server → All Observers
|
|
123
|
+
message TeleportPerformed {
|
|
124
|
+
uint32 subject_id = 1;
|
|
125
|
+
uint32 sequence = 2;
|
|
126
|
+
uint32 server_tick = 3;
|
|
127
|
+
PlayerState state = 4;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
message ServerMessage {
|
|
131
|
+
oneof message {
|
|
132
|
+
HandshakeResponse handshake = 1;
|
|
133
|
+
PlayerStateFull player_state_full = 2;
|
|
134
|
+
PlayerStateDeltaTier0 player_state_delta = 3;
|
|
135
|
+
PlayerJoined player_joined = 4;
|
|
136
|
+
PlayerLeft player_left = 5;
|
|
137
|
+
PlayerProfileVersionsAnnounced player_profile_version_announced = 6;
|
|
138
|
+
EmoteStarted emote_started = 7;
|
|
139
|
+
EmoteStopped emote_stopped = 8;
|
|
140
|
+
TeleportPerformed teleported = 9;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package decentraland.pulse;
|
|
4
|
+
|
|
5
|
+
import "decentraland/common/options.proto";
|
|
6
|
+
|
|
7
|
+
enum PlayerAnimationFlags {
|
|
8
|
+
NONE = 0;
|
|
9
|
+
GROUNDED = 1;
|
|
10
|
+
LONG_JUMP = 2;
|
|
11
|
+
LONG_FALL = 4;
|
|
12
|
+
FALLING = 8;
|
|
13
|
+
STUNNED = 16;
|
|
14
|
+
HEAD_YAW = 32;
|
|
15
|
+
HEAD_PITCH = 64;
|
|
16
|
+
POINTING_AT = 128;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
enum GlideState {
|
|
20
|
+
PROP_CLOSED = 0;
|
|
21
|
+
OPENING_PROP = 1;
|
|
22
|
+
GLIDING = 2;
|
|
23
|
+
CLOSING_PROP = 3;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Quantized identically to PlayerStateDeltaTier0 so a full state and a stream of deltas land on the same grid.
|
|
27
|
+
message PlayerState {
|
|
28
|
+
int32 parcel_index = 1;
|
|
29
|
+
|
|
30
|
+
// Position inside the parcel (X/Z) and world altitude (Y).
|
|
31
|
+
uint32 position_x = 2 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
32
|
+
uint32 position_y = 3 [(decentraland.common.quantized) = { min: 0, max: 200, bits: 13 }];
|
|
33
|
+
uint32 position_z = 4 [(decentraland.common.quantized) = { min: 0, max: 16, bits: 8 }];
|
|
34
|
+
|
|
35
|
+
uint32 velocity_x = 5 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
36
|
+
uint32 velocity_y = 6 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
37
|
+
uint32 velocity_z = 7 [(decentraland.common.quantized_power) = { max: 50, pow: 2, bits: 8 }];
|
|
38
|
+
|
|
39
|
+
uint32 rotation_y = 8 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
40
|
+
|
|
41
|
+
uint32 movement_blend = 9 [(decentraland.common.quantized) = { min: 0, max: 3, bits: 5 }];
|
|
42
|
+
uint32 slide_blend = 10 [(decentraland.common.quantized) = { min: 0, max: 1, bits: 4 }];
|
|
43
|
+
|
|
44
|
+
optional uint32 head_yaw = 11 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
45
|
+
optional uint32 head_pitch = 12 [(decentraland.common.quantized) = { min: 0, max: 360.0, bits: 7 }];
|
|
46
|
+
|
|
47
|
+
uint32 state_flags = 13;
|
|
48
|
+
GlideState glide_state = 14;
|
|
49
|
+
|
|
50
|
+
int32 jump_count = 15;
|
|
51
|
+
|
|
52
|
+
// Absolute world hit position the player is pointing at.
|
|
53
|
+
// Only meaningful when POINTING_AT is set in `state_flags`.
|
|
54
|
+
optional uint32 point_at_x = 16 [(decentraland.common.quantized) = { min: -3000.0, max: 3000.0, bits: 17 }];
|
|
55
|
+
optional uint32 point_at_y = 17 [(decentraland.common.quantized) = { min: 0.0, max: 200.0, bits: 7 }];
|
|
56
|
+
optional uint32 point_at_z = 18 [(decentraland.common.quantized) = { min: -3000.0, max: 3000.0, bits: 17 }];
|
|
57
|
+
}
|
|
@@ -25,4 +25,4 @@ message PBLightSource {
|
|
|
25
25
|
optional float inner_angle = 9; // default = 21.8. Inner angle can't be higher than outer angle, otherwise will default to same value. Min value is 0. Max value is 179.
|
|
26
26
|
optional float outer_angle = 10; // default = 30. Outer angle can't be lower than inner angle, otherwise will inner angle will be set to same value. Max value is 179.
|
|
27
27
|
}
|
|
28
|
-
}
|
|
28
|
+
}
|
|
@@ -10,7 +10,9 @@ option (common.ecs_component_id) = 1076;
|
|
|
10
10
|
// an 'instant' transition (like using speed/time = 0)
|
|
11
11
|
// * The lookAtEntity defines to which entity the Camera has to look at constantly (independent from
|
|
12
12
|
// the holding entity transform).
|
|
13
|
+
// * The fov defines the Field of View of the virtual camera
|
|
13
14
|
message PBVirtualCamera {
|
|
14
15
|
optional common.CameraTransition default_transition = 1;
|
|
15
16
|
optional uint32 look_at_entity = 2;
|
|
17
|
+
optional float fov = 3; // default: 60
|
|
16
18
|
}
|