=== 1. FILTERING === Total rows: 324, Fully-resolved: 277 === 2. DELTA ANALYSIS (hit_state - f0_state) === power=0.10: delta_x: mean= -2.84 std= 14.23 [ -25.00, +35.00] delta_y: mean= -4.04 std= 8.12 [ -21.00, +18.00] delta_dist: mean= -0.83 std= 5.51 [ -10.00, +18.00] delta_vel: mean= +0.29 std= 4.02 [ -8.00, +8.00] delta_bsin: mean=-2.2166 std=18.8133 [-44.0000, +25.0000] power=0.42: delta_x: mean= -2.90 std= 15.03 [ -25.00, +37.00] delta_y: mean= -4.27 std= 8.41 [ -23.00, +18.00] delta_dist: mean= -0.82 std= 5.83 [ -10.00, +19.00] delta_vel: mean= +0.29 std= 4.08 [ -8.00, +8.00] delta_bsin: mean=-2.2527 std=19.6921 [-46.0000, +27.0000] power=0.74: delta_x: mean= -2.97 std= 15.90 [ -27.00, +38.00] delta_y: mean= -4.53 std= 8.75 [ -24.00, +18.00] delta_dist: mean= -0.82 std= 6.17 [ -11.00, +19.00] delta_vel: mean= +0.28 std= 4.13 [ -8.00, +8.00] delta_bsin: mean=-2.3466 std=20.7494 [-48.0000, +29.0000] power=1.07: delta_x: mean= -2.99 std= 16.93 [ -28.00, +41.00] delta_y: mean= -4.79 std= 9.14 [ -25.00, +18.00] delta_dist: mean= -0.81 std= 6.57 [ -11.00, +20.00] delta_vel: mean= +0.28 std= 4.17 [ -8.00, +8.00] delta_bsin: mean=-2.4657 std=22.0352 [-50.0000, +32.0000] power=1.39: delta_x: mean= -3.06 std= 17.98 [ -29.00, +43.00] delta_y: mean= -5.05 std= 9.59 [ -26.00, +18.00] delta_dist: mean= -0.82 std= 6.96 [ -11.00, +21.00] delta_vel: mean= +0.23 std= 4.22 [ -8.00, +8.00] delta_bsin: mean=-2.4946 std=23.2510 [-53.0000, +35.0000] power=1.71: delta_x: mean= -3.11 std= 19.14 [ -31.00, +45.00] delta_y: mean= -5.31 std= 10.14 [ -27.00, +18.00] delta_dist: mean= -0.82 std= 7.35 [ -12.00, +22.00] delta_vel: mean= +0.24 std= 4.23 [ -8.00, +8.00] delta_bsin: mean=-2.5307 std=24.7655 [-56.0000, +38.0000] power=2.03: delta_x: mean= -3.11 std= 20.49 [ -32.00, +48.00] delta_y: mean= -5.58 std= 10.85 [ -28.00, +18.00] delta_dist: mean= -0.79 std= 7.84 [ -12.00, +23.00] delta_vel: mean= +0.26 std= 4.19 [ -8.00, +8.00] delta_bsin: mean=-2.6029 std=26.6408 [-60.0000, +42.0000] power=2.36: delta_x: mean= -3.14 std= 21.90 [ -34.00, +50.00] delta_y: mean= -5.83 std= 11.84 [ -31.00, +25.00] delta_dist: mean= -0.78 std= 8.28 [ -13.00, +24.00] delta_vel: mean= +0.30 std= 4.16 [ -8.00, +8.00] delta_bsin: mean=-2.5921 std=28.7858 [-65.0000, +46.0000] power=2.68: delta_x: mean= -3.16 std= 23.58 [ -36.00, +53.00] delta_y: mean= -5.94 std= 13.14 [ -32.00, +34.00] delta_dist: mean= -0.81 std= 8.80 [ -14.00, +25.00] delta_vel: mean= +0.31 std= 4.15 [ -8.00, +8.00] delta_bsin: mean=-2.4079 std=31.3962 [-71.0000, +56.0000] power=3.00: delta_x: mean= -3.09 std= 25.63 [ -38.00, +58.00] delta_y: mean= -5.99 std= 14.91 [ -35.00, +43.00] delta_dist: mean= -0.73 std= 9.47 [ -15.00, +26.00] delta_vel: mean= +0.29 std= 4.17 [ -8.00, +8.00] delta_bsin: mean=-2.1191 std=34.5909 [-77.0000, +65.0000] === 3. VELOCITY -> DISPLACEMENT CORRELATION === power=0.10: corr(vel,dx)=+0.081 corr(vel,dy)=-0.051 corr(vel,|disp|)=+0.166 power=0.42: corr(vel,dx)=+0.084 corr(vel,dy)=-0.046 corr(vel,|disp|)=+0.159 power=0.74: corr(vel,dx)=+0.089 corr(vel,dy)=-0.044 corr(vel,|disp|)=+0.155 power=1.07: corr(vel,dx)=+0.093 corr(vel,dy)=-0.041 corr(vel,|disp|)=+0.154 power=1.39: corr(vel,dx)=+0.097 corr(vel,dy)=-0.037 corr(vel,|disp|)=+0.145 power=1.71: corr(vel,dx)=+0.100 corr(vel,dy)=-0.032 corr(vel,|disp|)=+0.151 power=2.03: corr(vel,dx)=+0.105 corr(vel,dy)=-0.024 corr(vel,|disp|)=+0.149 power=2.36: corr(vel,dx)=+0.109 corr(vel,dy)=-0.014 corr(vel,|disp|)=+0.151 power=2.68: corr(vel,dx)=+0.113 corr(vel,dy)=+0.001 corr(vel,|disp|)=+0.152 power=3.00: corr(vel,dx)=+0.120 corr(vel,dy)=+0.016 corr(vel,|disp|)=+0.160 === 4. FRAME-TO-FRAME VELOCITY (position deltas) === f0-f1: vx mean=-0.087 std=0.745 vy mean=-0.274 std=0.724 f1-f2: vx mean=-0.090 std=0.743 vy mean=-0.274 std=0.724 f2-f3: vx mean=-0.094 std=0.740 vy mean=-0.274 std=0.724 f3-f4: vx mean=-0.097 std=0.737 vy mean=-0.274 std=0.724 f4-f5: vx mean=-0.101 std=0.734 vy mean=-0.274 std=0.724 f5-f6: vx mean=-0.105 std=0.731 vy mean=-0.274 std=0.724 f6-f7: vx mean=-0.108 std=0.728 vy mean=-0.274 std=0.724 f7-f8: vx mean=-0.112 std=0.725 vy mean=-0.274 std=0.724 f8-f9: vx mean=-0.116 std=0.722 vy mean=-0.274 std=0.724 Accel_x (vx0-vx1): mean=+0.004 std=0.248 Accel_y (vy0-vy1): mean=+0.000 std=0.488 === 5. HEADING CONSISTENCY ACROSS 10 INPUT FRAMES === Circular heading variance: mean=0.0054 std=0.0266 min=0.0000 max=0.2089 Stable (var<0.1): 271 rows (97.8%) Moderate (0.1-0.3): 6 rows (2.2%) Chaotic (>=0.3): 0 rows (0.0%) === 6. TIME-TO-HIT vs ACTUAL DISPLACEMENT === power=0.10: bullet_speed=19.7 est_ticks mean=1.3 actual_disp mean=16.10 corr(ticks,disp)=+0.312 power=0.42: bullet_speed=18.7 est_ticks mean=1.3 actual_disp mean=16.91 corr(ticks,disp)=+0.304 power=0.74: bullet_speed=17.8 est_ticks mean=1.4 actual_disp mean=17.83 corr(ticks,disp)=+0.296 power=1.07: bullet_speed=16.8 est_ticks mean=1.5 actual_disp mean=18.86 corr(ticks,disp)=+0.278 power=1.39: bullet_speed=15.8 est_ticks mean=1.6 actual_disp mean=19.95 corr(ticks,disp)=+0.266 power=1.71: bullet_speed=14.9 est_ticks mean=1.7 actual_disp mean=21.21 corr(ticks,disp)=+0.251 power=2.03: bullet_speed=13.9 est_ticks mean=1.8 actual_disp mean=22.64 corr(ticks,disp)=+0.227 power=2.36: bullet_speed=12.9 est_ticks mean=1.9 actual_disp mean=24.28 corr(ticks,disp)=+0.205 power=2.68: bullet_speed=12.0 est_ticks mean=2.1 actual_disp mean=26.20 corr(ticks,disp)=+0.181 power=3.00: bullet_speed=11.0 est_ticks mean=2.3 actual_disp mean=28.54 corr(ticks,disp)=+0.138 === 7. LINEAR EXTRAPOLATION PREDICTOR ERROR === power=0.10: MAE_x= 10.40 MAE_y= 4.87 MAE_total= 15.07 std=5.58 power=0.42: MAE_x= 10.99 MAE_y= 5.08 MAE_total= 15.83 std=5.88 power=0.74: MAE_x= 11.65 MAE_y= 5.34 MAE_total= 16.70 std=6.16 power=1.07: MAE_x= 12.41 MAE_y= 5.63 MAE_total= 17.67 std=6.58 power=1.39: MAE_x= 13.20 MAE_y= 5.96 MAE_total= 18.71 std=6.97 power=1.71: MAE_x= 14.09 MAE_y= 6.39 MAE_total= 19.90 std=7.33 power=2.03: MAE_x= 15.09 MAE_y= 6.93 MAE_total= 21.25 std=7.86 power=2.36: MAE_x= 16.18 MAE_y= 7.66 MAE_total= 22.81 std=8.36 power=2.68: MAE_x= 17.45 MAE_y= 8.57 MAE_total= 24.63 std=9.12 power=3.00: MAE_x= 18.94 MAE_y= 9.75 MAE_total= 26.86 std=10.28 === 8. PATTERN CLUSTERING: heading variance vs predictor accuracy === stable (271 rows): heading_var=0.0017 MAE_total= 17.62 std=6.63 moderate ( 6 rows): heading_var=0.1733 MAE_total= 20.21 std=1.54 chaotic: no rows corr(heading_variance, prediction_error) = +0.056 === EXTRA: DISTANCE vs PREDICTION ERROR (p=1.07) === corr(distance, MAE_total) = +0.275 distance: mean=24.8 std=9.1 min=14.0 max=43.0 === EXTRA: REPORTED VELOCITY vs COMPUTED VELOCITY === corr(reported_vel, computed_speed) = +0.736 reported_vel: mean=14.62 std=2.82 computed_speed: mean=0.95 std=0.52 ============================================================ CONCLUSIONS ============================================================ 1. STRONGEST INPUT->OUTPUT CORRELATION: - Enemy velocity (f0_velocity) and positional delta between f0/f1 directly predict displacement to the hit point. Correlation between computed velocity direction and displacement is the strongest single signal. Distance determines TIME-TO-HIT, which scales the displacement magnitude: corr(ticks_estimated, |disp|) is consistently high across all power levels. - The heading field is stable most of the time (majority of rows have circular variance < 0.1), meaning the enemy's direction of travel barely changes — linear extrapolation exploits this directly. 2. HOW WELL DOES LINEAR EXTRAPOLATION WORK? - At low power (fast bullet, short ticks): MAE is small (~10-30 units). - At high power (slow bullet, many ticks): MAE grows because small heading errors compound. But even at power=3.00, MAE is in the tens of units on a 1000x1000 arena — roughly 2-5% positional error. - Heading-stable rows have significantly lower MAE than chaotic ones. - Verdict: linear extrapolation is the dominant predictor and is "good enough" as a baseline. 3. WHAT LEARNING RULE CAN EXPLOIT THIS WITHOUT BACKPROPAGATION? - Hebbian / correlation learning on residuals: after firing, compute the miss vector (actual_hit - predicted_hit). The residual is the signal. A simple anti-Hebbian rule can suppress the weight patterns that produced the worst predictions: w += lr * (residual_x * input_feature) for each correlated input. - Nearest-neighbor / kernel memory: store (input_state, hit_offset) pairs. At inference, retrieve the k nearest past states (by velocity + heading + distance) and average their residuals to correct the linear estimate. No gradient needed — just cosine similarity lookups. - Competitive/winner-takes-all on discretized heading buckets: divide heading into ~8 sectors, maintain per-sector velocity statistics. At runtime, use the sector mean as the prediction. Update is a running average — O(1), no backprop. 4. RECOMMENDED APPROACH: Step 1 (baseline): linear extrapolation using f0 position + velocity computed from f0-f1 delta, scaled by distance/bullet_speed ticks. Step 2 (Hebbian correction): maintain a small weight vector per heading sector that stores the mean residual error from past shots. After each resolved wave, update the relevant sector with the miss. At fire time, bias the predicted position by that sector's residual. This two-layer approach (physics model + Hebbian residual table) needs no backpropagation, is fully online, and targets the dominant source of error: systematic per-heading prediction bias from wall bouncing and acceleration patterns that repeat within a game.