@ue-shed/protocol 0.1.0 → 0.3.0
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 +2 -1
- package/contracts/cameras/map-tile/v1/README.md +44 -0
- package/contracts/cameras/map-tile/v1/capture-request.schema.json +68 -0
- package/contracts/cameras/map-tile/v1/capture-response.schema.json +115 -0
- package/contracts/cameras/map-tile/v1/fixtures/capture-request-valid.json +32 -0
- package/contracts/cameras/map-tile/v1/fixtures/capture-response-valid.json +24 -0
- package/contracts/cameras/map-tile/v1/fixtures/manifest-invalid-complete.json +41 -0
- package/contracts/cameras/map-tile/v1/fixtures/manifest-invalid-grid.json +44 -0
- package/contracts/cameras/map-tile/v1/fixtures/manifest-valid.json +60 -0
- package/contracts/cameras/map-tile/v1/fixtures/plan-valid.json +27 -0
- package/contracts/cameras/map-tile/v1/manifest.schema.json +162 -0
- package/contracts/cameras/map-tile/v1/plan.schema.json +176 -0
- package/contracts/cameras/provisioning/v1/README.md +5 -3
- package/contracts/cameras/provisioning/v1/fixtures/provision-request-valid.json +11 -2
- package/contracts/cameras/provisioning/v1/provision-request.schema.json +131 -50
- package/contracts/cameras/v1/README.md +6 -3
- package/contracts/editor-world/v1/README.md +10 -0
- package/contracts/editor-world/v1/request.schema.json +16 -0
- package/contracts/editor-world/v1/response.schema.json +93 -0
- package/contracts/uasset-io/v1/event.schema.json +110 -60
- package/contracts/uasset-io/v1/fixtures/valid/saved-world-result-event.json +20 -4
- package/dist/authoring.d.ts +6 -1
- package/dist/authoring.d.ts.map +1 -1
- package/dist/companion.d.ts +14 -0
- package/dist/companion.d.ts.map +1 -1
- package/dist/companion.js +7 -0
- package/dist/companion.js.map +1 -1
- package/dist/editor-play-session.d.ts +4 -1
- package/dist/editor-play-session.d.ts.map +1 -1
- package/dist/editor-play-session.js.map +1 -1
- package/dist/editor-world-control.d.ts +179 -0
- package/dist/editor-world-control.d.ts.map +1 -0
- package/dist/editor-world-control.js +47 -0
- package/dist/editor-world-control.js.map +1 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/saved-world.d.ts +121 -40
- package/dist/saved-world.d.ts.map +1 -1
- package/dist/saved-world.js +35 -11
- package/dist/saved-world.js.map +1 -1
- package/dist/uasset-io.d.ts +90 -31
- package/dist/uasset-io.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ue-shed.dev/contracts/cameras/map-tile/v1/plan.schema.json",
|
|
4
|
+
"title": "UE Shed Map Capture Plan v1.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"capture",
|
|
9
|
+
"contract",
|
|
10
|
+
"gutterPixels",
|
|
11
|
+
"id",
|
|
12
|
+
"levels",
|
|
13
|
+
"output",
|
|
14
|
+
"project",
|
|
15
|
+
"requestedBounds",
|
|
16
|
+
"tilePixelSize"
|
|
17
|
+
],
|
|
18
|
+
"properties": {
|
|
19
|
+
"capture": { "$ref": "#/$defs/capturePolicy" },
|
|
20
|
+
"contract": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"required": ["name", "version"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"name": { "const": "ue-shed-map-capture-plan" },
|
|
26
|
+
"version": { "$ref": "#/$defs/version" }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"gutterPixels": { "type": "integer", "minimum": 0, "maximum": 32 },
|
|
30
|
+
"id": { "$ref": "#/$defs/id" },
|
|
31
|
+
"levels": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": ["coarsestUnitsPerPixel", "count"],
|
|
35
|
+
"properties": {
|
|
36
|
+
"coarsestUnitsPerPixel": { "type": "number", "exclusiveMinimum": 0 },
|
|
37
|
+
"count": { "type": "integer", "minimum": 1, "maximum": 24 }
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"output": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"additionalProperties": false,
|
|
43
|
+
"required": ["imageFormat", "publication"],
|
|
44
|
+
"properties": {
|
|
45
|
+
"imageFormat": { "const": "png" },
|
|
46
|
+
"publication": { "const": "local_immutable" }
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"project": { "$ref": "#/$defs/project" },
|
|
50
|
+
"requestedBounds": { "$ref": "#/$defs/bounds" },
|
|
51
|
+
"tilePixelSize": { "type": "integer", "minimum": 64, "maximum": 4096 }
|
|
52
|
+
},
|
|
53
|
+
"$defs": {
|
|
54
|
+
"id": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$" },
|
|
55
|
+
"version": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"additionalProperties": false,
|
|
58
|
+
"required": ["major", "minor"],
|
|
59
|
+
"properties": { "major": { "const": 1 }, "minor": { "const": 0 } }
|
|
60
|
+
},
|
|
61
|
+
"bounds": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"additionalProperties": false,
|
|
64
|
+
"required": ["minX", "minY", "maxX", "maxY"],
|
|
65
|
+
"properties": {
|
|
66
|
+
"minX": { "type": "number" },
|
|
67
|
+
"minY": { "type": "number" },
|
|
68
|
+
"maxX": { "type": "number" },
|
|
69
|
+
"maxY": { "type": "number" }
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"project": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"additionalProperties": false,
|
|
75
|
+
"required": ["id", "mapPath"],
|
|
76
|
+
"properties": {
|
|
77
|
+
"id": { "$ref": "#/$defs/id" },
|
|
78
|
+
"mapPath": { "type": "string", "pattern": "^/[A-Za-z0-9_./-]+$" }
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"dataLayers": {
|
|
82
|
+
"oneOf": [
|
|
83
|
+
{
|
|
84
|
+
"type": "object",
|
|
85
|
+
"additionalProperties": false,
|
|
86
|
+
"required": ["mode"],
|
|
87
|
+
"properties": { "mode": { "const": "unchanged" } }
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"type": "object",
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"required": ["mode", "states"],
|
|
93
|
+
"properties": {
|
|
94
|
+
"mode": { "const": "explicit" },
|
|
95
|
+
"states": {
|
|
96
|
+
"type": "array",
|
|
97
|
+
"maxItems": 64,
|
|
98
|
+
"items": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"additionalProperties": false,
|
|
101
|
+
"required": ["name", "state"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"name": { "type": "string", "minLength": 1, "maxLength": 1024 },
|
|
104
|
+
"state": { "enum": ["unloaded", "loaded", "activated"] }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"capturePolicy": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"additionalProperties": false,
|
|
115
|
+
"required": ["dataLayers", "orientation", "render", "z"],
|
|
116
|
+
"properties": {
|
|
117
|
+
"dataLayers": { "$ref": "#/$defs/dataLayers" },
|
|
118
|
+
"orientation": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"required": ["pitch", "roll", "yaw"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"pitch": { "const": -90 },
|
|
124
|
+
"roll": { "const": 0 },
|
|
125
|
+
"yaw": { "const": 0 }
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"render": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"required": ["effects", "lodPolicy", "profile"],
|
|
132
|
+
"properties": {
|
|
133
|
+
"effects": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"additionalProperties": false,
|
|
136
|
+
"required": ["fog", "volumetricFog"],
|
|
137
|
+
"properties": {
|
|
138
|
+
"fog": { "type": "boolean" },
|
|
139
|
+
"volumetricFog": { "type": "boolean" }
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"lodDistanceScaleByZoom": {
|
|
143
|
+
"type": "array",
|
|
144
|
+
"minItems": 1,
|
|
145
|
+
"maxItems": 24,
|
|
146
|
+
"items": { "type": "number", "minimum": 0.1, "maximum": 100 }
|
|
147
|
+
},
|
|
148
|
+
"lodPolicy": {
|
|
149
|
+
"enum": ["natural", "fixed_lod_zero", "per_level_distance_scale"]
|
|
150
|
+
},
|
|
151
|
+
"profile": {
|
|
152
|
+
"enum": [
|
|
153
|
+
"full_fidelity",
|
|
154
|
+
"seam_stable",
|
|
155
|
+
"scene_capture_defaults",
|
|
156
|
+
"observation"
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"allOf": [
|
|
161
|
+
{
|
|
162
|
+
"if": {
|
|
163
|
+
"properties": {
|
|
164
|
+
"lodPolicy": { "const": "per_level_distance_scale" }
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"then": { "required": ["lodDistanceScaleByZoom"] },
|
|
168
|
+
"else": { "not": { "required": ["lodDistanceScaleByZoom"] } }
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"z": { "type": "number" }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
camera is a transient runtime realization, identified by a generated `ProvisionedCameraId`; it is
|
|
5
5
|
never a durable Map Review camera record.
|
|
6
6
|
|
|
7
|
-
Each request carries an explicit correlation to
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Each request carries an expected map and an explicit correlation to a framing candidate, a durable
|
|
8
|
+
Review View, or a Map Capture Plan. A camera selects either perspective field of view or
|
|
9
|
+
orthographic width through a discriminated projection. The compatibility decoder accepts the
|
|
10
|
+
candidate-only and `schemaVersion: 2` perspective request shapes for already-installed clients, but
|
|
11
|
+
new clients emit only `schemaVersion: 3`.
|
|
10
12
|
|
|
11
13
|
The editor returns the same correlation for every provisioned camera. Array index remains a live
|
|
12
14
|
frame transport position, never durable identity.
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 3,
|
|
3
|
+
"expectedMapPath": "/Game/Fixture/Cameras/L_CameraLoad",
|
|
3
4
|
"previewFps": 5,
|
|
4
5
|
"cameras": [
|
|
5
6
|
{
|
|
6
7
|
"correlation": { "type": "framing_candidate", "candidateId": "context_three_quarter" },
|
|
7
|
-
"fieldOfViewDegrees": 60,
|
|
8
|
+
"projection": { "type": "perspective", "fieldOfViewDegrees": 60 },
|
|
8
9
|
"location": { "x": 1200, "y": -1400, "z": 700 },
|
|
9
10
|
"rotation": { "pitch": -12, "yaw": 135, "roll": 0 },
|
|
10
11
|
"width": 320,
|
|
11
12
|
"height": 180
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"correlation": { "type": "map_capture_plan", "mapCapturePlanId": "fixture-overview" },
|
|
16
|
+
"projection": { "type": "orthographic", "orthoWidth": 4096 },
|
|
17
|
+
"location": { "x": 0, "y": 0, "z": 5000 },
|
|
18
|
+
"rotation": { "pitch": -90, "yaw": 0, "roll": 0 },
|
|
19
|
+
"width": 640,
|
|
20
|
+
"height": 360
|
|
12
21
|
}
|
|
13
22
|
]
|
|
14
23
|
}
|
|
@@ -4,68 +4,149 @@
|
|
|
4
4
|
"title": "UE Shed provisioned camera request v1",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"additionalProperties": false,
|
|
7
|
-
"required": ["schemaVersion", "previewFps", "cameras"],
|
|
7
|
+
"required": ["schemaVersion", "expectedMapPath", "previewFps", "cameras"],
|
|
8
8
|
"properties": {
|
|
9
|
-
"schemaVersion": { "const":
|
|
9
|
+
"schemaVersion": { "const": 3 },
|
|
10
|
+
"expectedMapPath": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"maxLength": 1024,
|
|
14
|
+
"pattern": "^/[A-Za-z0-9_./-]+$"
|
|
15
|
+
},
|
|
10
16
|
"previewFps": { "type": "integer", "minimum": 1, "maximum": 10 },
|
|
11
17
|
"cameras": {
|
|
12
18
|
"type": "array",
|
|
13
19
|
"minItems": 1,
|
|
14
20
|
"maxItems": 32,
|
|
15
21
|
"items": {
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"correlation",
|
|
20
|
-
"fieldOfViewDegrees",
|
|
21
|
-
"location",
|
|
22
|
-
"rotation",
|
|
23
|
-
"width",
|
|
24
|
-
"height"
|
|
25
|
-
],
|
|
26
|
-
"properties": {
|
|
27
|
-
"correlation": {
|
|
28
|
-
"oneOf": [
|
|
29
|
-
{
|
|
30
|
-
"type": "object",
|
|
31
|
-
"additionalProperties": false,
|
|
32
|
-
"required": ["type", "candidateId"],
|
|
33
|
-
"properties": {
|
|
34
|
-
"type": { "const": "framing_candidate" },
|
|
35
|
-
"candidateId": {
|
|
36
|
-
"type": "string",
|
|
37
|
-
"minLength": 1,
|
|
38
|
-
"maxLength": 128,
|
|
39
|
-
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"type": "object",
|
|
45
|
-
"additionalProperties": false,
|
|
46
|
-
"required": ["type", "reviewViewId"],
|
|
47
|
-
"properties": {
|
|
48
|
-
"type": { "const": "review_view" },
|
|
49
|
-
"reviewViewId": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"minLength": 1,
|
|
52
|
-
"maxLength": 128,
|
|
53
|
-
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
]
|
|
22
|
+
"oneOf": [
|
|
23
|
+
{
|
|
24
|
+
"$ref": "#/$defs/perspectiveCamera"
|
|
58
25
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"height": { "type": "integer", "minimum": 64, "maximum": 1440 }
|
|
64
|
-
}
|
|
26
|
+
{
|
|
27
|
+
"$ref": "#/$defs/orthographicCamera"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
65
30
|
}
|
|
66
31
|
}
|
|
67
32
|
},
|
|
68
33
|
"$defs": {
|
|
34
|
+
"cameraFields": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"required": ["correlation", "projection", "location", "rotation", "width", "height"],
|
|
37
|
+
"properties": {
|
|
38
|
+
"correlation": { "$ref": "#/$defs/correlation" },
|
|
39
|
+
"location": { "$ref": "#/$defs/vector" },
|
|
40
|
+
"rotation": { "$ref": "#/$defs/rotation" },
|
|
41
|
+
"width": { "type": "integer", "minimum": 64, "maximum": 2560 },
|
|
42
|
+
"height": { "type": "integer", "minimum": 64, "maximum": 1440 }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"perspectiveCamera": {
|
|
46
|
+
"allOf": [
|
|
47
|
+
{ "$ref": "#/$defs/cameraFields" },
|
|
48
|
+
{
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"required": [
|
|
52
|
+
"correlation",
|
|
53
|
+
"projection",
|
|
54
|
+
"location",
|
|
55
|
+
"rotation",
|
|
56
|
+
"width",
|
|
57
|
+
"height"
|
|
58
|
+
],
|
|
59
|
+
"properties": {
|
|
60
|
+
"correlation": { "$ref": "#/$defs/correlation" },
|
|
61
|
+
"projection": { "$ref": "#/$defs/perspectiveProjection" },
|
|
62
|
+
"location": { "$ref": "#/$defs/vector" },
|
|
63
|
+
"rotation": { "$ref": "#/$defs/rotation" },
|
|
64
|
+
"width": { "type": "integer", "minimum": 64, "maximum": 2560 },
|
|
65
|
+
"height": { "type": "integer", "minimum": 64, "maximum": 1440 }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"orthographicCamera": {
|
|
71
|
+
"allOf": [
|
|
72
|
+
{ "$ref": "#/$defs/cameraFields" },
|
|
73
|
+
{
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"required": [
|
|
77
|
+
"correlation",
|
|
78
|
+
"projection",
|
|
79
|
+
"location",
|
|
80
|
+
"rotation",
|
|
81
|
+
"width",
|
|
82
|
+
"height"
|
|
83
|
+
],
|
|
84
|
+
"properties": {
|
|
85
|
+
"correlation": { "$ref": "#/$defs/correlation" },
|
|
86
|
+
"projection": { "$ref": "#/$defs/orthographicProjection" },
|
|
87
|
+
"location": { "$ref": "#/$defs/vector" },
|
|
88
|
+
"rotation": { "$ref": "#/$defs/rotation" },
|
|
89
|
+
"width": { "type": "integer", "minimum": 64, "maximum": 2560 },
|
|
90
|
+
"height": { "type": "integer", "minimum": 64, "maximum": 1440 }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"perspectiveProjection": {
|
|
96
|
+
"type": "object",
|
|
97
|
+
"additionalProperties": false,
|
|
98
|
+
"required": ["type", "fieldOfViewDegrees"],
|
|
99
|
+
"properties": {
|
|
100
|
+
"type": { "const": "perspective" },
|
|
101
|
+
"fieldOfViewDegrees": { "type": "number", "minimum": 5, "maximum": 170 }
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"orthographicProjection": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": false,
|
|
107
|
+
"required": ["type", "orthoWidth"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"type": { "const": "orthographic" },
|
|
110
|
+
"orthoWidth": { "type": "number", "exclusiveMinimum": 0 }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"correlation": {
|
|
114
|
+
"oneOf": [
|
|
115
|
+
{
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": false,
|
|
118
|
+
"required": ["type", "candidateId"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"type": { "const": "framing_candidate" },
|
|
121
|
+
"candidateId": { "$ref": "#/$defs/identifier" }
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"type": "object",
|
|
126
|
+
"additionalProperties": false,
|
|
127
|
+
"required": ["type", "reviewViewId"],
|
|
128
|
+
"properties": {
|
|
129
|
+
"type": { "const": "review_view" },
|
|
130
|
+
"reviewViewId": { "$ref": "#/$defs/identifier" }
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"type": "object",
|
|
135
|
+
"additionalProperties": false,
|
|
136
|
+
"required": ["type", "mapCapturePlanId"],
|
|
137
|
+
"properties": {
|
|
138
|
+
"type": { "const": "map_capture_plan" },
|
|
139
|
+
"mapCapturePlanId": { "$ref": "#/$defs/identifier" }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"identifier": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"minLength": 1,
|
|
147
|
+
"maxLength": 128,
|
|
148
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
|
149
|
+
},
|
|
69
150
|
"vector": {
|
|
70
151
|
"type": "object",
|
|
71
152
|
"additionalProperties": false,
|
|
@@ -20,9 +20,9 @@ frames from an old session are disposable.
|
|
|
20
20
|
| 40 | f64 | Unreal world seconds at capture request |
|
|
21
21
|
| 48 | f64 | producer monotonic milliseconds at capture request |
|
|
22
22
|
| 56 | f64 | GPU readback latency in milliseconds |
|
|
23
|
-
| 64 |
|
|
24
|
-
| 80 |
|
|
25
|
-
| 96 |
|
|
23
|
+
| 64 | u32[4] | producer FGuid words, each little-endian |
|
|
24
|
+
| 80 | u32[4] | session FGuid words, each little-endian |
|
|
25
|
+
| 96 | u32[4] | camera FGuid words, each little-endian |
|
|
26
26
|
| 112 | u32 | cumulative readback/staging drops |
|
|
27
27
|
| 116 | u32 | cumulative latest-frame transport replacements |
|
|
28
28
|
| 120 | u32 | reserved, zero |
|
|
@@ -31,3 +31,6 @@ frames from an old session are disposable.
|
|
|
31
31
|
The payload is top-to-bottom, tightly packed BGRA8. Live buffers are bounded and latest-frame-wins;
|
|
32
32
|
sequence gaps are expected and observable. The control plane owns camera listing, schedule tuning,
|
|
33
33
|
pause/focus, and health. This binary stream never carries durable evidence.
|
|
34
|
+
|
|
35
|
+
To compare an ID with Unreal's `FGuid::ToString(EGuidFormats::Digits)` output, read the four
|
|
36
|
+
little-endian `u32` words and concatenate them as four zero-padded, eight-digit hexadecimal values.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Unreal editor world-control contract v1
|
|
2
|
+
|
|
3
|
+
This contract lets a trusted external client open one explicit `/Game/` map in Unreal Editor
|
|
4
|
+
without player input. The operation never saves, discards, or prompts over dirty work. It returns
|
|
5
|
+
`already_open` when the target is current and otherwise rejects active play sessions, dirty world
|
|
6
|
+
packages, missing maps, and failed loads as typed outcomes.
|
|
7
|
+
|
|
8
|
+
`request.schema.json` and `response.schema.json` are the language-neutral authority shared by
|
|
9
|
+
`@ue-shed/protocol` and `UEShedCoreEditor`. The companion advertises
|
|
10
|
+
`editor.world-control.v1` and its reflected object path before clients may invoke the operation.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ue-shed.dev/contracts/editor-world/v1/request.schema.json",
|
|
4
|
+
"title": "UE Shed editor world open request v1.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["contract", "operationId", "targetMapPath"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"contract": { "$ref": "response.schema.json#/$defs/contract" },
|
|
10
|
+
"operationId": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
|
13
|
+
},
|
|
14
|
+
"targetMapPath": { "$ref": "response.schema.json#/$defs/gameMapPath" }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ue-shed.dev/contracts/editor-world/v1/response.schema.json",
|
|
4
|
+
"title": "UE Shed editor world open response v1.0",
|
|
5
|
+
"oneOf": [
|
|
6
|
+
{
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": ["after", "before", "contract", "operationId", "outcome", "targetMapPath"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"after": { "$ref": "#/$defs/snapshot" },
|
|
12
|
+
"before": { "$ref": "#/$defs/snapshot" },
|
|
13
|
+
"contract": { "$ref": "#/$defs/contract" },
|
|
14
|
+
"operationId": { "$ref": "#/$defs/operationId" },
|
|
15
|
+
"outcome": { "enum": ["opened", "already_open"] },
|
|
16
|
+
"targetMapPath": { "$ref": "#/$defs/gameMapPath" }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"required": [
|
|
23
|
+
"after",
|
|
24
|
+
"before",
|
|
25
|
+
"code",
|
|
26
|
+
"contract",
|
|
27
|
+
"message",
|
|
28
|
+
"operationId",
|
|
29
|
+
"outcome",
|
|
30
|
+
"recovery",
|
|
31
|
+
"retrySafe",
|
|
32
|
+
"targetMapPath"
|
|
33
|
+
],
|
|
34
|
+
"properties": {
|
|
35
|
+
"after": { "$ref": "#/$defs/snapshot" },
|
|
36
|
+
"before": { "$ref": "#/$defs/snapshot" },
|
|
37
|
+
"code": {
|
|
38
|
+
"enum": [
|
|
39
|
+
"dirty_world",
|
|
40
|
+
"invalid_request",
|
|
41
|
+
"map_not_found",
|
|
42
|
+
"open_failed",
|
|
43
|
+
"play_session_active",
|
|
44
|
+
"unavailable"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"contract": { "$ref": "#/$defs/contract" },
|
|
48
|
+
"message": { "type": "string" },
|
|
49
|
+
"operationId": { "$ref": "#/$defs/operationId" },
|
|
50
|
+
"outcome": { "const": "rejected" },
|
|
51
|
+
"recovery": { "type": "string" },
|
|
52
|
+
"retrySafe": { "type": "boolean" },
|
|
53
|
+
"targetMapPath": { "$ref": "#/$defs/gameMapPath" }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"$defs": {
|
|
58
|
+
"contract": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"required": ["name", "version"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"name": { "const": "unreal-editor-world-control" },
|
|
64
|
+
"version": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"additionalProperties": false,
|
|
67
|
+
"required": ["major", "minor"],
|
|
68
|
+
"properties": { "major": { "const": 1 }, "minor": { "const": 0 } }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"mapPath": { "type": "string", "pattern": "^/[A-Za-z0-9_./-]+$" },
|
|
73
|
+
"gameMapPath": { "type": "string", "pattern": "^/Game/[A-Za-z0-9_./-]+$" },
|
|
74
|
+
"operationId": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
|
77
|
+
},
|
|
78
|
+
"snapshot": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"required": ["dirtyWorldPackages", "playSessionActive"],
|
|
82
|
+
"properties": {
|
|
83
|
+
"dirtyWorldPackages": {
|
|
84
|
+
"type": "array",
|
|
85
|
+
"maxItems": 256,
|
|
86
|
+
"items": { "$ref": "#/$defs/mapPath" }
|
|
87
|
+
},
|
|
88
|
+
"mapPath": { "$ref": "#/$defs/mapPath" },
|
|
89
|
+
"playSessionActive": { "type": "boolean" }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|