@rine-kit/pubg-intelligence 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/dist/src/analytics.d.ts +176 -0
- package/dist/src/analytics.js +431 -0
- package/dist/src/analytics.js.map +1 -0
- package/dist/src/assistant.d.ts +87 -0
- package/dist/src/assistant.js +310 -0
- package/dist/src/assistant.js.map +1 -0
- package/dist/src/battle.d.ts +280 -0
- package/dist/src/battle.js +1249 -0
- package/dist/src/battle.js.map +1 -0
- package/dist/src/combat-long.d.ts +42 -0
- package/dist/src/combat-long.js +146 -0
- package/dist/src/combat-long.js.map +1 -0
- package/dist/src/combat-quality.d.ts +101 -0
- package/dist/src/combat-quality.js +253 -0
- package/dist/src/combat-quality.js.map +1 -0
- package/dist/src/evaluation-fixtures.d.ts +13 -0
- package/dist/src/evaluation-fixtures.js +144 -0
- package/dist/src/evaluation-fixtures.js.map +1 -0
- package/dist/src/evaluation-replay.d.ts +5 -0
- package/dist/src/evaluation-replay.js +107 -0
- package/dist/src/evaluation-replay.js.map +1 -0
- package/dist/src/evaluation.d.ts +140 -0
- package/dist/src/evaluation.js +180 -0
- package/dist/src/evaluation.js.map +1 -0
- package/dist/src/experiment-store.d.ts +56 -0
- package/dist/src/experiment-store.js +159 -0
- package/dist/src/experiment-store.js.map +1 -0
- package/dist/src/field.d.ts +103 -0
- package/dist/src/field.js +298 -0
- package/dist/src/field.js.map +1 -0
- package/dist/src/fights.d.ts +89 -0
- package/dist/src/fights.js +238 -0
- package/dist/src/fights.js.map +1 -0
- package/dist/src/highlights.d.ts +44 -0
- package/dist/src/highlights.js +153 -0
- package/dist/src/highlights.js.map +1 -0
- package/dist/src/index.d.ts +24 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/insights.d.ts +44 -0
- package/dist/src/insights.js +343 -0
- package/dist/src/insights.js.map +1 -0
- package/dist/src/intent.d.ts +40 -0
- package/dist/src/intent.js +119 -0
- package/dist/src/intent.js.map +1 -0
- package/dist/src/landing.d.ts +74 -0
- package/dist/src/landing.js +195 -0
- package/dist/src/landing.js.map +1 -0
- package/dist/src/lobby.d.ts +48 -0
- package/dist/src/lobby.js +209 -0
- package/dist/src/lobby.js.map +1 -0
- package/dist/src/match-insight.d.ts +165 -0
- package/dist/src/match-insight.js +542 -0
- package/dist/src/match-insight.js.map +1 -0
- package/dist/src/match-relative.d.ts +73 -0
- package/dist/src/match-relative.js +145 -0
- package/dist/src/match-relative.js.map +1 -0
- package/dist/src/match-story.d.ts +155 -0
- package/dist/src/match-story.js +636 -0
- package/dist/src/match-story.js.map +1 -0
- package/dist/src/profiles.d.ts +41 -0
- package/dist/src/profiles.js +136 -0
- package/dist/src/profiles.js.map +1 -0
- package/dist/src/raw-telemetry-archive.d.ts +29 -0
- package/dist/src/raw-telemetry-archive.js +340 -0
- package/dist/src/raw-telemetry-archive.js.map +1 -0
- package/dist/src/raw-telemetry-backfill.d.ts +28 -0
- package/dist/src/raw-telemetry-backfill.js +144 -0
- package/dist/src/raw-telemetry-backfill.js.map +1 -0
- package/dist/src/research.d.ts +89 -0
- package/dist/src/research.js +376 -0
- package/dist/src/research.js.map +1 -0
- package/dist/src/rhythm.d.ts +104 -0
- package/dist/src/rhythm.js +260 -0
- package/dist/src/rhythm.js.map +1 -0
- package/dist/src/streaks.d.ts +117 -0
- package/dist/src/streaks.js +367 -0
- package/dist/src/streaks.js.map +1 -0
- package/dist/src/style.d.ts +304 -0
- package/dist/src/style.js +1461 -0
- package/dist/src/style.js.map +1 -0
- package/dist/src/tactics.d.ts +88 -0
- package/dist/src/tactics.js +1221 -0
- package/dist/src/tactics.js.map +1 -0
- package/package.json +49 -3
- package/README.md +0 -3
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { type RoleCounts } from './fights.js';
|
|
2
|
+
export declare const STYLE_SCHEMA_VERSION: 2;
|
|
3
|
+
export declare const STYLE_RULE_VERSION: "play-style-v2";
|
|
4
|
+
export declare const STYLE_BOOTSTRAP_RESAMPLES = 300;
|
|
5
|
+
export declare const STYLE_BOOTSTRAP_SEED = 20261018;
|
|
6
|
+
/** Ratio to teammates beyond which a difference is worth naming; its inverse applies on the low side. */
|
|
7
|
+
export declare const STYLE_NOTABLE_RATIO = 1.15;
|
|
8
|
+
/** Share of bootstrap resamples that must agree on the direction for a "lean". */
|
|
9
|
+
export declare const STYLE_LEAN_CONFIDENCE = 0.85;
|
|
10
|
+
export declare const STYLE_MIN_FIGHTS = 40;
|
|
11
|
+
export declare const STYLE_MIN_DAMAGE = 1500;
|
|
12
|
+
export declare const STYLE_MIN_MINUTES = 60;
|
|
13
|
+
export declare const STYLE_MIN_SHOTS = 800;
|
|
14
|
+
/** A shot counts as part of a fight when someone on either side was hurt within this long before or after it. */
|
|
15
|
+
export declare const STYLE_ENGAGE_WINDOW_MS = 8000;
|
|
16
|
+
/** Fewest shots in a first-shot or follow-up group before its hit rate is measured. */
|
|
17
|
+
export declare const STYLE_MIN_SPLIT_SHOTS = 300;
|
|
18
|
+
/** A shot fired this soon after the previous one from the same weapon is a follow-up bullet of a burst or spray. */
|
|
19
|
+
export declare const STYLE_BURST_GAP_MS = 120;
|
|
20
|
+
/** Prior shots pulling a teammate class hit rate toward the teammates' overall rate in the weapon-mix adjustment. */
|
|
21
|
+
export declare const STYLE_CLASS_PRIOR_SHOTS = 200;
|
|
22
|
+
export declare const STYLE_MIN_KNOCKS = 25;
|
|
23
|
+
export declare const STYLE_MIN_SPACING_SAMPLES = 100;
|
|
24
|
+
export declare const STYLE_MIN_ZONE_SAMPLES = 150;
|
|
25
|
+
export declare const STYLE_MIN_PICKUP_MATCHES = 8;
|
|
26
|
+
export declare const STYLE_ARCHETYPE_STRONG = 0.45;
|
|
27
|
+
export declare const STYLE_ARCHETYPE_LEAN = 0.3;
|
|
28
|
+
export declare const STYLE_ARCHETYPE_SLIGHT = 0.1;
|
|
29
|
+
/** Weight of an axis that is close to teammates when scoring archetypes; lets a faint lean still point somewhere. */
|
|
30
|
+
export declare const STYLE_EVEN_FACTOR = 0.25;
|
|
31
|
+
export declare const STYLE_ISOLATED_METERS = 150;
|
|
32
|
+
export declare const STYLE_SPACING_BUCKET_SECONDS = 15;
|
|
33
|
+
export declare const STYLE_EARLY_LOOT_SECONDS = 240;
|
|
34
|
+
export declare const STYLE_LATE_PHASE = 5;
|
|
35
|
+
export declare const STYLE_EDGE_RATIO = 0.85;
|
|
36
|
+
export declare const STYLE_MAX_FOOT_STEP_METERS = 400;
|
|
37
|
+
export declare const STYLE_MAX_FOOT_GAP_SECONDS = 30;
|
|
38
|
+
/** Upper edges (metres) of the distance bins used for a damage-weighted median engagement distance. */
|
|
39
|
+
export declare const STYLE_DISTANCE_EDGES: readonly [10, 25, 50, 75, 100, 150, 200, 300];
|
|
40
|
+
/** Upper edges (metres) of the nearest-teammate distance bins. */
|
|
41
|
+
export declare const STYLE_SPACING_EDGES: readonly [20, 50, 100, 150, 250];
|
|
42
|
+
export type WeaponClass = 'AR' | 'SMG' | 'DMR' | 'SR' | 'LMG' | 'SG' | 'Pistol' | 'other';
|
|
43
|
+
export declare function weaponClassOf(weapon: string): WeaponClass;
|
|
44
|
+
/** Damage categories of player-thrown or player-fired explosives and fire. */
|
|
45
|
+
export declare const EXPLOSIVE_DAMAGE: ReadonlySet<string>;
|
|
46
|
+
export interface ThrowableCounts {
|
|
47
|
+
frag: number;
|
|
48
|
+
smoke: number;
|
|
49
|
+
flash: number;
|
|
50
|
+
fire: number;
|
|
51
|
+
}
|
|
52
|
+
/** Raw-telemetry counters for one member of the squad in one match. */
|
|
53
|
+
export interface PlayerRawStyle {
|
|
54
|
+
gunDamage: number;
|
|
55
|
+
/** Rocket, grenade and fire damage to opponents; counts toward damage per minute but not the shooting statistics. */
|
|
56
|
+
explosiveDamage: number;
|
|
57
|
+
headDamage: number;
|
|
58
|
+
/**
|
|
59
|
+
* Aimed shots: gun shots fired inside a fight, leaving out the shots that went into a downed player, with the shots
|
|
60
|
+
* that hurt a standing opponent and their damage. Each shot is paired with its damage by attackId, so one shotgun
|
|
61
|
+
* blast with several pellets is one hit. Fired outside any fight (walls, vehicles, testing, empty air) and finishing
|
|
62
|
+
* shots into a downed player are counted separately instead of as misses.
|
|
63
|
+
*/
|
|
64
|
+
shots: number;
|
|
65
|
+
hits: number;
|
|
66
|
+
hitDamage: number;
|
|
67
|
+
/** Shots, hits and hit damage per weapon class (CLASS_ORDER), so hit rates can be compared on the same weapon mix. */
|
|
68
|
+
classShots: number[];
|
|
69
|
+
classHits: number[];
|
|
70
|
+
classHitDamage: number[];
|
|
71
|
+
/** The first shot of a burst (or a single shot) versus the follow-up bullets of an automatic burst, among the aimed shots. */
|
|
72
|
+
firstShots: number;
|
|
73
|
+
firstHits: number;
|
|
74
|
+
followShots: number;
|
|
75
|
+
followHits: number;
|
|
76
|
+
/** Shots fired with nobody on either side hurt within the engage window. */
|
|
77
|
+
idleShots: number;
|
|
78
|
+
/** Shots that went into a downed opponent. */
|
|
79
|
+
finishingShots: number;
|
|
80
|
+
dealtBins: number[];
|
|
81
|
+
/** Gun damage dealt in the early (circles 1-2), middle (3-4) and late (5+) game. */
|
|
82
|
+
phaseDamage: number[];
|
|
83
|
+
weaponDamage: Record<string, number>;
|
|
84
|
+
spacingBins: number[];
|
|
85
|
+
throwables: ThrowableCounts;
|
|
86
|
+
rides: number;
|
|
87
|
+
healUses: number;
|
|
88
|
+
boostUses: number;
|
|
89
|
+
/** Items picked up in the first minutes after landing. */
|
|
90
|
+
earlyPickups: number;
|
|
91
|
+
/** Distance covered on foot in metres. */
|
|
92
|
+
footMeters: number;
|
|
93
|
+
zoneSamples: number;
|
|
94
|
+
zoneEdgeSamples: number;
|
|
95
|
+
/** Distance in metres from the squad's landing centre; null when the landing is unknown. */
|
|
96
|
+
landingSpread: number | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One pass over a raw payload: engagement distance, weapons and game stage of the damage, spacing from teammates,
|
|
100
|
+
* utility, healing, early looting, movement, circle position, rides and landing spread.
|
|
101
|
+
*/
|
|
102
|
+
export declare function analyzeStyleTelemetry(payload: unknown, trackedIds: ReadonlySet<string>): Record<string, PlayerRawStyle>;
|
|
103
|
+
/** Everything the style model needs to know about one member in one match. */
|
|
104
|
+
export interface PlayerStyleMatch extends PlayerRawStyle {
|
|
105
|
+
minutes: number;
|
|
106
|
+
fights: RoleCounts;
|
|
107
|
+
}
|
|
108
|
+
export declare function emptyFights(): RoleCounts;
|
|
109
|
+
type Vec = Float64Array;
|
|
110
|
+
/** Damage-weighted median engagement distance in metres, interpolated inside the winning bin. */
|
|
111
|
+
export declare function weightedMedianDistance(bins: readonly number[]): number | null;
|
|
112
|
+
export type StyleAxisKey = 'range' | 'farShare' | 'closeShare' | 'marksman' | 'closeGun' | 'precision' | 'firstShot' | 'followShot' | 'burst' | 'tempo' | 'initiative' | 'fragging' | 'lateGame' | 'earlyLoot' | 'revive' | 'utility' | 'supplies' | 'isolation' | 'risk' | 'zoneEdge' | 'foot' | 'mobility' | 'dpm' | 'hitRate' | 'dmgPerShot' | 'knockRate' | 'conversion' | 'combat';
|
|
113
|
+
export type StyleGroup = '战斗效率' | '射击' | '节奏' | '协作与补给' | '位置与风险';
|
|
114
|
+
export interface StyleAxisDefinition {
|
|
115
|
+
key: StyleAxisKey;
|
|
116
|
+
group: StyleGroup;
|
|
117
|
+
label: string;
|
|
118
|
+
high: string;
|
|
119
|
+
low: string;
|
|
120
|
+
/** Derived from other axes (geometric mean of their ratios) instead of measured directly. */
|
|
121
|
+
composite?: readonly StyleAxisKey[];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Axes that make up the fighting-power index and their weights. Chosen on 112 ranked squad matches: damage per
|
|
125
|
+
* minute tracked fight wins and placement best; headshot share was unreliable (split-half 0.45) and unrelated to
|
|
126
|
+
* winning, and knock conversion depends on teammates finishing, so both stay as separate axes only.
|
|
127
|
+
*/
|
|
128
|
+
export declare const COMBAT_WEIGHTS: Readonly<Partial<Record<StyleAxisKey, number>>>;
|
|
129
|
+
export declare const COMBAT_COMPONENTS: readonly StyleAxisKey[];
|
|
130
|
+
export declare const STYLE_AXES: readonly StyleAxisDefinition[];
|
|
131
|
+
/** Raw metric for one axis from a summed vector; null when there is too little data to measure it. */
|
|
132
|
+
export declare function axisValue(key: StyleAxisKey, vector: Vec): number | null;
|
|
133
|
+
export interface StyleInputMatch {
|
|
134
|
+
matchId: string;
|
|
135
|
+
players: Record<string, PlayerStyleMatch>;
|
|
136
|
+
}
|
|
137
|
+
/** stable: the 95% interval excludes parity; lean: the direction holds in most resamples; even: close to teammates. */
|
|
138
|
+
export type StyleTier = 'stable' | 'lean' | 'even' | 'unknown';
|
|
139
|
+
export interface AxisReading {
|
|
140
|
+
key: StyleAxisKey;
|
|
141
|
+
group: StyleGroup;
|
|
142
|
+
label: string;
|
|
143
|
+
value: number | null;
|
|
144
|
+
/** The same metric pooled over the player's teammates. */
|
|
145
|
+
matesValue: number | null;
|
|
146
|
+
/** Player value divided by the teammates' pooled value. */
|
|
147
|
+
ratio: number | null;
|
|
148
|
+
/** 95% bootstrap interval of the ratio across matches. */
|
|
149
|
+
low: number | null;
|
|
150
|
+
high: number | null;
|
|
151
|
+
/** Share of resamples that agree with the direction of the point estimate. */
|
|
152
|
+
confidence: number | null;
|
|
153
|
+
tier: StyleTier;
|
|
154
|
+
direction: 'high' | 'low' | null;
|
|
155
|
+
/** True when the interval excludes 1 (kept for callers that only need a flag). */
|
|
156
|
+
stable: boolean;
|
|
157
|
+
}
|
|
158
|
+
export interface StyleTrait {
|
|
159
|
+
key: StyleAxisKey;
|
|
160
|
+
text: string;
|
|
161
|
+
ratio: number;
|
|
162
|
+
tier: 'stable' | 'lean';
|
|
163
|
+
confidence: number | null;
|
|
164
|
+
}
|
|
165
|
+
/** stable and lean name a type; slight is a faint lean ("偏…"); balanced means close to teammates on everything. */
|
|
166
|
+
export type ArchetypeTier = 'stable' | 'lean' | 'slight' | 'balanced';
|
|
167
|
+
export interface PlayerStyle {
|
|
168
|
+
accountId: string;
|
|
169
|
+
name: string;
|
|
170
|
+
matches: number;
|
|
171
|
+
minutes: number;
|
|
172
|
+
axes: AxisReading[];
|
|
173
|
+
traits: StyleTrait[];
|
|
174
|
+
archetypes: Array<{
|
|
175
|
+
id: string;
|
|
176
|
+
label: string;
|
|
177
|
+
score: number;
|
|
178
|
+
tier: ArchetypeTier;
|
|
179
|
+
}>;
|
|
180
|
+
classShares: Array<{
|
|
181
|
+
weaponClass: WeaponClass;
|
|
182
|
+
share: number;
|
|
183
|
+
}>;
|
|
184
|
+
weapons: Array<{
|
|
185
|
+
weapon: string;
|
|
186
|
+
share: number;
|
|
187
|
+
}>;
|
|
188
|
+
landingSpread: number | null;
|
|
189
|
+
summary: string;
|
|
190
|
+
}
|
|
191
|
+
export interface StyleOverlap {
|
|
192
|
+
accountIds: [string, string];
|
|
193
|
+
names: [string, string];
|
|
194
|
+
similarity: number;
|
|
195
|
+
sharedTraits: string[];
|
|
196
|
+
}
|
|
197
|
+
export interface AxisSpread {
|
|
198
|
+
key: StyleAxisKey;
|
|
199
|
+
group: StyleGroup;
|
|
200
|
+
label: string;
|
|
201
|
+
highest: {
|
|
202
|
+
name: string;
|
|
203
|
+
value: number;
|
|
204
|
+
ratio: number | null;
|
|
205
|
+
tier: StyleTier;
|
|
206
|
+
};
|
|
207
|
+
lowest: {
|
|
208
|
+
name: string;
|
|
209
|
+
value: number;
|
|
210
|
+
ratio: number | null;
|
|
211
|
+
tier: StyleTier;
|
|
212
|
+
};
|
|
213
|
+
/** Highest value divided by lowest value; how differently the squad plays on this axis. */
|
|
214
|
+
spread: number;
|
|
215
|
+
/** True when at least one of the two extremes is a stable or lean difference from teammates. */
|
|
216
|
+
supported: boolean;
|
|
217
|
+
}
|
|
218
|
+
export interface CombatEntry {
|
|
219
|
+
accountId: string;
|
|
220
|
+
name: string;
|
|
221
|
+
rank: number;
|
|
222
|
+
ratio: number | null;
|
|
223
|
+
low: number | null;
|
|
224
|
+
high: number | null;
|
|
225
|
+
confidence: number | null;
|
|
226
|
+
tier: StyleTier;
|
|
227
|
+
components: Array<{
|
|
228
|
+
key: StyleAxisKey;
|
|
229
|
+
label: string;
|
|
230
|
+
ratio: number | null;
|
|
231
|
+
tier: StyleTier;
|
|
232
|
+
}>;
|
|
233
|
+
}
|
|
234
|
+
/** Shots to hits to knocks to kills for one member, summed over matches. */
|
|
235
|
+
export interface FunnelEntry {
|
|
236
|
+
accountId: string;
|
|
237
|
+
name: string;
|
|
238
|
+
fights: number;
|
|
239
|
+
minutes: number;
|
|
240
|
+
/** Aimed shots (inside fights, not into downed players) and the ones that hurt a standing opponent. */
|
|
241
|
+
shots: number;
|
|
242
|
+
hits: number;
|
|
243
|
+
hitRate: number | null;
|
|
244
|
+
/** Hit rate of the first shot of a burst (or a single shot) and of the follow-up bullets of an automatic burst. */
|
|
245
|
+
firstShotRate: number | null;
|
|
246
|
+
followShotRate: number | null;
|
|
247
|
+
/** Share of aimed shots that were follow-up bullets of a burst. */
|
|
248
|
+
burstShare: number | null;
|
|
249
|
+
/** Shots fired with nobody hurt around them, as a share of all shots that were not finishing shots. */
|
|
250
|
+
idleShare: number | null;
|
|
251
|
+
/** Shots into downed opponents, as a share of all shots. */
|
|
252
|
+
finishingShare: number | null;
|
|
253
|
+
hitDamage: number;
|
|
254
|
+
damagePerShot: number | null;
|
|
255
|
+
damagePerMinute: number | null;
|
|
256
|
+
knocks: number;
|
|
257
|
+
hitsPerKnock: number | null;
|
|
258
|
+
kills: number;
|
|
259
|
+
knockFights: number;
|
|
260
|
+
knockRate: number | null;
|
|
261
|
+
chainsDealt: number;
|
|
262
|
+
chainsFinished: number;
|
|
263
|
+
conversion: number | null;
|
|
264
|
+
}
|
|
265
|
+
export interface CombatHighlight {
|
|
266
|
+
name: string;
|
|
267
|
+
label: string;
|
|
268
|
+
ratio: number;
|
|
269
|
+
tier: 'stable' | 'lean';
|
|
270
|
+
confidence: number | null;
|
|
271
|
+
}
|
|
272
|
+
export interface SquadStyle {
|
|
273
|
+
schemaVersion: typeof STYLE_SCHEMA_VERSION;
|
|
274
|
+
ruleVersion: typeof STYLE_RULE_VERSION;
|
|
275
|
+
matches: number;
|
|
276
|
+
players: PlayerStyle[];
|
|
277
|
+
/** One sentence on who fights best, or that the squad cannot be separated on the overall index. */
|
|
278
|
+
combatVerdict: string;
|
|
279
|
+
/** Component-level strengths and weaknesses that are stable or lean, strongest first. */
|
|
280
|
+
combatHighlights: CombatHighlight[];
|
|
281
|
+
combat: CombatEntry[];
|
|
282
|
+
funnel: FunnelEntry[];
|
|
283
|
+
spreads: AxisSpread[];
|
|
284
|
+
overlaps: StyleOverlap[];
|
|
285
|
+
gaps: string[];
|
|
286
|
+
notes: string[];
|
|
287
|
+
}
|
|
288
|
+
export declare function mulberry32(seed: number): () => number;
|
|
289
|
+
export declare function percentile(sorted: readonly number[], fraction: number): number;
|
|
290
|
+
export declare function tierFor(ratio: number | null, low: number | null, high: number | null, confidence: number | null): {
|
|
291
|
+
tier: StyleTier;
|
|
292
|
+
direction: 'high' | 'low' | null;
|
|
293
|
+
};
|
|
294
|
+
export interface BuildSquadStyleInput {
|
|
295
|
+
matches: readonly StyleInputMatch[];
|
|
296
|
+
names: ReadonlyMap<string, string>;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* One style profile per member: nineteen measurable axes, each expressed as a ratio to the player's teammates
|
|
300
|
+
* (excluding the player) with a bootstrap interval over matches. Differences are graded stable, lean or even,
|
|
301
|
+
* so a squad that plays alike still gets honest, ranked tendencies instead of an empty card.
|
|
302
|
+
*/
|
|
303
|
+
export declare function buildSquadStyle(input: BuildSquadStyleInput): SquadStyle;
|
|
304
|
+
export {};
|