diff --git a/system/backend/tests/oskiewar-jev.test.mjs b/system/backend/tests/oskiewar-jev.test.mjs index 1abc4136e..3d1cc7ceb 100644 --- a/system/backend/tests/oskiewar-jev.test.mjs +++ b/system/backend/tests/oskiewar-jev.test.mjs @@ -74,3 +74,24 @@ test('Jev chooses from usable attacks after dismemberment',()=>{ assert.match(choices.punch,/Spit/);assert.match(choices.kick,/Spit/); assert.equal(choices.block,undefined); }); +test('crouch and aerial attacks are timed sequences with separate button edges',()=>{ + const low=controlPlan('still','low_kick'); + assert.deepEqual(controlsAt(low,0),['ArrowDown']); + assert.deepEqual(controlsAt(low,120),['ArrowDown','A']); + assert.deepEqual(controlsAt(low,300),['ArrowDown']); + assert.deepEqual(controlsAt(low,700),[]); + const jump=controlPlan('right','jump_punch'); + assert.deepEqual(controlsAt(jump,0),['ArrowRight','ArrowUp']); + assert.deepEqual(controlsAt(jump,260),['ArrowRight','ArrowUp','B']); + assert.ok(jump.releaseMs>=524,'next command waits for the delayed attack recovery'); +}); +test('bounded box evidence and movement estimates survive observation normalization',()=>{ + const value=cleanScene({self:{x:100,y:200,vx:0},opponent:{x:200,y:200,dx:100,dy:0,vx:-100,ducking:true,headOnly:true}, + strikes:{low_kick:{canHit:true,headshot:true,clearance:0,startupMs:133,totalMs:434,private:'SECRET'}}, + options:[{kind:'jump',reach:350,cost:80,landLeft:20,landRight:100}]}); + assert.equal(value.relative.predictedDx200ms,80); + assert.equal(value.opponent.headOnly,true); + assert.equal(value.strikes.low_kick.canHit,true); + assert.equal(value.options[0].reach,350); + assert.doesNotMatch(JSON.stringify(value),/SECRET|private/); +}); diff --git a/xbox/live/jev-vs-jev/README.md b/xbox/live/jev-vs-jev/README.md index 178f5c944..653e98739 100644 --- a/xbox/live/jev-vs-jev/README.md +++ b/xbox/live/jev-vs-jev/README.md @@ -14,6 +14,15 @@ neutral input; stale responses and old-round responses are discarded. Transient provider failures leave a fighter neutral while it requests a fresh decision; three consecutive failures stop the match. +Combat now uses rectangular hurtboxes, active attack boxes and guard boxes. Tab +shows those same collision boxes. Punches have 5 startup / 3 active / 9 recovery +frames; kicks have 8 / 4 / 14. Recovery cannot be canceled by another strike. +Crouch-punch, low-kick, crouch-block and timed jump-attack sequences are available. +Each observation includes box-based strike reach probes, posture and remaining +recovery. The probes hold positions fixed; the 200 ms velocity estimate is only +an estimate, not a simulated future. A bounding-volume tree narrows collision +and nearby-platform queries. Full combo planning and hitstop remain future work. + The page shows separate provider-reported cost, input/output tokens, decision counts, and browser round-trip latency. Simulation stays at its normal rate while decisions arrive asynchronously. It is not frame-by-frame inference. diff --git a/xbox/live/jev-vs-jev/demo.mjs b/xbox/live/jev-vs-jev/demo.mjs index c9c0be43a..c0083bb0f 100644 --- a/xbox/live/jev-vs-jev/demo.mjs +++ b/xbox/live/jev-vs-jev/demo.mjs @@ -47,7 +47,8 @@ async function drive(seat, session) { let releaseMs = 210; pending++; try { - const result = await post({ ticket: session, seat, scene: f.scene }); + const scene = { ...f.scene, strikes: f.scene.strikeOptions?.() }; + const result = await post({ ticket: session, seat, scene }); f.failures = 0; // Account for successful requests even when Stop was pressed in flight. f.count++; f.cost += result.usage.costUsd; f.input += result.usage.inputTokens; f.output += result.usage.outputTokens; diff --git a/xbox/live/jev-vs-jev/model.mjs b/xbox/live/jev-vs-jev/model.mjs index bea954cf6..0ffe084c4 100644 --- a/xbox/live/jev-vs-jev/model.mjs +++ b/xbox/live/jev-vs-jev/model.mjs @@ -11,6 +11,11 @@ export const motion = { export const actions = { kick: 'Attack with A: kick, reach about 165 units. Can kick while moving toward the opponent.', punch: 'Attack with B: punch, reach about 130 units. Can punch while moving toward the opponent.', block: 'Shield (X); cannot move or attack while shielding', jump: 'Jump (up)', duck: 'Crouch (down)', + low_kick: 'Crouch, then kick while staying low. Sweeps feet or a detached head near the floor.', + crouch_punch: 'Crouch, then punch while staying low. Lower strike than a standing punch.', + crouch_block: 'Crouch and shield together against a low attack.', + jump_kick: 'Jump, then kick in the air. With left/right motion this travels across the opponent.', + jump_punch: 'Jump, then punch in the air. Choose the direction for an aerial approach or crossover.', drop: 'Double tap down: drop through the platform you stand on to reach an opponent below, or ground pound while airborne', item: 'Use held item (Y)', wait: 'No action button' }; export function decisionRequest(scene) { @@ -22,12 +27,15 @@ export function decisionRequest(scene) { criteria.kick = 'Spit a fast projectile with A toward the opponent.'; criteria.punch = 'Spit a heavy projectile with B toward the opponent.'; delete criteria.block; + for (const id of ['low_kick','crouch_punch','crouch_block','jump_kick','jump_punch']) delete criteria[id]; } else { - if (!combat.punch) delete criteria.punch; + if (!combat.punch) for (const id of ['punch','crouch_punch','jump_punch']) delete criteria[id]; const side = state.relative?.opponentSide || (state.self.facing < 0 ? 'left' : 'right'); - if (!(side === 'left' ? combat.kickLeft : combat.kickRight)) delete criteria.kick; + if (!(side === 'left' ? combat.kickLeft : combat.kickRight)) + for (const id of ['kick','low_kick','jump_kick']) delete criteria[id]; if (combat.pogo) { delete criteria.punch; delete criteria.kick; + for (const id of ['low_kick','crouch_punch','crouch_block','jump_kick','jump_punch']) delete criteria[id]; criteria.duck = 'Pogo dive: while airborne press down to attack the opponent below.'; } } @@ -39,8 +47,15 @@ export function decisionRequest(scene) { 'Fight actively: close the gap, face the opponent, and punch or kick repeatedly when near. ' + 'At distance under 100, stay still if facing the opponent, or choose a face tap if facing away; attack instead of walking through them. ' + 'At distance 100 to 210, use a short step and attack together. At larger gaps, walk toward them. ' + - 'Attacks last 220 ms, so a strike while closing can connect even if just outside its range now. ' + - 'Use self.combat to avoid attacks with missing limbs. Prefer an available punch or kick over waiting. ' + + 'Punch takes 5 startup frames, 3 active frames and 9 recovery frames; kick takes 8/4/14 at 60 Hz. Only active hitboxes deal damage. ' + + 'strikes tests real attack boxes against current hurtboxes, assuming you face the opponent at your current position. canHit is geometric reach, not a guaranteed future hit. ' + + 'Choose an available strike with canHit=true when near. If standing strikes miss low, use low_kick or crouch_punch. ' + + 'Against a head on the ground, prefer a low kick whose box reaches it. Crouch_block handles low threats. ' + + 'Plan a short sequence: jump_kick or jump_punch combines a leap, travel and delayed aerial attack. Cross over a defensive opponent, then turn to attack on the next decision. ' + + 'Read opponent velocity, predictedDx200ms and recoveryMs: intercept where they are going or approach during recovery rather than chase an old position. Predictions assume constant velocity. ' + + 'Use self.combat to avoid attacks with missing limbs. If every strikes entry has canHit=false, change position or posture instead of repeating a missed attack. ' + + 'A missing left or right leg can remove the low kick toward that side: jump across the opponent, turn around, and use the surviving leg. ' + + 'When you are headOnly, A/B spit horizontally: jump or change platforms to align your shots with the opponent. ' + 'Do not jump just because an airborne opponent is passing overhead: wait on the ground for them to land and strike. ' + 'Jump to reach a grounded opponent on a higher platform, not as a default dodge. ' + 'Shield briefly only against an imminent strike. Shielding and retreating do not deal damage. ' + @@ -53,37 +68,62 @@ export function decisionRequest(scene) { } const number = value => Number.isFinite(value) ? Math.max(-100000, Math.min(100000, Math.round(value))) : 0; const point = value => Object.fromEntries(['x','y','vx','vy','dx','dy','distance','facing','left','right','level','aim','takeoffLeft','takeoffRight','landLeft','landRight'] + .concat(['reach','cost','attackFrame','recoveryMs']) .filter(key => Number.isFinite(value?.[key])).map(key => [key, number(value[key])])); export function cleanScene(scene) { if (!scene?.self || !Number.isFinite(scene.self.x) || !Number.isFinite(scene.self.y)) throw new Error('Invalid fighter observation'); const dx = Number.isFinite(scene.opponent?.dx) ? scene.opponent.dx : 0; const dy = Number.isFinite(scene.opponent?.dy) ? scene.opponent.dy : 0; return { relative: scene.opponent ? { opponentSide: dx < 0 ? 'left' : 'right', + predictedDx200ms: number(dx + ((scene.opponent.vx || 0) - (scene.self.vx || 0)) * .2), opponentLevel: dy > 120 ? 'above' : dy < -120 ? 'below' : 'same', punchInRange: Math.abs(dx) < 130 && Math.abs(dy) < 90, kickInRange: Math.abs(dx) < 165 && Math.abs(dy) < 90 } : null, - self: { ...point(scene.self), grounded: scene.self.grounded === true, + self: { ...point(scene.self), grounded: scene.self.grounded === true, ducking: scene.self.ducking === true, footing: scene.self.footing ? point(scene.self.footing) : null, combat: scene.self.combat ? Object.fromEntries(['punch','kickLeft','kickRight','item','stunned','headOnly','pogo'].map(key => [key, scene.self.combat[key] === true])) : null }, - opponent: scene.opponent ? { ...point(scene.opponent), grounded: scene.opponent.grounded === true, attacking: scene.opponent.attacking === true } : null, + opponent: scene.opponent ? { ...point(scene.opponent), ...Object.fromEntries( + ['grounded','attacking','ducking','headOnly','pogo','blocking'].map(k=>[k,scene.opponent[k]===true])) } : null, + strikes: Object.fromEntries(['punch','kick','low_kick','crouch_punch'].filter(k=>scene.strikes?.[k]).map(k=>[k,{ + canHit:scene.strikes[k].canHit===true, headshot:scene.strikes[k].headshot===true, + clearance:Number.isFinite(scene.strikes[k].clearance)?number(scene.strikes[k].clearance):null, + facing:number(scene.strikes[k].facing), startupMs:number(scene.strikes[k].startupMs), totalMs:number(scene.strikes[k].totalMs), + }])), floor: scene.floor ? point(scene.floor) : null, rungs: (Array.isArray(scene.rungs) ? scene.rungs : []).slice(0, 8).map(point), options: (Array.isArray(scene.options) ? scene.options : []).slice(0, 8).map(o => ({ ...point(o), kind: ['walk','jump','sink'].includes(o.kind) ? o.kind : 'walk' })) }; } +const actionButtons = { + kick:['A'], punch:['B'], block:['X'], jump:['ArrowUp'], duck:['ArrowDown'], + drop:['ArrowDown'], item:['Y'], wait:[], low_kick:['ArrowDown','A'], + crouch_punch:['ArrowDown','B'], crouch_block:['ArrowDown','X'], + jump_kick:['ArrowUp','A'], jump_punch:['ArrowUp','B'], +}; export function buttons(move, action) { if (!Object.hasOwn(motion, move) || !Object.hasOwn(actions, action)) throw new Error('Invalid controller choice'); return [move.endsWith('left') ? 'ArrowLeft' : move.endsWith('right') ? 'ArrowRight' : null, - { kick:'A', punch:'B', block:'X', jump:'ArrowUp', duck:'ArrowDown', drop:'ArrowDown', item:'Y' }[action]].filter(Boolean); + ...actionButtons[action]].filter(Boolean); } export function controlPlan(move, action) { const down = buttons(move, action); - const motionMs = move === 'still' ? 0 : move.startsWith('face_') ? 20 : move.startsWith('step_') ? 55 : 180; - const actionMs = action === 'jump' ? 450 : action === 'drop' ? 220 : action === 'wait' ? 0 : 150; - return { down, motionMs, actionMs, actionWindows: action === 'drop' ? [[0,60],[130,220]] : [[0,actionMs]], - releaseMs: Math.max(motionMs, actionMs, 150) + 60 }; + const aerial = action.startsWith('jump_'); + const low = action === 'low_kick' || action === 'crouch_punch'; + const motionMs = move === 'still' ? 0 : move.startsWith('face_') ? 20 + : move.startsWith('step_') ? 55 : aerial ? 450 : 180; + const actionMs = action === 'jump' || aerial ? 450 : action === 'drop' ? 220 + : action === 'wait' ? 0 : low ? 550 : action === 'duck' || action === 'crouch_block' ? 300 : 150; + const presses = down.map(key=>{ + const direction = key === 'ArrowLeft' || key === 'ArrowRight'; + const strike = key === 'A' || key === 'B'; + const windows = direction ? [[0,motionMs]] : action === 'drop' ? [[0,60],[130,220]] + : low && strike ? [[100,250]] : aerial && strike ? [[240,390]] : [[0,actionMs]]; + return {key,windows}; + }); + const recoveryMs = action.includes('kick') ? 434 : action.includes('punch') ? 284 : 0; + return { down, motionMs, actionMs, presses, + releaseMs: Math.max(motionMs, actionMs, recoveryMs+(low?100:aerial?240:0), 150)+60 }; } export function controlsAt(plan, elapsed) { if (!plan || elapsed < 0) return []; - return plan.down.filter(key => key === 'ArrowLeft' || key === 'ArrowRight' - ? elapsed < plan.motionMs : plan.actionWindows.some(([from,to])=>elapsed >= from && elapsed < to)); + return plan.presses.filter(p=>p.windows.some(([from,to])=>elapsed>=from && elapsedp.key); } diff --git a/xbox/live/oskiewar.js b/xbox/live/oskiewar.js index b180061f0..d2369a733 100644 --- a/xbox/live/oskiewar.js +++ b/xbox/live/oskiewar.js @@ -81,7 +81,7 @@ if (hostAnalytics) }; // Monotonic count of committed revisions to this piece (next revision included). -const buildVersion = 131; +const buildVersion = 132; const floorY = 1800; // Oskiewar now opens as a versus game. An ordinary web visit hosts a room — // the URL becomes the invitation — and until a friend opens it, all you can @@ -526,16 +526,16 @@ const meleeSpecFor = (player, kind) => { }; const meleeSpecs = { PUNCH: { reach: 58, swell: 50, span: 58, height: 115, radius: 28, - windowUs: 220000, force: 1200, lift: 140, + windowUs: 17 * 16667, force: 1200, lift: 140, cue: ["snare", 1.05], thud: ["block", 1] }, KICK: { reach: 75, swell: 62, span: 74, height: 55, radius: 35, - windowUs: 220000, force: 1550, lift: 220, + windowUs: 26 * 16667, force: 1550, lift: 220, cue: ["kick", 1.05], thud: ["block", 1] }, WHIP: { reach: 92, swell: 74, span: 76, height: 122, radius: 24, - windowUs: 190000, force: 1000, lift: 110, + windowUs: 15 * 16667, force: 1000, lift: 110, cue: ["whoosh", 1.15], thud: ["hat", 1.35] }, BASH: { reach: 62, swell: 40, span: 58, height: 108, radius: 40, - windowUs: 280000, force: 1750, lift: 210, + windowUs: 28 * 16667, force: 1750, lift: 210, cue: ["kick", 1.3], thud: ["kick", 1.4] }, }; // One lookup serves both Y and the loaded punch, so the thing you can see in @@ -1812,17 +1812,9 @@ let debugHitboxes = false; // those mean HERE is a question about this game rather than that one, and the // honest answers are not all flattering: // -// startup — structurally zero. `startMelee` sets `attackUntil` and -// `resolveMelee` gates on nothing but `now < attackUntil`, so a -// strike is live on the frame it is thrown. The meter computes -// the phase anyway, so the day an anticipation window is added -// it lights up on its own rather than needing to be remembered. -// active — the swing can still connect: inside the window, nothing hit. -// recovery — the swing is spent. `attackHit` makes a strike land once, so -// the rest of its window is a limb hanging out that cannot hurt -// anybody, which is exactly what recovery is and exactly what a -// player needs to see to know they are being punished for it. -// stun — `hitStunUntil`, hit or shield-broken alike. +// Startup, active and recovery come from the same integer-frame table as +// the collision sampler. A landed strike remains in recovery until its +// original action deadline. Stun still takes precedence over the action. // // Shielding gets a color of its own because holding a shield is a stance in // this game rather than a reaction, and folding it into stun would say @@ -1846,18 +1838,12 @@ function frameMeterState(player, now) { if (now < player.hitStunUntil) return "stun"; if (player.attackKind && now < player.attackUntil) { if (player.attackHit) return "recovery"; - // Kept for the day a startup window exists. `meleeActiveFrom` is zero - // today, so this never fires and the meter tells the truth about that. - if (now < player.attackStartedAt + meleeActiveFrom) return "startup"; - return "active"; + return meleeFrame(player, now).phase; } if (player.blocking) return "shield"; if (!player.grounded) return "airborne"; return "neutral"; } -// Zero, and named rather than absent, so the absence is a decision somebody -// can find instead of a gap somebody has to infer. -const meleeActiveFrom = 0; function recordFrameMeter(now) { if (!debugHitboxes) return; for (const player of players) { @@ -7106,8 +7092,9 @@ function updateBullets(dt, now, combat = true) { // Flipping `owner` lets the returned shot hurt whoever fired it. if (target.blocking) { const shield = shieldGeometry(target); - if (Math.hypot(bullet.x - shield.x, bullet.y - shield.y, - bullet.z - shield.z) <= shield.radius + 24) { + const guard = sampleCombatBoxes(target,now).guard[0]; + if (guard && segmentBoxEntry({x1:bullet.previousX??bullet.x,y1:bullet.previousY??bullet.y, + z1:bullet.z,x2:bullet.x,y2:bullet.y,z2:bullet.z},guard,24)!==null) { let nx = bullet.x - shield.x; let ny = bullet.y - shield.y; const normalLength = Math.hypot(nx, ny); @@ -7133,7 +7120,7 @@ function updateBullets(dt, now, combat = true) { continue; } } - const contact = attackCapsuleContact([{ + const contact = sweptProjectileContact([{ x1: bullet.previousX ?? bullet.x, y1: bullet.previousY ?? bullet.y, z1: bullet.z, x2: bullet.x, y2: bullet.y, z2: bullet.z, width: 48, role: "bullet", part: "bullet", @@ -7259,6 +7246,7 @@ function updateGrenades(dt, now, combat = true) { function startMelee(player, kind, now) { if (isHeadOnly(player) || isPogo(player)) return; + if (player.attackKind && now < player.attackUntil) return; const spec = meleeSpecs[kind]; if (!spec) return; const attackingPart = kind === "KICK" @@ -7308,9 +7296,27 @@ const itemSwinging = (player, now) => function meleePulse(player, now) { if (now >= player.attackUntil || player.attackUntil <= player.attackStartedAt) return 0; - const phase = (now - player.attackStartedAt) / - (player.attackUntil - player.attackStartedAt); - return Math.sin(Math.max(0, Math.min(1, phase)) * Math.PI); + const { frame, startup, active, recovery, phase } = meleeFrame(player, now); + if (phase === 'startup') return .25 * frame / startup; + if (phase === 'active') return 1; + return Math.max(0, 1 - (frame - startup - active) / recovery); +} + +// Authored gameplay windows. Frame 1 is the accepted input frame; drawing +// may interpolate, but no collision exists in startup or recovery. +const meleeFrames = { + PUNCH: { startup: 5, active: 3, recovery: 9 }, + KICK: { startup: 8, active: 4, recovery: 14 }, + WHIP: { startup: 4, active: 3, recovery: 8 }, + BASH: { startup: 8, active: 4, recovery: 16 }, +}; +function meleeFrame(player, now) { + const timing = meleeFrames[player.attackKind]; + if (!timing || now < player.attackStartedAt || now >= player.attackUntil) + return { frame: 0, phase: 'neutral', startup: 0, active: 0, recovery: 0 }; + const frame = Math.floor((now - player.attackStartedAt) / replayTickUs + 1e-7) + 1; + return { ...timing, frame, phase: frame <= timing.startup ? 'startup' + : frame <= timing.startup + timing.active ? 'active' : 'recovery' }; } function meleeTarget(player, now) { @@ -7326,7 +7332,8 @@ function meleeTarget(player, now) { return { x: player.x + player.facing * (spec.reach + spec.swell * pulse + (lowKick ? 34 * pulse : 0)), - y: lowKick ? sweepY : player.y - spec.height, + y: lowKick ? sweepY : player.y - (player.attackKind !== 'KICK' && + (player.ducking || player.crouchBlend > .35) ? 68 : spec.height), z: player.z, }; } @@ -7634,13 +7641,12 @@ function updateBall(ball, dt, now) { if (!player.alive || ((ball.safePlayers & (1 << player.pad)) && now < ball.safeUntil)) continue; - if (!player.attackHit && now < player.attackUntil) { - const strike = meleeStrike(player, now); - const distance = Math.hypot(ball.x - strike.x, ball.y - strike.y, - ball.z - strike.z); - if (distance <= ball.radius + strike.radius) - hitters.push({ player, contact: clamp(1 - distance / - (ball.radius + strike.radius), 0, 1) }); + const boxes = sampleCombatBoxes(player, now); + for (const strike of boxes.hit) { + const distance = pointBoxDistance(strike, ball.x, ball.y, ball.z); + if (distance <= ball.radius) { + hitters.push({ player, contact: clamp(1-distance/ball.radius,0,1) }); break; + } } } if (hitters.length >= 2) { @@ -7657,24 +7663,21 @@ function updateBall(ball, dt, now) { now < ball.safeUntil)) continue; if (player.blocking) { - const shield = shieldGeometry(player); - const centerDistance = Math.hypot(ball.x - shield.x, ball.y - shield.y, - ball.z - shield.z); - const surfaceDistance = Math.max(0, centerDistance - ball.radius); - if (surfaceDistance <= shield.radius) { - const proximity = clamp(1 - surfaceDistance / shield.radius, 0, 1); + const guard = sampleCombatBoxes(player, now).guard[0]; + const distance = guard ? pointBoxDistance(guard, ball.x, ball.y, ball.z) : Infinity; + if (distance <= ball.radius) { + const shield = shieldGeometry(player); + const proximity = clamp(1-Math.max(0,Math.hypot(ball.x-shield.x, + ball.y-shield.y,ball.z-shield.z)-ball.radius)/shield.radius,0,1); returnBall(ball, player, now, true, proximity); return; } } - const geometry = runnerWorldGeometry(player, poseTime); - const currentHeadDistance = Math.max(0, Math.hypot( - ball.x - geometry.head.x, ball.y - geometry.head.y, - ball.z - geometry.head.z) - geometry.head.radius); - const sweptHeadDistance = Math.max(0, pointSegmentDistance( - geometry.head.x, geometry.head.y, geometry.head.z, + const headBox = sampleCombatBoxes(player,now).hurt.find(b=>b.part==='head'); + const currentHeadDistance = pointBoxDistance(headBox,ball.x,ball.y,ball.z); + const sweptHeadDistance = segmentBoxEntry( { x1: previous.x, y1: previous.y, z1: previous.z, - x2: ball.x, y2: ball.y, z2: ball.z }) - geometry.head.radius); + x2: ball.x, y2: ball.y, z2: ball.z },headBox,ball.radius)!==null ? 0 : Infinity; const headDistance = Math.min(currentHeadDistance, sweptHeadDistance); const bodyContact = runnerContactToPoint(player, poseTime, ball.x, ball.y, ball.z); @@ -7940,27 +7943,25 @@ function groundPound(player, now) { function resolveMelee(now) { const poseTime = (now - startedAt) / 1000000; const contacts = []; + const samples = players.map(player => sampleCombatBoxes(player, now)); for (const attacker of players) { - if (!attacker.alive || attacker.attackHit || now >= attacker.attackUntil) continue; - const attackingLimbs = runnerWorldGeometry(attacker, poseTime).segments - .filter((segment) => segment.role?.startsWith("attack-")); + const attacking = samples[attacker.pad]; + if (!attacker.alive || !attacking.hit.length) continue; for (const fragment of detachedParts) { - let closest = null; - for (const limb of attackingLimbs) { - const candidate = segmentSegmentClosest(limb, fragment); - const separation = candidate.distance - (limb.width + fragment.width) / 2; - if (!closest || separation < closest.separation) - closest = { ...candidate, separation }; - } - if (!closest || closest.separation > 3) continue; + const r = fragment.width/2; + const bounds = combatRect('fragment',Math.min(fragment.x1,fragment.x2)-r, + Math.min(fragment.y1,fragment.y2)-r,Math.max(fragment.x1,fragment.x2)+r, + Math.max(fragment.y1,fragment.y2)+r,(fragment.z1+fragment.z2)/2, + Math.abs(fragment.z2-fragment.z1)/2+r); + if (!attacking.hit.some(hit=>boxesOverlap(hit,bounds))) continue; const spec = meleeSpecFor(attacker, attacker.attackKind); fragment.vx += attacker.facing * spec.force * .8; fragment.vy -= Math.max(220, spec.lift); fragment.owner = attacker.pad; fragment.hitAfter = now + 120000; attacker.attackHit = true; - spawnImpact({ x: closest.secondPoint.x, y: closest.secondPoint.y, - z: closest.secondPoint.z, life: .18, duration: .18, + spawnImpact({ x: (bounds.left+bounds.right)/2, y: (bounds.top+bounds.bottom)/2, + z: (bounds.near+bounds.far)/2, life: .18, duration: .18, death: false, explosion: false }); playDrum("clap", .82, panPlayer(attacker)); emitSignal("part-hit", attacker.pad, -1, spec.force); @@ -7969,7 +7970,7 @@ function resolveMelee(now) { if (attacker.attackHit) continue; const target = players[attacker.pad === 0 ? 1 : 0]; if (!target.alive) continue; - const contact = meleeLimbContact(attacker, target, poseTime); + const contact = combatBoxContact(attacking, samples[target.pad]); if (contact?.separation <= 3) { attacker.attackHit = true; contacts.push({ attacker, target, @@ -8047,15 +8048,9 @@ function resolvePogoAttacks(now) { for (const attacker of players) { if (!attacker.alive || !isPogo(attacker) || attacker.grounded || attacker.pogoHit) continue; - const geometry = runnerWorldGeometry(attacker, poseTime); - const torso = geometry.segments.find((segment) => segment.role === "torso"); - if (!torso) continue; - const bottom = { x1: torso.x2, y1: torso.y2, z1: torso.z2, - x2: torso.x2, y2: torso.y2, z2: torso.z2, - width: torso.width + 6, role: "attack-pogo", part: "torso" }; const target = players[attacker.pad === 0 ? 1 : 0]; if (!target.alive) continue; - const contact = attackCapsuleContact([bottom], target, poseTime); + const contact = combatBoxContact(sampleCombatBoxes(attacker,now),sampleCombatBoxes(target,now)); if (!contact || contact.separation > 3) continue; attacker.pogoHit = true; attacker.vy = Math.min(attacker.vy, -985); @@ -8074,8 +8069,8 @@ function resolvePogoAttacks(now) { function resolvePlayerPushboxes() { if (!players[0].alive || !players[1].alive) return; const poseTime = (runtime().monotonicUs - startedAt) / 1000000; - const firstBounds = runnerBounds(players[0], poseTime); - const secondBounds = runnerBounds(players[1], poseTime); + const firstBounds = combatPushbox(players[0]); + const secondBounds = combatPushbox(players[1]); const verticalOverlap = Math.min(firstBounds.bottom, secondBounds.bottom) - Math.max(firstBounds.top, secondBounds.top); // Grounded fighters nudge one another. Once a jumper is clearly above the @@ -8085,7 +8080,7 @@ function resolvePlayerPushboxes() { Math.abs(players[0].y - players[1].y) > 58)) return; const left = players[0].x <= players[1].x ? players[0] : players[1]; const right = left === players[0] ? players[1] : players[0]; - const pushRadius = (player) => isHeadOnly(player) ? 24 : isPogo(player) ? 38 : 69; + const pushRadius = (player) => (combatPushbox(player).right-combatPushbox(player).left)/2; const minimumGap = pushRadius(left) + pushRadius(right); const overlap = minimumGap - (right.x - left.x); if (overlap <= 0) return; @@ -8480,7 +8475,7 @@ function updatePlayer(player, pad, dt, now) { // A broken shield stays down until X is let go, so the opening it bought is // spent on attacking rather than on re-guarding by reflex. if (player.shieldLocked && !pad.down.includes("X")) player.shieldLocked = false; - player.blocking = !carrying && !headOnly && pad.down.includes("X") && + player.blocking = !carrying && !headOnly && !(player.attackKind && now < player.attackUntil) && pad.down.includes("X") && !player.shieldLocked; if (player.blocking && !wasBlocking) { player.shieldCrouched = rawInput.vertical < 0 || player.ducking || @@ -9146,7 +9141,13 @@ function botOptions(player, scene) { options.push({ kind: "walk", level: footing.level, y: footing.y, left: footing.left, right: footing.right }); const inset = survivalTune().landingInset; - for (const rung of scene.rungs) { + const visible = new Set(scene.rungs.map(r=>r.level)); + const maxReach = jumpReach(0); + const nearby = queryBoxTree(platformBoxTree(), combatRect('jump-window', + footing.left-maxReach, footing.y-jumpApex(), footing.right+maxReach, footing.y)); + for (const box of nearby) { + const rung = box.ledge; + if (!visible.has(rung.level)) continue; const dy = footing.y - rung.y; if (dy <= 0 || dy > jumpApex()) continue; const landLeft = rung.left + inset; @@ -9178,6 +9179,17 @@ function botOptions(player, scene) { return options; } +let platformTreeSource = null, platformTreeRevision = -1, platformTree = null; +function platformBoxTree() { + const ledges = activeLedges(); + if (platformTreeSource !== ledges || platformTreeRevision !== workshopRevision) { + platformTreeSource = ledges; platformTreeRevision = workshopRevision; + platformTree = buildBoxTree(ledges.map(ledge => combatRect('platform-'+ledge.level, + ledge.left,ledge.y,ledge.right,ledge.y+12,0,18,{ledge}))); + } + return platformTree; +} + // The climb's subgoal: the highest deck one jump reaches from this footing, // the nearest of them when two tie. On the ladder that is the deck above — // two decks is 470 and the apex is 322 — but the choice is made from the @@ -9195,6 +9207,9 @@ function highestJump(options) { function botPad(player, opponent, now) { if (selfPlay && typeof globalThis.__oskiewarJevPad === 'function') { const scene = botScene(player, opponent, now); + scene.self.ducking = player.ducking; + scene.self.attackFrame = meleeFrame(player, now).frame; + scene.self.recoveryMs = Math.max(0, (player.attackUntil-now)/1000); scene.self.combat = { punch: Boolean(availableArm(player)), kickLeft: hasPart(player, 'left-leg'), kickRight: hasPart(player, 'right-leg'), @@ -9204,6 +9219,16 @@ function botPad(player, opponent, now) { if (scene.opponent) { scene.opponent.grounded = opponent.grounded; scene.opponent.vx = opponent.vx; scene.opponent.vy = opponent.vy; + scene.opponent.ducking = opponent.ducking; + scene.opponent.headOnly = isHeadOnly(opponent); + scene.opponent.pogo = isPogo(opponent); + scene.opponent.blocking = opponent.blocking; + scene.opponent.attackFrame = meleeFrame(opponent, now).frame; + scene.opponent.recoveryMs = Math.max(0, (opponent.attackUntil-now)/1000); + // The parent calls this only when preparing a model request, not every + // simulation tick. Probes read clones and never advance the live fight. + scene.strikeOptions = () => jevStrikeOptions(player, opponent, + runtime().simMonotonicUs || runtime().monotonicUs); } const down = globalThis.__oskiewarJevPad(player.pad, { ...scene, round: matchName, alive: player.alive && opponent.alive }); @@ -10215,8 +10240,10 @@ function fighterAnimationPhase(player, now = null) { } else if (Math.abs(player.vx) > 40) { state = "WALK"; } - const [steps, authoredTicksPerStep, basePhase, loop] = + const [authoredSteps, authoredTicksPerStep, basePhase, loop] = fighterAnimationSpecs[state] || fighterAnimationSpecs.IDLE; + const timing = meleeFrames[state]; + const steps = timing ? timing.startup+timing.active+timing.recovery : authoredSteps; // Descending terrain advances planted-foot exchanges faster. The result is // still integer-tick animation, but the legs keep pace with downhill speed // instead of the body skating through a leisurely flat-ground cycle. @@ -10233,8 +10260,8 @@ function fighterAnimationPhase(player, now = null) { const rawStep = Math.floor(rawTick / ticksPerStep); const step = loop ? rawStep % steps : Math.min(steps - 1, rawStep); let phase = basePhase; - if (["PUNCH", "KICK", "WHIP", "BASH", "FIRE", "THROW", "REACH"] - .includes(state)) { + if (timing) phase = meleeFrame(player,now).phase.toUpperCase(); + else if (["FIRE", "THROW", "REACH"].includes(state)) { const section = step / Math.max(1, steps - 1); phase = section < .3 ? "STARTUP" : section < .68 ? "ACTIVE" : "RECOVERY"; } else if (state === "JUMP" || state === "FALL") { @@ -10265,11 +10292,11 @@ function runnerWorldGeometry(player, t) { return pose; } -function buildRunnerWorldGeometry(player, t) { +function buildRunnerWorldGeometry(player, t, at = null) { if (player.spiderDummy) return spiderDummyWorldGeometry(player, t); // Rendering consumes the same fixed 60 Hz phase clock as simulation. The // display can remain uncapped without inventing in-between combat poses. - const animation = fighterAnimationPhase(player); + const animation = fighterAnimationPhase(player, at); const poseNow = animation.frameNow; const poseCycle = animation.progress * Math.PI * 2; const speed = Math.min(1, Math.abs(player.vx) / 1500); @@ -10909,47 +10936,188 @@ function segmentSegmentClosest(first, second) { firstPoint.y - secondPoint.y, firstPoint.z - secondPoint.z) }; } -function attackCapsuleContact(attackingLimbs, target, t) { - const targetGeometry = runnerWorldGeometry(target, t); - if (!attackingLimbs.length) return null; - const head = targetGeometry.head; - const headCapsule = { x1: head.x, y1: head.y, z1: head.z, - x2: head.x, y2: head.y, z2: head.z, width: head.radius * 2 }; - let headContact = null; - let bodyContact = null; - for (const attackingLimb of attackingLimbs) { - const headClosest = segmentSegmentClosest(attackingLimb, headCapsule); - const headSeparation = headClosest.distance - - (attackingLimb.width + headCapsule.width) / 2; - if (!headContact || headSeparation < headContact.separation) - headContact = { closest: headClosest, separation: headSeparation }; - for (let index = 0; index < targetGeometry.segments.length; index++) { - const targetLimb = targetGeometry.segments[index]; - const closest = segmentSegmentClosest(attackingLimb, targetLimb); - const separation = closest.distance - - (attackingLimb.width + targetLimb.width) / 2; - if (!bodyContact || separation < bodyContact.separation) - bodyContact = { closest, separation, segmentIndex: index }; - } - } - const headshot = headContact.separation <= 3; - const contact = headshot ? headContact : bodyContact; - if (!contact) return null; - return { - x: (contact.closest.firstPoint.x + contact.closest.secondPoint.x) / 2, - y: (contact.closest.firstPoint.y + contact.closest.secondPoint.y) / 2, - z: (contact.closest.firstPoint.z + contact.closest.secondPoint.z) / 2, - separation: contact.separation, - segmentIndex: headshot ? -1 : contact.segmentIndex, - headshot, - }; -} function meleeLimbContact(attacker, target, t) { - const attackingGeometry = runnerWorldGeometry(attacker, t); - const attackingLimbs = attackingGeometry.segments.filter((segment) => - segment.role?.startsWith("attack-")); - return attackCapsuleContact(attackingLimbs, target, t); + const now = runtime().simMonotonicUs || runtime().monotonicUs; + return combatBoxContact(sampleCombatBoxes(attacker, now), sampleCombatBoxes(target, now)); +} + +// World-space rectangles with a shallow Z interval. Visual line width never +// changes these authored radii. The same records feed collision, Tab and Jev. +function combatRect(id, left, top, right, bottom, z = 0, depth = 18, extra = {}) { + return { id, left, top, right, bottom, near: z - depth, far: z + depth, ...extra }; +} +function boxesOverlap(a, b) { + return a.left <= b.right && a.right >= b.left && a.top <= b.bottom && + a.bottom >= b.top && a.near <= b.far && a.far >= b.near; +} +function boxBounds(items) { + return { left: Math.min(...items.map(b => b.left)), right: Math.max(...items.map(b => b.right)), + top: Math.min(...items.map(b => b.top)), bottom: Math.max(...items.map(b => b.bottom)), + near: Math.min(...items.map(b => b.near)), far: Math.max(...items.map(b => b.far)) }; +} +function buildBoxTree(items) { + if (!items.length) return null; + const bounds = boxBounds(items); + if (items.length <= 3) return { bounds, items }; + const horizontal = bounds.right - bounds.left >= bounds.bottom - bounds.top; + const sorted = items.slice().sort((a,b) => horizontal + ? (a.left+a.right)-(b.left+b.right) : (a.top+a.bottom)-(b.top+b.bottom)); + const middle = Math.floor(sorted.length / 2); + return { bounds, children: [buildBoxTree(sorted.slice(0,middle)), buildBoxTree(sorted.slice(middle))] }; +} +function queryBoxTree(tree, area, found = []) { + if (!tree || !boxesOverlap(tree.bounds, area)) return found; + if (tree.items) for (const item of tree.items) { if (boxesOverlap(item, area)) found.push(item); } + else for (const child of tree.children) queryBoxTree(child, area, found); + return found; +} +function pointBoxDistance(box, x, y, z = 0) { + return Math.hypot(Math.max(box.left-x,0,x-box.right), + Math.max(box.top-y,0,y-box.bottom), Math.max(box.near-z,0,z-box.far)); +} +// Slab test on an expanded AABB: a fast projectile cannot skip a thin hurtbox. +function segmentBoxEntry(segment, box, radius = 0) { + let enter = 0, leave = 1; + for (const [axis,low,high] of [['x','left','right'],['y','top','bottom'],['z','near','far']]) { + const origin = segment[axis+'1'], delta = segment[axis+'2']-origin; + if (Math.abs(delta)<1e-9) { + if (originbox[high]+radius) return null; + } else { + const a=(box[low]-radius-origin)/delta,b=(box[high]+radius-origin)/delta; + enter=Math.max(enter,Math.min(a,b));leave=Math.min(leave,Math.max(a,b)); + if(enter>leave)return null; + } + } + return enter; +} +function sweptProjectileContact(segments,target,t) { + const now=runtime().simMonotonicUs || runtime().monotonicUs; + const boxes=sampleCombatBoxes(target,now); + let result=null; + for(const s of segments) { + const r=s.width/2; + const area=combatRect('sweep',Math.min(s.x1,s.x2)-r,Math.min(s.y1,s.y2)-r, + Math.max(s.x1,s.x2)+r,Math.max(s.y1,s.y2)+r,(s.z1+s.z2)/2,Math.abs(s.z2-s.z1)/2+r); + for(const hurt of queryBoxTree(boxes.tree,area)) { + const amount=segmentBoxEntry(s,hurt,r); + if(amount===null || (result && amount>=result.amount))continue; + result={amount,x:s.x1+(s.x2-s.x1)*amount,y:s.y1+(s.y2-s.y1)*amount, + z:s.z1+(s.z2-s.z1)*amount,separation:0,headshot:hurt.part==='head',segmentIndex:hurt.segmentIndex}; + } + } + return result; +} +function combatPushbox(player) { + const half = isHeadOnly(player) ? 24 : isPogo(player) ? 38 : 69; + const height = isHeadOnly(player) ? 44 : isPogo(player) ? 116 : player.ducking ? 118 : 180; + return combatRect('push', player.x-half, player.y-height, player.x+half, player.y, player.z); +} +function sampleCombatBoxes(player, now, world = null) { + world ||= runnerWorldGeometry(player, (now-startedAt)/1e6); + const hurt = []; + const head = world.head; + hurt.push(combatRect('head', head.x-22, head.y-22, head.x+22, head.y+22, head.z, 22, + { part: 'head', segmentIndex: -1 })); + for (let i=0; is.role==='torso'); + if(torso)hit.push(combatRect('pogo',torso.x2-10,torso.y2-10, + torso.x2+10,torso.y2+10,torso.z2,10,{part:'torso'})); + } + if (player.alive && !player.attackHit && !player.blocking && now >= player.hitStunUntil && + frame.phase === 'active' && !isHeadOnly(player) && !isPogo(player)) { + const kick = player.attackKind === 'KICK'; + const part = kick ? player.facing > 0 ? 'right-leg' : 'left-leg' : itemHand(player); + if (part && hasPart(player, part)) { + const tip = meleeTarget(player, now); + const halfX = kick ? 26 : 22; + const halfY = kick && player.lowKick ? 17 : 20; + const inner = player.x+player.facing*(kick ? 42 : 30); + const outer = tip.x+player.facing*halfX; + hit.push(combatRect(player.attackKind.toLowerCase(), Math.min(inner,outer), + tip.y-halfY, Math.max(inner,outer), tip.y+halfY, tip.z, 18, { part })); + } + } + const guard = []; + if (player.blocking) { + const shield = shieldGeometry(player); + guard.push(combatRect('guard', shield.x-shield.radius, shield.y-shield.radius, + shield.x+shield.radius, shield.y+shield.radius, shield.z, shield.radius)); + } + return { hurt, hit, guard, push: combatPushbox(player), frame, + tree: buildBoxTree(hurt) }; +} +function combatBoxContact(attacker, target) { + let result = null; + for (const hit of attacker.hit) { + const overlaps = queryBoxTree(target.tree, hit).sort((a,b) => + (a.part === 'head' ? -1 : b.part === 'head' ? 1 : a.segmentIndex-b.segmentIndex)); + const hurt = overlaps[0]; + if (!hurt) continue; + result = { x:(Math.max(hit.left,hurt.left)+Math.min(hit.right,hurt.right))/2, + y:(Math.max(hit.top,hurt.top)+Math.min(hit.bottom,hurt.bottom))/2, + z:(Math.max(hit.near,hurt.near)+Math.min(hit.far,hurt.far))/2, + separation: 0, headshot:hurt.part === 'head', segmentIndex:hurt.segmentIndex, + hitbox:hit.id, hurtbox:hurt.id }; + if (result.headshot) break; + } + return result; +} + +// Sample the game's real strike capsules against the opponent's current +// hurtboxes. This is reach evidence at fixed positions, not a predicted hit: +// travel, input latency, shields and the opponent's next move can change it. +function jevStrikeOptions(player, opponent, now) { + if (!player.alive || !opponent.alive || isHeadOnly(player) || isPogo(player)) return {}; + const t = (now - startedAt) / 1000000; + const target = sampleCombatBoxes(opponent, now); + const facing = Math.sign(opponent.x - player.x) || player.facing; + const result = {}; + for (const [action, kind, crouched] of [ + ['punch', itemMelee[heldItem(player)] || 'PUNCH', false], + ['kick', 'KICK', false], ['low_kick', 'KICK', true], + ['crouch_punch', itemMelee[heldItem(player)] || 'PUNCH', true], + ]) { + const part = kind === 'KICK' ? facing > 0 ? 'right-leg' : 'left-leg' : itemHand(player); + if (!part || !hasPart(player, part) || (crouched && !player.grounded)) continue; + const probe = { ...player, facing, vx: 0, blocking: false, + ducking: crouched, crouchBlend: crouched ? 1 : 0, + grabHeld: false, itemAction: '', hitStunUntil: 0, attackHit: false, + attackKind: kind, lowKick: crouched && kind === 'KICK', + attackStartedAt: now, attackUntil: now + meleeSpecs[kind].windowUs }; + let closest = null, clearance = Infinity; + const timing = meleeFrames[kind]; + for (let frame=timing.startup; frame= .11) return; - const world = player.replayGeometry || player.frozenGeometry || - runnerWorldGeometry(player, t); - const geometry = projectRunnerWorldGeometry(world); - // Training-mode box colors, in the arrangement every fighting game has - // agreed on and every hitbox site draws: GREEN is what can be hit, RED is - // what is hitting, ORANGE is the space the body occupies. The old palette - // said cyan limbs, a red head and a green box, which is the same three - // facts wearing the wrong three colors -- red on the head in particular - // read as "this is the dangerous part" when the head is the most - // vulnerable part there is. + if (renderFlags.hud === false || !debugHitboxes || !player.alive) return; + const now = player.frozenAt || runtime().simMonotonicUs || runtime().monotonicUs; + const boxes = sampleCombatBoxes(player, now); const hurtColor = [82, 226, 116]; const pushColor = [255, 158, 54]; const attackColor = [255, 58, 64]; - const spentColor = [72, 150, 255]; - - for (const segment of geometry.segments) - debugCapsule(segment.x1, segment.y1, segment.x2, segment.y2, - Math.max(2, segment.width * .22), hurtColor); - filledRing(geometry.head.x, geometry.head.y, geometry.head.radius, - Math.max(0, geometry.head.radius - Math.max(2, - geometry.head.radius * .12)), hurtColor); - - const halfWidth = player.ducking ? 76 : 62; - const top = player.y - (player.ducking ? 132 : 174); - const corners = [ - projectPoint(player.x - halfWidth, top, player.z), - projectPoint(player.x + halfWidth, top, player.z), - projectPoint(player.x + halfWidth, player.y, player.z), - projectPoint(player.x - halfWidth, player.y, player.z), - ]; - for (let index = 0; index < corners.length; index++) { - const next = corners[(index + 1) % corners.length]; - debugCapsule(corners[index].x, corners[index].y, - next.x, next.y, 2, pushColor); - } - - const displayNow = player.frozenAt || now; - if (player.attackKind && displayNow < player.attackUntil) { - // A swing that has already landed is drawn in recovery blue rather than - // hitbox red, because `attackHit` means it cannot hurt anybody again -- - // and a red box that cannot hit is the single most misleading thing a - // training overlay can show you. - const live = !player.attackHit; - for (const segment of geometry.segments) { - if (!segment.role?.startsWith("attack-")) continue; - debugCapsule(segment.x1, segment.y1, segment.x2, segment.y2, - segment.width + 5, live ? attackColor : spentColor); + const guardColor = [186, 118, 255]; + const draw = (b, color, width = 2) => { + const z = (b.near+b.far)/2; + const points = [[b.left,b.top],[b.right,b.top],[b.right,b.bottom],[b.left,b.bottom]] + .map(([x,y])=>projectPoint(x,y,z)); + for (let i=0;i<4;i++) { + const a=points[i], next=points[(i+1)%4]; + debugCapsule(a.x,a.y,next.x,next.y,width,color); } - } + }; + for (const b of boxes.hurt) draw(b,hurtColor); + draw(boxes.push,pushColor); + for (const b of boxes.guard) draw(b,guardColor,3); + for (const b of boxes.hit) draw(b,attackColor,4); } // The frame meter. One pip per simulation frame, oldest on the left, the diff --git a/xbox/live/social/manifest.json b/xbox/live/social/manifest.json index 5acb5d065..7ae7af0c0 100644 --- a/xbox/live/social/manifest.json +++ b/xbox/live/social/manifest.json @@ -1,7 +1,7 @@ { "format": "ac.oskiewar.social-preview", "version": 2, - "build": "049308608f0d462e", + "build": "57795a9f7c339827", "theme": "light", "imageWidth": 1200, "imageHeight": 630, diff --git a/xbox/live/social/oskiewar-title.jpg b/xbox/live/social/oskiewar-title.jpg index cfc93d6bcf3294f3118ed597443f85b14797c989..63eb6f122861e41431229a592efe39a7b9f8575a 100644 GIT binary patch literal 59477 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