@threenative/core 0.3.0 → 0.3.1
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 +10 -0
- package/capabilities.json +1881 -131
- package/dist/assets-kyoF7JlJ.d.ts +103 -0
- package/dist/{audio-Dp2mXpD3.d.ts → audio-BFiGneTL.d.ts} +62 -0
- package/dist/canvas-layer-BLVijiUJ.d.ts +62 -0
- package/dist/{game-CYIaKhgl.d.ts → game-XGrTzapq.d.ts} +350 -164
- package/dist/gpu-readback-D2iRvoe9.d.ts +112 -0
- package/dist/hot.d.ts +5 -3
- package/dist/hot.js +5 -1
- package/dist/index.d.ts +813 -143
- package/dist/index.js +4548 -941
- package/dist/net.d.ts +65 -0
- package/dist/net.js +643 -0
- package/dist/playtest.d.ts +29 -5
- package/dist/playtest.js +181 -35
- package/dist/react.d.ts +4 -2
- package/dist/{canvas-layer-CtrZHgIh.d.ts → renderer-C6hqZpoG.d.ts} +237 -75
- package/dist/world.d.ts +203 -4
- package/dist/world.js +2536 -25
- package/gpl/LICENSE.GPL +117 -0
- package/gpl/convert.py +192 -0
- package/gpl/recipes/_common.py +169 -0
- package/gpl/recipes/bake_ao.py +111 -0
- package/gpl/recipes/decimate.py +64 -0
- package/gpl/recipes/retarget.py +131 -0
- package/gpl/recipes/unwrap.py +71 -0
- package/mcp/blender-server.mjs +632 -0
- package/mcp/blender.mjs +27 -0
- package/mcp/engine-server.mjs +271 -23
- package/mcp/engine.mjs +15 -7
- package/mcp/install.d.mts +37 -0
- package/mcp/install.mjs +94 -26
- package/mcp/servers.d.mts +34 -0
- package/mcp/servers.mjs +110 -9
- package/package.json +36 -8
- package/patches/three@0.185.1.patch +249 -14
- package/scripts/ensure-mcp.mjs +20 -13
- package/scripts/bundle-engine-mcp.mjs +0 -15
- package/scripts/generate-version.mjs +0 -13
package/dist/playtest.js
CHANGED
|
@@ -8,14 +8,24 @@ function audioRuntimeSnapshot() {
|
|
|
8
8
|
let queued = 0;
|
|
9
9
|
let voices = 0;
|
|
10
10
|
let pooled = 0;
|
|
11
|
+
let paused = 0;
|
|
12
|
+
const unsupported = /* @__PURE__ */ new Set();
|
|
11
13
|
for (const bus of buses) {
|
|
12
14
|
queued += bus.queued;
|
|
13
15
|
voices += bus.voices;
|
|
14
16
|
pooled += bus.pooled;
|
|
17
|
+
paused += bus.pausedVoices;
|
|
18
|
+
for (const option of bus.unsupported) unsupported.add(option);
|
|
15
19
|
}
|
|
16
|
-
return { pooled, queued, voices };
|
|
20
|
+
return { paused, pooled, queued, unsupported: [...unsupported].sort(), voices };
|
|
17
21
|
}
|
|
18
22
|
|
|
23
|
+
// src/version.ts
|
|
24
|
+
var CORE_VERSION = "0.3.1";
|
|
25
|
+
|
|
26
|
+
// src/pipeline-census.ts
|
|
27
|
+
var PIPELINE_CENSUS_CAPABILITY = "runtime.pipelineCensus";
|
|
28
|
+
|
|
19
29
|
// src/render/chain.ts
|
|
20
30
|
var REPORT_KEY = /* @__PURE__ */ Symbol.for("threenative.renderChain.report");
|
|
21
31
|
function storedReport(target) {
|
|
@@ -36,17 +46,29 @@ function isObject(value) {
|
|
|
36
46
|
return typeof value === "object" && value !== null;
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
// src/version.ts
|
|
40
|
-
var CORE_VERSION = "0.3.0";
|
|
41
|
-
|
|
42
49
|
// src/playtest.ts
|
|
43
50
|
var currentAgent = typeof navigator === "undefined" ? "node" : navigator.userAgent;
|
|
44
51
|
function playtest(options = {}) {
|
|
45
52
|
let dispose;
|
|
46
53
|
let attached;
|
|
54
|
+
let startSceneEntered;
|
|
55
|
+
let disposePipelineCensus;
|
|
47
56
|
let contactHistory = [];
|
|
57
|
+
const watcher = createTransitionWatcher();
|
|
58
|
+
let readTick;
|
|
48
59
|
return {
|
|
60
|
+
sceneExit: () => {
|
|
61
|
+
contactHistory = [];
|
|
62
|
+
watcher.reset();
|
|
63
|
+
},
|
|
64
|
+
update: (ctx) => {
|
|
65
|
+
const tick = readTick?.();
|
|
66
|
+
if (tick === void 0) return;
|
|
67
|
+
drainContacts(ctx, contactHistory, tick);
|
|
68
|
+
watcher.observe(ctx, tick);
|
|
69
|
+
},
|
|
49
70
|
setup: async (ctx, runtime) => {
|
|
71
|
+
readTick = runtime?.tick;
|
|
50
72
|
const seed = runtime?.seed ?? null;
|
|
51
73
|
const replayRuntime = runtime?.seed === null || runtime?.seed === void 0 ? void 0 : {
|
|
52
74
|
agent: currentAgent,
|
|
@@ -62,13 +84,16 @@ function playtest(options = {}) {
|
|
|
62
84
|
...runtime === void 0 ? {} : { fixedStep: runtime.fixedStep, tick: runtime.tick },
|
|
63
85
|
...runtime?.runtimeDiagnosticsSeries === void 0 ? {} : { runtimeDiagnosticsSeries: runtime.runtimeDiagnosticsSeries },
|
|
64
86
|
...options.events === void 0 ? {} : { events: options.events },
|
|
65
|
-
gameplay: () => gameplayObservations(ctx, contactHistory, seed, replayRuntime),
|
|
87
|
+
gameplay: () => gameplayObservations(ctx, contactHistory, seed, replayRuntime, watcher),
|
|
66
88
|
gameplayChannels: () => gameplayChannels(),
|
|
67
89
|
renderer: ctx.renderer.raw,
|
|
68
90
|
renderChain: () => {
|
|
69
91
|
const observation = readRenderChainObservation(ctx.renderer);
|
|
70
92
|
return observation === void 0 ? void 0 : {
|
|
71
93
|
...observation,
|
|
94
|
+
contributions: observation.contributions.map((contribution) => ({
|
|
95
|
+
...contribution
|
|
96
|
+
})),
|
|
72
97
|
dropped: observation.dropped.map((stage) => ({ ...stage })),
|
|
73
98
|
requested: [...observation.requested],
|
|
74
99
|
stages: [...observation.stages],
|
|
@@ -83,19 +108,35 @@ function playtest(options = {}) {
|
|
|
83
108
|
startup: () => ({
|
|
84
109
|
phase: ctx.startup.phase,
|
|
85
110
|
progress: ctx.startup.progress,
|
|
86
|
-
...
|
|
111
|
+
...ctx.startup.warmup === void 0 ? {} : { warmup: ctx.startup.warmup },
|
|
112
|
+
...runtime?.startupCompileSettled === void 0 ? {} : { compileSettled: runtime.startupCompileSettled() },
|
|
113
|
+
// Wall-clock milestones, so a scenario asserts startup time as an observation instead
|
|
114
|
+
// of reading it off a console marker after the fact.
|
|
115
|
+
...runtime?.startupTimeline === void 0 ? {} : { timeline: runtime.startupTimeline() }
|
|
87
116
|
})
|
|
88
117
|
});
|
|
118
|
+
const pipelineCensus = runtime?.pipelineCensus;
|
|
119
|
+
if (runtime !== void 0 && pipelineCensus !== void 0) {
|
|
120
|
+
disposePipelineCensus = runtime.observations.contribute({
|
|
121
|
+
capabilities: [PIPELINE_CENSUS_CAPABILITY],
|
|
122
|
+
sample: () => ({ pipelineCensus: pipelineCensus() })
|
|
123
|
+
});
|
|
124
|
+
}
|
|
89
125
|
installRuntimeChannels(installation.bridge, runtime);
|
|
90
126
|
if (globalThis[PLAYTEST_RUNNER_EXPECTED_GLOBAL] === true)
|
|
91
127
|
runtime?.enableRuntimeDiagnostics?.();
|
|
92
128
|
dispose = installation.dispose;
|
|
93
|
-
attached = holdUntilAttached(installation.bridge, options);
|
|
129
|
+
attached = holdUntilAttached(installation.bridge, options, () => startSceneEntered);
|
|
94
130
|
const cleanup = () => {
|
|
131
|
+
disposePipelineCensus?.();
|
|
132
|
+
disposePipelineCensus = void 0;
|
|
95
133
|
dispose?.();
|
|
96
134
|
dispose = void 0;
|
|
97
135
|
attached = void 0;
|
|
136
|
+
startSceneEntered = void 0;
|
|
98
137
|
contactHistory = [];
|
|
138
|
+
readTick = void 0;
|
|
139
|
+
watcher.reset();
|
|
99
140
|
};
|
|
100
141
|
if (attached !== void 0) {
|
|
101
142
|
const gate = attached.catch((error) => {
|
|
@@ -103,7 +144,10 @@ function playtest(options = {}) {
|
|
|
103
144
|
throw error;
|
|
104
145
|
});
|
|
105
146
|
if (runtime?.holdStart === void 0) await gate;
|
|
106
|
-
else
|
|
147
|
+
else {
|
|
148
|
+
startSceneEntered = runtime.holdStart(gate);
|
|
149
|
+
void startSceneEntered.catch(() => void 0);
|
|
150
|
+
}
|
|
107
151
|
}
|
|
108
152
|
return cleanup;
|
|
109
153
|
}
|
|
@@ -113,27 +157,54 @@ var PLAYTEST_ATTACH_TIMEOUT_MS = 3e4;
|
|
|
113
157
|
var PLAYTEST_RUNNER_EXPECTED_GLOBAL = "__THREENATIVE_PLAYTEST_RUNNER_EXPECTED__";
|
|
114
158
|
function shouldHoldUntilAttached(options) {
|
|
115
159
|
if (options.holdUntilAttached !== void 0) return options.holdUntilAttached;
|
|
116
|
-
|
|
160
|
+
const host = globalThis;
|
|
161
|
+
return host[PLAYTEST_RUNNER_EXPECTED_GLOBAL] === true || host.TN_PLAYTEST_ENDPOINT !== void 0;
|
|
117
162
|
}
|
|
118
|
-
function holdUntilAttached(bridge, options) {
|
|
163
|
+
function holdUntilAttached(bridge, options, startSceneEntered) {
|
|
119
164
|
if (!shouldHoldUntilAttached(options)) return void 0;
|
|
120
165
|
const timeoutMs = options.attachTimeoutMs ?? PLAYTEST_ATTACH_TIMEOUT_MS;
|
|
121
166
|
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
122
167
|
throw new Error(`TN_PLAYTEST_ATTACH_TIMEOUT_INVALID: ${String(options.attachTimeoutMs)}`);
|
|
123
168
|
}
|
|
124
169
|
const describe = bridge.describe;
|
|
170
|
+
const applySetup = bridge.applySetup;
|
|
125
171
|
return new Promise((resolve, reject) => {
|
|
172
|
+
let settled = false;
|
|
126
173
|
const timer = setTimeout(() => {
|
|
174
|
+
settled = true;
|
|
127
175
|
reject(
|
|
128
176
|
new Error(
|
|
129
|
-
`TN_PLAYTEST_ATTACH_TIMEOUT: no playtest runner called describe() within ${timeoutMs}ms.`
|
|
177
|
+
`TN_PLAYTEST_ATTACH_TIMEOUT: no playtest runner applied setup or called describe() within ${timeoutMs}ms.`
|
|
130
178
|
)
|
|
131
179
|
);
|
|
132
180
|
}, timeoutMs);
|
|
133
181
|
timer.unref?.();
|
|
134
|
-
|
|
182
|
+
const release = () => {
|
|
183
|
+
if (settled) return;
|
|
184
|
+
settled = true;
|
|
135
185
|
clearTimeout(timer);
|
|
136
186
|
resolve();
|
|
187
|
+
};
|
|
188
|
+
const fail = (error) => {
|
|
189
|
+
if (settled) return;
|
|
190
|
+
settled = true;
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
reject(error);
|
|
193
|
+
};
|
|
194
|
+
if (applySetup !== void 0) {
|
|
195
|
+
bridge.applySetup = async (request) => {
|
|
196
|
+
try {
|
|
197
|
+
await applySetup(request);
|
|
198
|
+
release();
|
|
199
|
+
} catch (error) {
|
|
200
|
+
fail(error);
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
bridge.describe = async () => {
|
|
206
|
+
release();
|
|
207
|
+
await startSceneEntered();
|
|
137
208
|
return describe();
|
|
138
209
|
};
|
|
139
210
|
});
|
|
@@ -198,7 +269,7 @@ function entityObject(entity) {
|
|
|
198
269
|
const candidate = entity?.mesh ?? entity?.object;
|
|
199
270
|
return candidate instanceof Object3D ? candidate : void 0;
|
|
200
271
|
}
|
|
201
|
-
function gameplayObservations(ctx, contactHistory, seed, replayRuntime) {
|
|
272
|
+
function gameplayObservations(ctx, contactHistory, seed, replayRuntime, watcher) {
|
|
202
273
|
const animation = {};
|
|
203
274
|
const states = {};
|
|
204
275
|
const snapshot = ctx.entities.snapshot();
|
|
@@ -206,61 +277,136 @@ function gameplayObservations(ctx, contactHistory, seed, replayRuntime) {
|
|
|
206
277
|
const entity = ctx.entities.get(id);
|
|
207
278
|
const finished = typeof entity?.animation?.finished === "boolean" ? entity.animation.finished : void 0;
|
|
208
279
|
if (typeof entity?.animation?.current === "string" && typeof entity.animation.advancedFrames === "number") {
|
|
280
|
+
const stride = strideObservation(entity.animation.stride);
|
|
209
281
|
animation[id] = {
|
|
210
282
|
advancedFrames: entity.animation.advancedFrames,
|
|
211
283
|
clip: entity.animation.current,
|
|
212
|
-
...finished === void 0 ? {} : { finished }
|
|
284
|
+
...finished === void 0 ? {} : { finished },
|
|
285
|
+
...stride === void 0 ? {} : { stride }
|
|
213
286
|
};
|
|
214
287
|
}
|
|
215
288
|
if (typeof entity?.state === "string") states[id] = entity.state;
|
|
216
289
|
}
|
|
217
290
|
const channels = gameplayChannels();
|
|
218
|
-
const contacts = channels.includes("runtime.contacts") ? drainContacts(ctx, contactHistory) : void 0;
|
|
291
|
+
const contacts = channels.includes("runtime.contacts") ? drainContacts(ctx, contactHistory, watcher.lastTick()) : void 0;
|
|
219
292
|
const tags = channels.includes("runtime.tags") ? tagCounts(snapshot) : void 0;
|
|
293
|
+
const transitions = watcher.read();
|
|
220
294
|
return {
|
|
221
295
|
animation,
|
|
222
296
|
...contacts === void 0 ? {} : { contacts },
|
|
223
297
|
states,
|
|
224
298
|
...tags === void 0 ? {} : { tags },
|
|
299
|
+
...transitions === void 0 ? {} : { transitions },
|
|
225
300
|
...runtimeObservation(seed, replayRuntime)
|
|
226
301
|
};
|
|
227
302
|
}
|
|
303
|
+
function strideObservation(value) {
|
|
304
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
305
|
+
const report = value;
|
|
306
|
+
const numbers = ["clipGroundSpeed", "groundSpeed", "rate"];
|
|
307
|
+
const flags = ["overridden", "synced"];
|
|
308
|
+
if (!numbers.every((key) => typeof report[key] === "number" && Number.isFinite(report[key])))
|
|
309
|
+
return void 0;
|
|
310
|
+
if (!flags.every((key) => typeof report[key] === "boolean")) return void 0;
|
|
311
|
+
return {
|
|
312
|
+
clipGroundSpeed: report.clipGroundSpeed,
|
|
313
|
+
groundSpeed: report.groundSpeed,
|
|
314
|
+
overridden: report.overridden,
|
|
315
|
+
rate: report.rate,
|
|
316
|
+
synced: report.synced
|
|
317
|
+
};
|
|
318
|
+
}
|
|
228
319
|
function gameplayChannels(_ctx) {
|
|
229
|
-
return ["runtime.contacts", "runtime.tags"];
|
|
320
|
+
return ["runtime.contacts", "runtime.tags", "runtime.transitions"];
|
|
230
321
|
}
|
|
231
|
-
function drainContacts(ctx, history) {
|
|
232
|
-
const snapshot = ctx.entities.snapshot();
|
|
322
|
+
function drainContacts(ctx, history, tick) {
|
|
233
323
|
const idsByEntity = /* @__PURE__ */ new Map();
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
for (const id of Object.keys(snapshot)) {
|
|
243
|
-
for (const source of entitySources(ctx.entities.get(id))) {
|
|
324
|
+
ctx.entities.forEach((id, registered) => {
|
|
325
|
+
for (const value of objectGraphValues(registered))
|
|
326
|
+
if (!idsByEntity.has(value)) idsByEntity.set(value, id);
|
|
327
|
+
});
|
|
328
|
+
ctx.entities.forEach((id, registered) => {
|
|
329
|
+
for (const source of entitySources(registered)) {
|
|
244
330
|
for (const event of source.drainContacts()) {
|
|
245
331
|
const entity = idsByEntity.get(event.body);
|
|
246
|
-
|
|
332
|
+
const other = event.entity ?? (event.area === void 0 ? void 0 : idsByEntity.get(event.area)) ?? idsByEntity.get(source);
|
|
333
|
+
if (entity === void 0 || other === void 0) continue;
|
|
247
334
|
history.push({
|
|
248
335
|
entity,
|
|
249
336
|
kind: event.started ? "trigger" : "trigger.exit",
|
|
250
|
-
|
|
337
|
+
...tick === void 0 ? {} : { tick },
|
|
338
|
+
with: other
|
|
251
339
|
});
|
|
252
340
|
if (history.length > PLAYTEST_PROTOCOL_LIMITS.maxEventsPerDrain) history.shift();
|
|
253
341
|
}
|
|
254
342
|
}
|
|
255
|
-
}
|
|
343
|
+
});
|
|
256
344
|
return [...history];
|
|
257
345
|
}
|
|
346
|
+
var PLAYTEST_TRANSITION_LOG_LIMIT = 512;
|
|
347
|
+
function primitiveOrUndefined(value) {
|
|
348
|
+
if (value === null) return null;
|
|
349
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
350
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
351
|
+
}
|
|
352
|
+
function createTransitionWatcher() {
|
|
353
|
+
let previous = /* @__PURE__ */ new Map();
|
|
354
|
+
let log = [];
|
|
355
|
+
let seen = false;
|
|
356
|
+
let tickSeen;
|
|
357
|
+
const record = (path, to, tick) => {
|
|
358
|
+
const had = previous.has(path);
|
|
359
|
+
const from = previous.get(path);
|
|
360
|
+
previous.set(path, to);
|
|
361
|
+
if (!had || from === to) return;
|
|
362
|
+
log.push({ from, path, tick, to });
|
|
363
|
+
if (log.length > PLAYTEST_TRANSITION_LOG_LIMIT) log.shift();
|
|
364
|
+
};
|
|
365
|
+
return {
|
|
366
|
+
lastTick: () => tickSeen,
|
|
367
|
+
observe: (ctx, tick) => {
|
|
368
|
+
tickSeen = tick;
|
|
369
|
+
seen = true;
|
|
370
|
+
ctx.entities.forEach((id, entity) => {
|
|
371
|
+
const candidate = entity;
|
|
372
|
+
if (typeof candidate.state === "string") record(`states.${id}`, candidate.state, tick);
|
|
373
|
+
});
|
|
374
|
+
const state = ctx.state.getState();
|
|
375
|
+
for (const key of Object.keys(state)) {
|
|
376
|
+
const value = primitiveOrUndefined(state[key]);
|
|
377
|
+
if (value !== void 0) record(`state.${key}`, value, tick);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
// Absent until the loop has ticked at least once. A run that never ticked has not observed
|
|
381
|
+
// that nothing changed; it has observed nothing, and an assertion against it must say so.
|
|
382
|
+
read: () => seen ? log.map((entry) => ({ ...entry })) : void 0,
|
|
383
|
+
reset: () => {
|
|
384
|
+
previous = /* @__PURE__ */ new Map();
|
|
385
|
+
log = [];
|
|
386
|
+
seen = false;
|
|
387
|
+
tickSeen = void 0;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
258
391
|
function entitySources(entity) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
(value) => typeof value === "object" && value !== null && "drainContacts" in value && typeof value.drainContacts === "function"
|
|
392
|
+
return objectGraphValues(entity).filter(
|
|
393
|
+
(value) => "drainContacts" in value && typeof value.drainContacts === "function"
|
|
262
394
|
);
|
|
263
395
|
}
|
|
396
|
+
function objectGraphValues(root) {
|
|
397
|
+
if (root === void 0) return [];
|
|
398
|
+
const values = [];
|
|
399
|
+
const visited = /* @__PURE__ */ new Set();
|
|
400
|
+
const visit = (value, depth) => {
|
|
401
|
+
if (value === null || typeof value !== "object" || visited.has(value)) return;
|
|
402
|
+
visited.add(value);
|
|
403
|
+
values.push(value);
|
|
404
|
+
if (depth >= 4 || value instanceof Object3D) return;
|
|
405
|
+
for (const child of Object.values(value)) visit(child, depth + 1);
|
|
406
|
+
};
|
|
407
|
+
visit(root, 0);
|
|
408
|
+
return values;
|
|
409
|
+
}
|
|
264
410
|
function tagCounts(snapshot) {
|
|
265
411
|
const counts = {};
|
|
266
412
|
for (const fields of Object.values(snapshot)) {
|
|
@@ -303,4 +449,4 @@ function cloneJsonValue(value) {
|
|
|
303
449
|
return value;
|
|
304
450
|
}
|
|
305
451
|
|
|
306
|
-
export { PLAYTEST_ATTACH_TIMEOUT_MS, PLAYTEST_RUNNER_EXPECTED_GLOBAL, playtest };
|
|
452
|
+
export { PLAYTEST_ATTACH_TIMEOUT_MS, PLAYTEST_RUNNER_EXPECTED_GLOBAL, PLAYTEST_TRANSITION_LOG_LIMIT, playtest };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { C as CanvasLayer } from './canvas-layer-
|
|
2
|
+
import { C as CanvasLayer } from './canvas-layer-BLVijiUJ.js';
|
|
3
3
|
import 'three';
|
|
4
|
+
import './renderer-C6hqZpoG.js';
|
|
4
5
|
import 'three/webgpu';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -162,12 +163,13 @@ interface ITextProps {
|
|
|
162
163
|
/**
|
|
163
164
|
* A rectangle. Paints when its style has a `background`; otherwise it only positions children.
|
|
164
165
|
* @situation group and position native React HUD elements
|
|
165
|
-
* @example <View style={{ centerX:
|
|
166
|
+
* @example <View style={{ centerX: true, top: 24 }}><Text>READY</Text></View>
|
|
166
167
|
*/
|
|
167
168
|
declare function View(props: IViewProps): ReactNode;
|
|
168
169
|
/**
|
|
169
170
|
* A run of bitmap glyphs, drawn as one instanced quad per lit pixel.
|
|
170
171
|
* @situation show text in a native React HUD without a DOM
|
|
172
|
+
* @alias objective panel journal
|
|
171
173
|
* @example <Text style={{ color: "#ffffff", fontSize: 24 }}>SCORE 10</Text>
|
|
172
174
|
*/
|
|
173
175
|
declare function Text(props: ITextProps): ReactNode;
|