@vimp-games/snakes 0.1.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/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/assets/vimp_snakes_core_bg-BqmtH1zs.wasm +0 -0
- package/dist/client-DZrdJlPY.js +7 -0
- package/dist/core-node/package.json +16 -0
- package/dist/core-node/vimp_snakes_core.d.ts +231 -0
- package/dist/core-node/vimp_snakes_core.js +743 -0
- package/dist/core-node/vimp_snakes_core_bg.wasm +0 -0
- package/dist/core-node/vimp_snakes_core_bg.wasm.d.ts +56 -0
- package/dist/host-ClLuGvxl.js +1 -0
- package/dist/manifest.json +38 -0
- package/dist/maps/arena.json +1 -0
- package/dist/sounds/death.mp3 +0 -0
- package/dist/sounds/death.webm +0 -0
- package/dist/sounds/shot.mp3 +0 -0
- package/dist/sounds/shot.webm +0 -0
- package/package.json +48 -0
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
/* @ts-self-types="./vimp_snakes_core.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Client half of the core: interpolation of snapshots and prediction of the
|
|
5
|
+
* local snake. Lives in the main thread of the tab.
|
|
6
|
+
*/
|
|
7
|
+
class ClientCore {
|
|
8
|
+
__destroy_into_raw() {
|
|
9
|
+
const ptr = this.__wbg_ptr;
|
|
10
|
+
this.__wbg_ptr = 0;
|
|
11
|
+
ClientCoreFinalization.unregister(this);
|
|
12
|
+
return ptr;
|
|
13
|
+
}
|
|
14
|
+
free() {
|
|
15
|
+
const ptr = this.__destroy_into_raw();
|
|
16
|
+
wasm.__wbg_clientcore_free(ptr, 0);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Ввод игрока: action ('down'/'up') + имя клавиши — в историю
|
|
20
|
+
* предикта.
|
|
21
|
+
* @param {string} action
|
|
22
|
+
* @param {string} key_name
|
|
23
|
+
* @param {number} local_now
|
|
24
|
+
*/
|
|
25
|
+
apply_input(action, key_name, local_now) {
|
|
26
|
+
const ptr0 = passStringToWasm0(action, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
27
|
+
const len0 = WASM_VECTOR_LEN;
|
|
28
|
+
const ptr1 = passStringToWasm0(key_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
29
|
+
const len1 = WASM_VECTOR_LEN;
|
|
30
|
+
wasm.clientcore_apply_input(this.__wbg_ptr, ptr0, len0, ptr1, len1, local_now);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Дамп клиентского состояния для отладки: сетевой буфер
|
|
34
|
+
* (глубина, окно seq, оффсет, последний кадр), свой gameId,
|
|
35
|
+
* размеры hot-буфера и очереди событийных кадров.
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
debug_json() {
|
|
39
|
+
let deferred1_0;
|
|
40
|
+
let deferred1_1;
|
|
41
|
+
try {
|
|
42
|
+
const ret = wasm.clientcore_debug_json(this.__wbg_ptr);
|
|
43
|
+
deferred1_0 = ret[0];
|
|
44
|
+
deferred1_1 = ret[1];
|
|
45
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
46
|
+
} finally {
|
|
47
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Чистая распаковка кадра v3 → JSON {port, seq, serverTime,
|
|
52
|
+
* camera, player, snapshot} (замена unpackFrame в тестах);
|
|
53
|
+
* 'null' при несовпадении версии или повреждённом кадре.
|
|
54
|
+
* @param {Uint8Array} data
|
|
55
|
+
* @returns {string}
|
|
56
|
+
*/
|
|
57
|
+
decode_frame(data) {
|
|
58
|
+
let deferred2_0;
|
|
59
|
+
let deferred2_1;
|
|
60
|
+
try {
|
|
61
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
62
|
+
const len0 = WASM_VECTOR_LEN;
|
|
63
|
+
const ret = wasm.clientcore_decode_frame(this.__wbg_ptr, ptr0, len0);
|
|
64
|
+
deferred2_0 = ret[0];
|
|
65
|
+
deferred2_1 = ret[1];
|
|
66
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
67
|
+
} finally {
|
|
68
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Указатель на hot-буфер (zero-copy чтение из JS:
|
|
73
|
+
* new Float32Array(wasm.memory.buffer, ptr, len) — view
|
|
74
|
+
* пересоздавать каждый тик, рост памяти WASM инвалидирует
|
|
75
|
+
* buffer).
|
|
76
|
+
* @returns {number}
|
|
77
|
+
*/
|
|
78
|
+
hot_ptr() {
|
|
79
|
+
const ret = wasm.clientcore_hot_ptr(this.__wbg_ptr);
|
|
80
|
+
return ret >>> 0;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Копия hot-буфера (nodejs-таргет; горячий путь браузера —
|
|
84
|
+
* hot_ptr).
|
|
85
|
+
* @returns {Float32Array}
|
|
86
|
+
*/
|
|
87
|
+
hot_values() {
|
|
88
|
+
const ret = wasm.clientcore_hot_values(this.__wbg_ptr);
|
|
89
|
+
var v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
|
|
90
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
91
|
+
return v1;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Свой gameId из последнего player-блока; -1, если ещё не
|
|
95
|
+
* приходил.
|
|
96
|
+
* @returns {number}
|
|
97
|
+
*/
|
|
98
|
+
my_game_id() {
|
|
99
|
+
const ret = wasm.clientcore_my_game_id(this.__wbg_ptr);
|
|
100
|
+
return ret;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Builds the client core from `{engine: {...}, game: {...}}` assembled
|
|
104
|
+
* by the engine from CONFIG_DATA.
|
|
105
|
+
* @param {string} config_json
|
|
106
|
+
*/
|
|
107
|
+
constructor(config_json) {
|
|
108
|
+
const ptr0 = passStringToWasm0(config_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
109
|
+
const len0 = WASM_VECTOR_LEN;
|
|
110
|
+
const ret = wasm.clientcore_new(ptr0, len0);
|
|
111
|
+
if (ret[2]) {
|
|
112
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
113
|
+
}
|
|
114
|
+
this.__wbg_ptr = ret[0];
|
|
115
|
+
ClientCoreFinalization.register(this, this.__wbg_ptr, this);
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* EMA-оценка (serverTime − localNow); NaN, если кадров ещё не
|
|
120
|
+
* было. Это разница часов (`Date.now` хоста против
|
|
121
|
+
* `performance.now` клиента), а **не** латентность: за оценку
|
|
122
|
+
* RTT её принимать нельзя.
|
|
123
|
+
* @returns {number}
|
|
124
|
+
*/
|
|
125
|
+
offset() {
|
|
126
|
+
const ret = wasm.clientcore_offset(this.__wbg_ptr);
|
|
127
|
+
return ret;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Бинарный кадр из транспорта: распаковка, вставка в буфер по
|
|
131
|
+
* seq (+дедупликация/опоздавшие), reconciliation предикта по
|
|
132
|
+
* player-блоку. false — кадр отброшен (чужой порт/версия/
|
|
133
|
+
* повреждён).
|
|
134
|
+
* @param {Uint8Array} data
|
|
135
|
+
* @param {number} local_now
|
|
136
|
+
* @returns {boolean}
|
|
137
|
+
*/
|
|
138
|
+
push_frame(data, local_now) {
|
|
139
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
140
|
+
const len0 = WASM_VECTOR_LEN;
|
|
141
|
+
const ret = wasm.clientcore_push_frame(this.__wbg_ptr, ptr0, len0, local_now);
|
|
142
|
+
return ret !== 0;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Полный сброс (порт CLEAR).
|
|
146
|
+
*/
|
|
147
|
+
reset() {
|
|
148
|
+
wasm.clientcore_reset(this.__wbg_ptr);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Ресинк часов после долгой паузы вкладки: сброс сетевого
|
|
152
|
+
* буфера и очереди кадров без обнуления предикта.
|
|
153
|
+
*/
|
|
154
|
+
resync() {
|
|
155
|
+
wasm.clientcore_resync(this.__wbg_ptr);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Весь рендер-тик: выдача пересечённых кадров (фильтр дублей
|
|
159
|
+
* своих эффектов → JSON-очередь), интерполяция, шаг предикта,
|
|
160
|
+
* запись hot-буфера. Возвращает длину hot-буфера в
|
|
161
|
+
* f32-элементах.
|
|
162
|
+
* @param {number} local_now
|
|
163
|
+
* @returns {number}
|
|
164
|
+
*/
|
|
165
|
+
sample(local_now) {
|
|
166
|
+
const ret = wasm.clientcore_sample(this.__wbg_ptr, local_now);
|
|
167
|
+
return ret >>> 0;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Смена режима игрок/спектатор (KEYSET_DATA).
|
|
171
|
+
* @param {boolean} active
|
|
172
|
+
*/
|
|
173
|
+
set_active(active) {
|
|
174
|
+
wasm.clientcore_set_active(this.__wbg_ptr, active);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Данные карты (MAP_DATA): мир raycast + сброс буфера и
|
|
178
|
+
* предикта.
|
|
179
|
+
* @param {string} map_json
|
|
180
|
+
*/
|
|
181
|
+
set_map(map_json) {
|
|
182
|
+
const ptr0 = passStringToWasm0(map_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
183
|
+
const len0 = WASM_VECTOR_LEN;
|
|
184
|
+
const ret = wasm.clientcore_set_map(this.__wbg_ptr, ptr0, len0);
|
|
185
|
+
if (ret[1]) {
|
|
186
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Model of the local snake (known at authorization). Without it the
|
|
191
|
+
* predictor has no speed and no turn rate and cannot move anything.
|
|
192
|
+
* @param {string} model
|
|
193
|
+
*/
|
|
194
|
+
set_model(model) {
|
|
195
|
+
const ptr0 = passStringToWasm0(model, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
196
|
+
const len0 = WASM_VECTOR_LEN;
|
|
197
|
+
wasm.clientcore_set_model(this.__wbg_ptr, ptr0, len0);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Authoritative panel state (PANEL_DATA). Nothing in the prediction
|
|
201
|
+
* depends on it — the crystal count arrives in the player block — but the
|
|
202
|
+
* hook is called unconditionally and the plumbing is cheap to keep.
|
|
203
|
+
* @param {string} panel_json
|
|
204
|
+
*/
|
|
205
|
+
sync_panel(panel_json) {
|
|
206
|
+
const ptr0 = passStringToWasm0(panel_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
207
|
+
const len0 = WASM_VECTOR_LEN;
|
|
208
|
+
wasm.clientcore_sync_panel(this.__wbg_ptr, ptr0, len0);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Записи расхождения предикта с авторитетным состоянием
|
|
212
|
+
* (JSON {samples, violations, dropped, maxDelta, records});
|
|
213
|
+
* очередь очищается. 'null' — детектор выключен (конфиг без
|
|
214
|
+
* секции divergence, боевой путь).
|
|
215
|
+
* @returns {string}
|
|
216
|
+
*/
|
|
217
|
+
take_divergence() {
|
|
218
|
+
let deferred1_0;
|
|
219
|
+
let deferred1_1;
|
|
220
|
+
try {
|
|
221
|
+
const ret = wasm.clientcore_take_divergence(this.__wbg_ptr);
|
|
222
|
+
deferred1_0 = ret[0];
|
|
223
|
+
deferred1_1 = ret[1];
|
|
224
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
225
|
+
} finally {
|
|
226
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Событийные кадры JSON-строкой [{game, camera}, ...] в
|
|
231
|
+
* форме, готовой для applyShot; вызывать при флаге hasFrames
|
|
232
|
+
* hot-буфера, очередь очищается.
|
|
233
|
+
* @returns {string}
|
|
234
|
+
*/
|
|
235
|
+
take_frames() {
|
|
236
|
+
let deferred1_0;
|
|
237
|
+
let deferred1_1;
|
|
238
|
+
try {
|
|
239
|
+
const ret = wasm.clientcore_take_frames(this.__wbg_ptr);
|
|
240
|
+
deferred1_0 = ret[0];
|
|
241
|
+
deferred1_1 = ret[1];
|
|
242
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
243
|
+
} finally {
|
|
244
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (Symbol.dispose) ClientCore.prototype[Symbol.dispose] = ClientCore.prototype.free;
|
|
249
|
+
exports.ClientCore = ClientCore;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Public ABI of the core for the JS host (Worker / Node test harness).
|
|
253
|
+
* The field names `state` and `packer` are a contract: the macro looks them
|
|
254
|
+
* up literally.
|
|
255
|
+
*/
|
|
256
|
+
class GameCore {
|
|
257
|
+
__destroy_into_raw() {
|
|
258
|
+
const ptr = this.__wbg_ptr;
|
|
259
|
+
this.__wbg_ptr = 0;
|
|
260
|
+
GameCoreFinalization.unregister(this);
|
|
261
|
+
return ptr;
|
|
262
|
+
}
|
|
263
|
+
free() {
|
|
264
|
+
const ptr = this.__destroy_into_raw();
|
|
265
|
+
wasm.__wbg_gamecore_free(ptr, 0);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Живые игроки плоским массивом [id, teamId, x, y, ...]
|
|
269
|
+
* (аналог Game.getAlivePlayers для меты).
|
|
270
|
+
* @returns {Float32Array}
|
|
271
|
+
*/
|
|
272
|
+
alive_players() {
|
|
273
|
+
const ret = wasm.gamecore_alive_players(this.__wbg_ptr);
|
|
274
|
+
var v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
|
|
275
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
276
|
+
return v1;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Ввод игрока: seq + action ('down'/'up') + имя клавиши
|
|
280
|
+
* (wire-формат 'seq:action:name' разбирает JS-оболочка).
|
|
281
|
+
* @param {number} game_id
|
|
282
|
+
* @param {number} seq
|
|
283
|
+
* @param {string} action
|
|
284
|
+
* @param {string} key_name
|
|
285
|
+
*/
|
|
286
|
+
apply_input(game_id, seq, action, key_name) {
|
|
287
|
+
const ptr0 = passStringToWasm0(action, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
288
|
+
const len0 = WASM_VECTOR_LEN;
|
|
289
|
+
const ptr1 = passStringToWasm0(key_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
290
|
+
const len1 = WASM_VECTOR_LEN;
|
|
291
|
+
wasm.gamecore_apply_input(this.__wbg_ptr, game_id, seq, ptr0, len0, ptr1, len1);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Содержал ли последний `pack_body()` событийные блоки
|
|
295
|
+
* (трассеры/бомбы/взрывы/удаления). JS-Worker вызывает после
|
|
296
|
+
* `pack_body()` для выбора канала WebRTC: события → meta
|
|
297
|
+
* (reliable), только позиции → state.
|
|
298
|
+
* @returns {boolean}
|
|
299
|
+
*/
|
|
300
|
+
body_has_events() {
|
|
301
|
+
const ret = wasm.gamecore_body_has_events(this.__wbg_ptr);
|
|
302
|
+
return ret !== 0;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Полная очистка мира (смена карты).
|
|
306
|
+
*/
|
|
307
|
+
clear() {
|
|
308
|
+
wasm.gamecore_clear(this.__wbg_ptr);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Курированный дамп мира для отладки (тела, коллайдеры,
|
|
312
|
+
* карта, нав-граф, spatial-сетка, rng, аккумулятор) —
|
|
313
|
+
* читаемая альтернатива serialize_state.
|
|
314
|
+
* @returns {string}
|
|
315
|
+
*/
|
|
316
|
+
debug_json() {
|
|
317
|
+
let deferred1_0;
|
|
318
|
+
let deferred1_1;
|
|
319
|
+
try {
|
|
320
|
+
const ret = wasm.gamecore_debug_json(this.__wbg_ptr);
|
|
321
|
+
deferred1_0 = ret[0];
|
|
322
|
+
deferred1_1 = ret[1];
|
|
323
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
324
|
+
} finally {
|
|
325
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* @param {Uint8Array} data
|
|
330
|
+
*/
|
|
331
|
+
deserialize_state(data) {
|
|
332
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
333
|
+
const len0 = WASM_VECTOR_LEN;
|
|
334
|
+
const ret = wasm.gamecore_deserialize_state(this.__wbg_ptr, ptr0, len0);
|
|
335
|
+
if (ret[1]) {
|
|
336
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Копия последнего кадра (nodejs-таргет не отдаёт память
|
|
341
|
+
* наружу; горячий путь браузера использует frame_ptr + память
|
|
342
|
+
* WASM).
|
|
343
|
+
* @returns {Uint8Array}
|
|
344
|
+
*/
|
|
345
|
+
frame_bytes() {
|
|
346
|
+
const ret = wasm.gamecore_frame_bytes(this.__wbg_ptr);
|
|
347
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
348
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
349
|
+
return v1;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Указатель на буфер последнего кадра (zero-copy чтение из JS:
|
|
353
|
+
* new Uint8Array(wasm.memory.buffer, ptr, len)).
|
|
354
|
+
* @returns {number}
|
|
355
|
+
*/
|
|
356
|
+
frame_ptr() {
|
|
357
|
+
const ret = wasm.gamecore_frame_ptr(this.__wbg_ptr);
|
|
358
|
+
return ret >>> 0;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* @param {number} game_id
|
|
362
|
+
* @returns {boolean}
|
|
363
|
+
*/
|
|
364
|
+
is_alive(game_id) {
|
|
365
|
+
const ret = wasm.gamecore_is_alive(this.__wbg_ptr, game_id);
|
|
366
|
+
return ret !== 0;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* @param {number} game_id
|
|
370
|
+
* @returns {number}
|
|
371
|
+
*/
|
|
372
|
+
last_input_seq(game_id) {
|
|
373
|
+
const ret = wasm.gamecore_last_input_seq(this.__wbg_ptr, game_id);
|
|
374
|
+
return ret >>> 0;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Загружает карту из JSON (см. scripts/export-maps.js).
|
|
378
|
+
* @param {string} map_json
|
|
379
|
+
*/
|
|
380
|
+
load_map(map_json) {
|
|
381
|
+
const ptr0 = passStringToWasm0(map_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
382
|
+
const len0 = WASM_VECTOR_LEN;
|
|
383
|
+
const ret = wasm.gamecore_load_map(this.__wbg_ptr, ptr0, len0);
|
|
384
|
+
if (ret[1]) {
|
|
385
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Информация о загруженной карте: setId, масштабированные
|
|
390
|
+
* респауны, размеры мира (JSON).
|
|
391
|
+
* @returns {string}
|
|
392
|
+
*/
|
|
393
|
+
map_info() {
|
|
394
|
+
let deferred1_0;
|
|
395
|
+
let deferred1_1;
|
|
396
|
+
try {
|
|
397
|
+
const ret = wasm.gamecore_map_info(this.__wbg_ptr);
|
|
398
|
+
deferred1_0 = ret[0];
|
|
399
|
+
deferred1_1 = ret[1];
|
|
400
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
401
|
+
} finally {
|
|
402
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Builds the core from the JSON config `{engine: {...}, game: {...}}`
|
|
407
|
+
* assembled by the engine from src/config/.
|
|
408
|
+
* @param {string} config_json
|
|
409
|
+
*/
|
|
410
|
+
constructor(config_json) {
|
|
411
|
+
const ptr0 = passStringToWasm0(config_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
412
|
+
const len0 = WASM_VECTOR_LEN;
|
|
413
|
+
const ret = wasm.gamecore_new(ptr0, len0);
|
|
414
|
+
if (ret[2]) {
|
|
415
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
416
|
+
}
|
|
417
|
+
this.__wbg_ptr = ret[0];
|
|
418
|
+
GameCoreFinalization.register(this, this.__wbg_ptr, this);
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Пакует broadcast-тело кадра, дренируя накопленные события
|
|
423
|
+
* снапшота. Вызывать один раз на отправляемый кадр (throttle
|
|
424
|
+
* частоты отправки — забота JS-оболочки).
|
|
425
|
+
*/
|
|
426
|
+
pack_body() {
|
|
427
|
+
const ret = wasm.gamecore_pack_body(this.__wbg_ptr);
|
|
428
|
+
if (ret[1]) {
|
|
429
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Собирает per-user кадр v3 во внутренний буфер, возвращает
|
|
434
|
+
* длину. Кадр читается zero-copy через frame_ptr() + память
|
|
435
|
+
* WASM. player_id < 0 — кадр без player-блока (наблюдатель).
|
|
436
|
+
* @param {number} server_time
|
|
437
|
+
* @param {number} seq
|
|
438
|
+
* @param {boolean} has_camera
|
|
439
|
+
* @param {number} camera_x
|
|
440
|
+
* @param {number} camera_y
|
|
441
|
+
* @param {boolean} force_reset
|
|
442
|
+
* @param {string | null | undefined} shake
|
|
443
|
+
* @param {number} player_id
|
|
444
|
+
* @returns {number}
|
|
445
|
+
*/
|
|
446
|
+
pack_frame(server_time, seq, has_camera, camera_x, camera_y, force_reset, shake, player_id) {
|
|
447
|
+
var ptr0 = isLikeNone(shake) ? 0 : passStringToWasm0(shake, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
448
|
+
var len0 = WASM_VECTOR_LEN;
|
|
449
|
+
const ret = wasm.gamecore_pack_frame(this.__wbg_ptr, server_time, seq, has_camera, camera_x, camera_y, force_reset, ptr0, len0, player_id);
|
|
450
|
+
return ret >>> 0;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Полные данные всех игроков (Game.getPlayersData) одной
|
|
454
|
+
* JSON-строкой для первого кадра (FIRST_SHOT_DATA). Не
|
|
455
|
+
* дренирует накопители.
|
|
456
|
+
* @returns {string}
|
|
457
|
+
*/
|
|
458
|
+
players_data() {
|
|
459
|
+
let deferred1_0;
|
|
460
|
+
let deferred1_1;
|
|
461
|
+
try {
|
|
462
|
+
const ret = wasm.gamecore_players_data(this.__wbg_ptr);
|
|
463
|
+
deferred1_0 = ret[0];
|
|
464
|
+
deferred1_1 = ret[1];
|
|
465
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
466
|
+
} finally {
|
|
467
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Координаты танка [x, y] (скруглены до 2 знаков) или пустой
|
|
472
|
+
* массив.
|
|
473
|
+
* @param {number} game_id
|
|
474
|
+
* @returns {Float32Array}
|
|
475
|
+
*/
|
|
476
|
+
position_of(game_id) {
|
|
477
|
+
const ret = wasm.gamecore_position_of(this.__wbg_ptr, game_id);
|
|
478
|
+
var v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
|
|
479
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
480
|
+
return v1;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* @param {number} game_id
|
|
484
|
+
*/
|
|
485
|
+
remove_actor(game_id) {
|
|
486
|
+
wasm.gamecore_remove_actor(this.__wbg_ptr, game_id);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Удаляет игроков и снаряды, возвращает JSON-массив имён для
|
|
490
|
+
* очистки полотна клиентов (Game.removePlayersAndShots).
|
|
491
|
+
* @returns {string}
|
|
492
|
+
*/
|
|
493
|
+
remove_players_and_shots() {
|
|
494
|
+
let deferred1_0;
|
|
495
|
+
let deferred1_1;
|
|
496
|
+
try {
|
|
497
|
+
const ret = wasm.gamecore_remove_players_and_shots(this.__wbg_ptr);
|
|
498
|
+
deferred1_0 = ret[0];
|
|
499
|
+
deferred1_1 = ret[1];
|
|
500
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
501
|
+
} finally {
|
|
502
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* @param {number} game_id
|
|
507
|
+
*/
|
|
508
|
+
remove_scripted_actor(game_id) {
|
|
509
|
+
wasm.gamecore_remove_scripted_actor(this.__wbg_ptr, game_id);
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Респаун/смена команды (аналог Game.changePlayerData).
|
|
513
|
+
* @param {number} game_id
|
|
514
|
+
* @param {number} team_id
|
|
515
|
+
* @param {number} x
|
|
516
|
+
* @param {number} y
|
|
517
|
+
* @param {number} angle_deg
|
|
518
|
+
*/
|
|
519
|
+
reset_actor(game_id, team_id, x, y, angle_deg) {
|
|
520
|
+
wasm.gamecore_reset_actor(this.__wbg_ptr, game_id, team_id, x, y, angle_deg);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Сброс здоровья/боезапаса всех танков (аналог Panel.reset).
|
|
524
|
+
*/
|
|
525
|
+
reset_all_vitals() {
|
|
526
|
+
wasm.gamecore_reset_all_vitals(this.__wbg_ptr);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Дамп состояния симуляции (Worker Handoff, Этап 5.2).
|
|
530
|
+
* @returns {Uint8Array}
|
|
531
|
+
*/
|
|
532
|
+
serialize_state() {
|
|
533
|
+
const ret = wasm.gamecore_serialize_state(this.__wbg_ptr);
|
|
534
|
+
if (ret[3]) {
|
|
535
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
536
|
+
}
|
|
537
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
538
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
539
|
+
return v1;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* @param {number} game_id
|
|
543
|
+
* @param {string} model
|
|
544
|
+
* @param {number} team_id
|
|
545
|
+
* @param {number} x
|
|
546
|
+
* @param {number} y
|
|
547
|
+
* @param {number} angle_deg
|
|
548
|
+
*/
|
|
549
|
+
spawn_actor(game_id, model, team_id, x, y, angle_deg) {
|
|
550
|
+
const ptr0 = passStringToWasm0(model, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
551
|
+
const len0 = WASM_VECTOR_LEN;
|
|
552
|
+
const ret = wasm.gamecore_spawn_actor(this.__wbg_ptr, game_id, ptr0, len0, team_id, x, y, angle_deg);
|
|
553
|
+
if (ret[1]) {
|
|
554
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* @param {number} game_id
|
|
559
|
+
* @param {string} model
|
|
560
|
+
* @param {number} team_id
|
|
561
|
+
* @param {number} x
|
|
562
|
+
* @param {number} y
|
|
563
|
+
* @param {number} angle_deg
|
|
564
|
+
*/
|
|
565
|
+
spawn_scripted_actor(game_id, model, team_id, x, y, angle_deg) {
|
|
566
|
+
const ptr0 = passStringToWasm0(model, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
567
|
+
const len0 = WASM_VECTOR_LEN;
|
|
568
|
+
const ret = wasm.gamecore_spawn_scripted_actor(this.__wbg_ptr, game_id, ptr0, len0, team_id, x, y, angle_deg);
|
|
569
|
+
if (ret[1]) {
|
|
570
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Шаг симуляции: фиксированные подшаги физики + ИИ ботов.
|
|
575
|
+
* @param {number} dt
|
|
576
|
+
*/
|
|
577
|
+
step(dt) {
|
|
578
|
+
wasm.gamecore_step(this.__wbg_ptr, dt);
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* События за тик (kill/health/ammo/weapon/shake) одной
|
|
582
|
+
* JSON-строкой; буфер очищается.
|
|
583
|
+
* @returns {string}
|
|
584
|
+
*/
|
|
585
|
+
take_events() {
|
|
586
|
+
let deferred1_0;
|
|
587
|
+
let deferred1_1;
|
|
588
|
+
try {
|
|
589
|
+
const ret = wasm.gamecore_take_events(this.__wbg_ptr);
|
|
590
|
+
deferred1_0 = ret[0];
|
|
591
|
+
deferred1_1 = ret[1];
|
|
592
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
593
|
+
} finally {
|
|
594
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (Symbol.dispose) GameCore.prototype[Symbol.dispose] = GameCore.prototype.free;
|
|
599
|
+
exports.GameCore = GameCore;
|
|
600
|
+
function __wbg_get_imports() {
|
|
601
|
+
const import0 = {
|
|
602
|
+
__proto__: null,
|
|
603
|
+
__wbg_Error_408e67f47ca7b58b: function(arg0, arg1) {
|
|
604
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
605
|
+
return ret;
|
|
606
|
+
},
|
|
607
|
+
__wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
|
|
608
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
609
|
+
},
|
|
610
|
+
__wbindgen_init_externref_table: function() {
|
|
611
|
+
const table = wasm.__wbindgen_externrefs;
|
|
612
|
+
const offset = table.grow(4);
|
|
613
|
+
table.set(0, undefined);
|
|
614
|
+
table.set(offset + 0, undefined);
|
|
615
|
+
table.set(offset + 1, null);
|
|
616
|
+
table.set(offset + 2, true);
|
|
617
|
+
table.set(offset + 3, false);
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
return {
|
|
621
|
+
__proto__: null,
|
|
622
|
+
"./vimp_snakes_core_bg.js": import0,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const ClientCoreFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
627
|
+
? { register: () => {}, unregister: () => {} }
|
|
628
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_clientcore_free(ptr, 1));
|
|
629
|
+
const GameCoreFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
630
|
+
? { register: () => {}, unregister: () => {} }
|
|
631
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_gamecore_free(ptr, 1));
|
|
632
|
+
|
|
633
|
+
function getArrayF32FromWasm0(ptr, len) {
|
|
634
|
+
ptr = ptr >>> 0;
|
|
635
|
+
return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
639
|
+
ptr = ptr >>> 0;
|
|
640
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
let cachedFloat32ArrayMemory0 = null;
|
|
644
|
+
function getFloat32ArrayMemory0() {
|
|
645
|
+
if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {
|
|
646
|
+
cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);
|
|
647
|
+
}
|
|
648
|
+
return cachedFloat32ArrayMemory0;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function getStringFromWasm0(ptr, len) {
|
|
652
|
+
return decodeText(ptr >>> 0, len);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
let cachedUint8ArrayMemory0 = null;
|
|
656
|
+
function getUint8ArrayMemory0() {
|
|
657
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
658
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
659
|
+
}
|
|
660
|
+
return cachedUint8ArrayMemory0;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function isLikeNone(x) {
|
|
664
|
+
return x === undefined || x === null;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
668
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
669
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
670
|
+
WASM_VECTOR_LEN = arg.length;
|
|
671
|
+
return ptr;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
675
|
+
if (realloc === undefined) {
|
|
676
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
677
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
678
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
679
|
+
WASM_VECTOR_LEN = buf.length;
|
|
680
|
+
return ptr;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
let len = arg.length;
|
|
684
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
685
|
+
|
|
686
|
+
const mem = getUint8ArrayMemory0();
|
|
687
|
+
|
|
688
|
+
let offset = 0;
|
|
689
|
+
|
|
690
|
+
for (; offset < len; offset++) {
|
|
691
|
+
const code = arg.charCodeAt(offset);
|
|
692
|
+
if (code > 0x7F) break;
|
|
693
|
+
mem[ptr + offset] = code;
|
|
694
|
+
}
|
|
695
|
+
if (offset !== len) {
|
|
696
|
+
if (offset !== 0) {
|
|
697
|
+
arg = arg.slice(offset);
|
|
698
|
+
}
|
|
699
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
700
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
701
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
702
|
+
|
|
703
|
+
offset += ret.written;
|
|
704
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
WASM_VECTOR_LEN = offset;
|
|
708
|
+
return ptr;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function takeFromExternrefTable0(idx) {
|
|
712
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
713
|
+
wasm.__externref_table_dealloc(idx);
|
|
714
|
+
return value;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
718
|
+
cachedTextDecoder.decode();
|
|
719
|
+
function decodeText(ptr, len) {
|
|
720
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
const cachedTextEncoder = new TextEncoder();
|
|
724
|
+
|
|
725
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
726
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
727
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
728
|
+
view.set(buf);
|
|
729
|
+
return {
|
|
730
|
+
read: arg.length,
|
|
731
|
+
written: buf.length
|
|
732
|
+
};
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
let WASM_VECTOR_LEN = 0;
|
|
737
|
+
|
|
738
|
+
const wasmPath = `${__dirname}/vimp_snakes_core_bg.wasm`;
|
|
739
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
740
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
741
|
+
let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports());
|
|
742
|
+
let wasm = wasmInstance.exports;
|
|
743
|
+
wasm.__wbindgen_start();
|