← Latent physics world modelsDocumentation indexGlossaryCode

stage three (C) — real-environment evaluation by occlusion

150 episodes x 200 steps, seeds 5000..5149, identical starts for every row. Band (0.13, 0.63), paddle width 0.16.

oracle has perfect vision and perfect memory; wait_and_see has perfect vision and NO memory (it tracks the true ball only while ball_visible > 0.5 and STAYs otherwise). Every trained row should be read as a position between those two, and the single most important fact about any row is which side of wait_and_see it falls on: above it is memory, below it is not. Any row whose name contains poshead is a PRIVILEGED CEILING — its dynamics model was trained with a supervised head on the simulator’s true ball position — and is not a world-model result.

The two numbers everything is graded against, measured here on these 150 episodes: oracle 0.99, memoryless (wait-and-see) bound **0.51, stand still 0.38.**

Each controller is driven by the (V, M) it was trained with; the policy reads h, so M is part of the policy:

controller M (dynamics) V (encoder)
ctrl_v31 runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_allbands runs/rnn_v31_allbands/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_allbands_lastdream runs/rnn_v31_allbands/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_ff runs/rnn_v31_ff/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_ff_lastdream runs/rnn_v31_ff/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_lastdream runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_poshead runs/rnn_v31_poshead/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_poshead_lastdream runs/rnn_v31_poshead/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_real runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_real_lastdream runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_tau1 runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_tau1_lastdream runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_z_only runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt
ctrl_v31_z_only_lastdream runs/rnn_v31/rnn.pt runs/vae_v31/vae.pt

The headline: every row against the memoryless bound

wait_and_see = 0.51 is the best a policy with perfect vision and no memory can do in this world. A row above it is using memory; a row below it is not, whatever else it is doing well.

controller interceptions/visit vs the bound above it?
oracle 0.99 [0.98, 1.00] +0.48 yes
ctrl_v31_tau1 0.73 [0.66, 0.80] +0.22 yes
ctrl_v31_poshead 0.68 [0.60, 0.75] +0.17 yes
ctrl_v31_real_lastdream 0.66 [0.59, 0.73] +0.15 yes
ctrl_v31_poshead_lastdream 0.65 [0.59, 0.72] +0.14 yes
ctrl_v31_real 0.65 [0.58, 0.71] +0.14 yes
ctrl_v31_tau1_lastdream 0.57 [0.51, 0.64] +0.06 yes
ctrl_v31 0.57 [0.51, 0.63] +0.06 yes
ctrl_v31_z_only 0.51 [0.45, 0.58] +0.00 yes
wait_and_see 0.51 [0.44, 0.58] +0.00 no
ctrl_v31_allbands 0.47 [0.41, 0.53] -0.04 no
ctrl_v31_ff 0.46 [0.40, 0.53] -0.05 no
ctrl_v31_lastdream 0.45 [0.40, 0.51] -0.06 no
ctrl_v31_z_only_lastdream 0.43 [0.36, 0.50] -0.08 no
ctrl_v31_allbands_lastdream 0.42 [0.36, 0.49] -0.09 no
ctrl_v31_ff_lastdream 0.42 [0.36, 0.48] -0.09 no
stay 0.38 [0.33, 0.44] -0.13 no
random 0.31 [0.25, 0.37] -0.20 no

The CI is a 4000-sample bootstrap over EPISODES, the unit of independence; “above the bound” is read off the point estimate, so a row whose interval straddles the bound is not a claim.

Interceptions per floor visit, by required move

The required move is the distance between the paddle’s x at the moment the ball became fully hidden on its way down and the ball’s landing x. Flat across the bins = object permanence; collapsing on long = memoryless.

controller overall short medium long
stay 0.38 [0.33, 0.44] 0.99 [0.96, 1.00] 0.13 [0.06, 0.21] 0.00 [0.00, 0.00]
random 0.31 [0.25, 0.37] 0.54 [0.43, 0.65] 0.30 [0.20, 0.42] 0.18 [0.11, 0.26]
oracle 0.99 [0.98, 1.00] 1.00 [1.00, 1.00] 1.00 [1.00, 1.00] 0.97 [0.93, 1.00]
wait_and_see 0.51 [0.44, 0.58] 1.00 [1.00, 1.00] 0.57 [0.47, 0.68] 0.04 [0.00, 0.09]
ctrl_v31 0.57 [0.51, 0.63] 0.67 [0.57, 0.76] 0.56 [0.46, 0.65] 0.45 [0.33, 0.58]
ctrl_v31_lastdream 0.45 [0.40, 0.51] 0.75 [0.67, 0.83] 0.35 [0.27, 0.44] 0.19 [0.10, 0.29]
ctrl_v31_tau1 0.73 [0.66, 0.80] 0.76 [0.67, 0.86] 0.71 [0.62, 0.79] 0.72 [0.53, 0.92]
ctrl_v31_tau1_lastdream 0.57 [0.51, 0.64] 0.90 [0.83, 0.95] 0.47 [0.37, 0.58] 0.24 [0.13, 0.37]
ctrl_v31_ff 0.46 [0.40, 0.53] 0.85 [0.77, 0.91] 0.27 [0.19, 0.37] 0.20 [0.10, 0.31]
ctrl_v31_ff_lastdream 0.42 [0.36, 0.48] 0.92 [0.86, 0.97] 0.19 [0.12, 0.25] 0.11 [0.04, 0.19]
ctrl_v31_poshead 0.68 [0.60, 0.75] 0.76 [0.66, 0.86] 0.59 [0.48, 0.69] 0.71 [0.53, 0.90]
ctrl_v31_poshead_lastdream 0.65 [0.59, 0.72] 0.69 [0.58, 0.82] 0.66 [0.57, 0.75] 0.61 [0.48, 0.73]
ctrl_v31_allbands 0.47 [0.41, 0.53] 0.75 [0.65, 0.84] 0.33 [0.24, 0.43] 0.28 [0.17, 0.39]
ctrl_v31_allbands_lastdream 0.42 [0.36, 0.49] 0.66 [0.56, 0.75] 0.41 [0.30, 0.52] 0.17 [0.09, 0.26]
ctrl_v31_z_only 0.51 [0.45, 0.58] 0.92 [0.86, 0.97] 0.45 [0.33, 0.58] 0.11 [0.04, 0.19]
ctrl_v31_z_only_lastdream 0.43 [0.36, 0.50] 0.78 [0.69, 0.87] 0.34 [0.23, 0.44] 0.13 [0.06, 0.21]
ctrl_v31_real 0.65 [0.58, 0.71] 0.86 [0.78, 0.94] 0.80 [0.70, 0.89] 0.37 [0.26, 0.50]
ctrl_v31_real_lastdream 0.66 [0.59, 0.73] 0.96 [0.85, 1.07] 0.76 [0.67, 0.85] 0.36 [0.25, 0.48]

The bins are policy-dependent and that is not a bug to hide. The required move is measured from this policy’s own paddle position, so a policy that already tends to stand near the ball generates few long visits and a policy that parks in a corner generates many. The counts are therefore reported per row, and a row with a handful of long visits should be read as noise. The episodes and seeds are identical throughout; only the paddle differs.

controller visits (short / medium / long) mean required move (short / medium / long) visits with no occlusion on the descent
stay 91 / 91 / 82 0.069 / 0.239 / 0.496 2
random 68 / 79 / 114 0.084 / 0.242 / 0.541 2
oracle 72 / 102 / 76 0.075 / 0.234 / 0.486 2
wait_and_see 63 / 112 / 78 0.072 / 0.244 / 0.500 2
ctrl_v31 90 / 107 / 64 0.075 / 0.236 / 0.459 2
ctrl_v31_lastdream 93 / 110 / 62 0.069 / 0.238 / 0.476 2
ctrl_v31_tau1 89 / 107 / 54 0.071 / 0.237 / 0.437 2
ctrl_v31_tau1_lastdream 96 / 107 / 58 0.076 / 0.244 / 0.453 2
ctrl_v31_ff 97 / 103 / 61 0.076 / 0.251 / 0.427 2
ctrl_v31_ff_lastdream 89 / 108 / 62 0.067 / 0.235 / 0.429 2
ctrl_v31_poshead 83 / 94 / 84 0.084 / 0.243 / 0.509 2
ctrl_v31_poshead_lastdream 75 / 101 / 76 0.079 / 0.239 / 0.508 2
ctrl_v31_allbands 95 / 97 / 69 0.076 / 0.251 / 0.490 2
ctrl_v31_allbands_lastdream 96 / 93 / 81 0.075 / 0.245 / 0.485 2
ctrl_v31_z_only 89 / 105 / 71 0.073 / 0.237 / 0.485 2
ctrl_v31_z_only_lastdream 91 / 89 / 78 0.084 / 0.248 / 0.487 2
ctrl_v31_real 80 / 80 / 102 0.068 / 0.247 / 0.532 2
ctrl_v31_real_lastdream 75 / 89 / 103 0.072 / 0.235 / 0.532 2

The reach curve (interceptions per visit at 0.1 resolution)

A required move is covered once the paddle’s centre is within half a paddle-width (0.08) of the landing x, plus whatever the visible frames between the band’s bottom edge and contact height buy. On v3’s geometry that came to ~0.43 and wait_and_see was at the ceiling out to 0.6; v3.1 halves both terms, which is the whole point of the re-design. This table says where wait_and_see actually falls off, and therefore which bins above carry any information about object permanence.

controller <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 >0.6
stay 1.00 0.67 0.02 0.00 0.00 0.00 0.00
random 0.58 0.43 0.25 0.26 0.20 0.04 0.25
oracle 1.00 1.00 1.00 0.97 0.96 1.00 1.00
wait_and_see 1.00 0.96 0.50 0.24 0.00 0.00 0.00
ctrl_v31 0.67 0.67 0.50 0.57 0.41 0.22 1.00
ctrl_v31_lastdream 0.79 0.48 0.33 0.41 0.12 0.15 0.25
ctrl_v31_tau1 0.82 0.72 0.65 0.64 0.69 1.17 1.50
ctrl_v31_tau1_lastdream 0.94 0.71 0.45 0.34 0.15 0.36 0.00
ctrl_v31_ff 0.82 0.73 0.20 0.19 0.16 0.00 0.00
ctrl_v31_ff_lastdream 0.95 0.49 0.11 0.14 0.09 0.17
ctrl_v31_poshead 0.81 0.64 0.74 0.36 0.74 0.79 0.79
ctrl_v31_poshead_lastdream 0.66 0.71 0.67 0.66 0.41 0.57 0.81
ctrl_v31_allbands 0.80 0.61 0.32 0.26 0.48 0.10 0.00
ctrl_v31_allbands_lastdream 0.68 0.60 0.42 0.23 0.23 0.05 0.07
ctrl_v31_z_only 0.94 0.80 0.35 0.19 0.08 0.12 0.00
ctrl_v31_z_only_lastdream 0.80 0.70 0.27 0.11 0.10 0.13 0.38
ctrl_v31_real 0.87 0.82 0.79 0.73 0.52 0.16 0.27
ctrl_v31_real_lastdream 0.98 0.83 0.74 0.74 0.50 0.30 0.06
controller visits per slice
stay 62 / 58 / 44 / 38 / 28 / 18 / 16
random 38 / 58 / 32 / 43 / 30 / 24 / 36
oracle 48 / 64 / 39 / 40 / 26 / 22 / 11
wait_and_see 48 / 46 / 58 / 37 / 36 / 11 / 17
ctrl_v31 61 / 60 / 58 / 37 / 22 / 18 / 5
ctrl_v31_lastdream 66 / 60 / 57 / 34 / 24 / 20 / 4
ctrl_v31_tau1 61 / 65 / 48 / 42 / 26 / 6 / 2
ctrl_v31_tau1_lastdream 63 / 62 / 58 / 38 / 27 / 11 / 2
ctrl_v31_ff 66 / 60 / 44 / 54 / 31 / 5 / 1
ctrl_v31_ff_lastdream 73 / 49 / 54 / 44 / 33 / 6 / 0
ctrl_v31_poshead 47 / 66 / 43 / 36 / 31 / 19 / 19
ctrl_v31_poshead_lastdream 47 / 62 / 46 / 38 / 22 / 21 / 16
ctrl_v31_allbands 64 / 51 / 53 / 39 / 23 / 21 / 10
ctrl_v31_allbands_lastdream 65 / 57 / 48 / 43 / 22 / 20 / 15
ctrl_v31_z_only 63 / 60 / 54 / 32 / 25 / 25 / 6
ctrl_v31_z_only_lastdream 51 / 63 / 49 / 37 / 20 / 30 / 8
ctrl_v31_real 61 / 40 / 43 / 30 / 33 / 25 / 30
ctrl_v31_real_lastdream 53 / 53 / 42 / 38 / 26 / 23 / 32

Paddle motion during occlusion

Over the descending hidden runs: the fraction of hidden frames whose ACTION moved the paddle toward the eventual landing x (chance 1/3 — three actions, STAY counts as not-toward), and the displacement the paddle actually achieved toward the landing point while blind, as a fraction of the required move.

oracle is not the ceiling for these two columns and should not be read as one: it chases the ball’s CURRENT x rather than its landing x, and it is usually already inside its dead zone when the ball vanishes, so it STAYs. The references that mean something here are chance (1/3) and wait_and_see (0.000 by construction).

controller hidden runs mean hidden frames mean required move moved on (frac. of hidden frames) toward / all hidden frames (chance 1/3) toward / moving frames (chance 1/2) displacement fraction
stay 264 21.8 0.260 0.000 0.000 [0.000, 0.000] – [–, –] 0.000 [0.000, 0.000]
random 261 21.7 0.331 0.671 0.278 [0.234, 0.322] 0.414 [0.355, 0.476] 0.202 [0.125, 0.284]
oracle 250 22.3 0.265 0.509 0.456 [0.434, 0.480] 0.897 [0.868, 0.926] 0.793 [0.747, 0.843]
wait_and_see 253 21.9 0.280 0.000 0.000 [0.000, 0.000] – [–, –] 0.000 [0.000, 0.000]
ctrl_v31 261 21.6 0.235 0.519 0.326 [0.306, 0.347] 0.628 [0.593, 0.662] 0.280 [0.209, 0.351]
ctrl_v31_lastdream 265 21.7 0.235 0.519 0.311 [0.292, 0.329] 0.599 [0.565, 0.632] 0.208 [0.137, 0.276]
ctrl_v31_tau1 250 21.6 0.221 0.283 0.193 [0.158, 0.227] 0.682 [0.631, 0.731] 0.215 [0.151, 0.279]
ctrl_v31_tau1_lastdream 261 21.7 0.229 0.522 0.286 [0.273, 0.301] 0.548 [0.525, 0.572] 0.100 [0.053, 0.149]
ctrl_v31_ff 261 21.7 0.227 0.109 0.086 [0.063, 0.111] 0.791 [0.704, 0.864] 0.125 [0.078, 0.172]
ctrl_v31_ff_lastdream 259 21.9 0.224 0.032 0.030 [0.016, 0.046] 0.940 [0.836, 1.000] 0.059 [0.030, 0.090]
ctrl_v31_poshead 261 21.6 0.278 0.508 0.338 [0.315, 0.360] 0.665 [0.621, 0.708] 0.296 [0.216, 0.375]
ctrl_v31_poshead_lastdream 252 21.8 0.272 0.511 0.369 [0.348, 0.391] 0.723 [0.681, 0.763] 0.420 [0.348, 0.496]
ctrl_v31_allbands 261 21.6 0.251 0.225 0.165 [0.132, 0.201] 0.730 [0.656, 0.801] 0.195 [0.126, 0.268]
ctrl_v31_allbands_lastdream 270 21.5 0.257 0.231 0.138 [0.115, 0.163] 0.595 [0.542, 0.648] 0.083 [0.036, 0.133]
ctrl_v31_z_only 265 21.7 0.248 0.149 0.092 [0.058, 0.130] 0.617 [0.561, 0.679] 0.072 [0.038, 0.110]
ctrl_v31_z_only_lastdream 258 21.8 0.263 0.195 0.135 [0.099, 0.174] 0.689 [0.625, 0.762] 0.135 [0.085, 0.189]
ctrl_v31_real 262 21.4 0.304 0.460 0.332 [0.304, 0.362] 0.722 [0.684, 0.761] 0.337 [0.294, 0.380]
ctrl_v31_real_lastdream 267 21.6 0.304 0.750 0.486 [0.462, 0.509] 0.648 [0.631, 0.666] 0.367 [0.323, 0.415]

Overall

controller interceptions/visit interceptions/ep floor visits/ep gap at floor approach sign agreement left/stay/right
stay 0.38 [0.33, 0.44] 0.68 1.77 0.261 0.00/1.00/0.00
random 0.31 [0.25, 0.37] 0.55 1.75 0.327 0.337 0.35/0.32/0.33
oracle 0.99 [0.98, 1.00] 1.67 1.68 0.039 1.000 0.26/0.48/0.26
wait_and_see 0.51 [0.44, 0.58] 0.87 1.70 0.222 1.000 0.11/0.77/0.12
ctrl_v31 0.57 [0.51, 0.63] 1.00 1.75 0.184 0.492 0.30/0.41/0.30
ctrl_v31_lastdream 0.45 [0.40, 0.51] 0.81 1.78 0.201 0.524 0.31/0.39/0.30
ctrl_v31_tau1 0.73 [0.66, 0.80] 1.23 1.68 0.149 0.575 0.25/0.50/0.25
ctrl_v31_tau1_lastdream 0.57 [0.51, 0.64] 1.01 1.75 0.174 0.595 0.29/0.43/0.28
ctrl_v31_ff 0.46 [0.40, 0.53] 0.81 1.75 0.208 0.556 0.10/0.80/0.10
ctrl_v31_ff_lastdream 0.42 [0.36, 0.48] 0.73 1.74 0.215 0.609 0.03/0.96/0.02
ctrl_v31_poshead 0.68 [0.60, 0.75] 1.19 1.75 0.189 0.573 0.30/0.38/0.32
ctrl_v31_poshead_lastdream 0.65 [0.59, 0.72] 1.11 1.69 0.175 0.532 0.31/0.36/0.33
ctrl_v31_allbands 0.47 [0.41, 0.53] 0.82 1.75 0.208 0.442 0.20/0.61/0.18
ctrl_v31_allbands_lastdream 0.42 [0.36, 0.49] 0.77 1.81 0.245 0.463 0.22/0.59/0.19
ctrl_v31_z_only 0.51 [0.45, 0.58] 0.91 1.78 0.212 0.474 0.15/0.72/0.13
ctrl_v31_z_only_lastdream 0.43 [0.36, 0.50] 0.74 1.73 0.245 0.417 0.20/0.64/0.16
ctrl_v31_real 0.65 [0.58, 0.71] 1.14 1.76 0.204 0.570 0.24/0.52/0.23
ctrl_v31_real_lastdream 0.66 [0.59, 0.73] 1.19 1.79 0.199 0.580 0.32/0.38/0.30

Other band (0.13, 0.45)

60 episodes. Read the VAE reconstruction table below before attributing any drop to the controller — in v3 these bands were out of the encoder’s distribution and cost it 133-262x reconstruction error, and in v3.1 the encoder was trained on all three, so the same comparison is finally about the controller.

controller interceptions/visit floor visits/ep toward fraction (move > 0.15) displacement fraction mean hidden frames
oracle 0.99 [0.97, 1.00] 1.72 0.513 0.561 10.3
wait_and_see 0.54 [0.44, 0.64] 1.75 0.000 0.000 10.1
ctrl_v31 0.55 [0.45, 0.65] 1.85 0.294 0.099 10.0
ctrl_v31_ff 0.43 [0.34, 0.52] 1.93 0.358 0.010 9.7
ctrl_v31_poshead 0.30 [0.23, 0.38] 1.93 0.274 -0.035 9.8

Other band (0.13, 0.78)

60 episodes. Read the VAE reconstruction table below before attributing any drop to the controller — in v3 these bands were out of the encoder’s distribution and cost it 133-262x reconstruction error, and in v3.1 the encoder was trained on all three, so the same comparison is finally about the controller.

controller interceptions/visit floor visits/ep toward fraction (move > 0.15) displacement fraction mean hidden frames
oracle 0.97 [0.94, 1.00] 1.73 0.398 0.835 32.4
wait_and_see 0.50 [0.39, 0.60] 1.78 0.000 0.000 31.7
ctrl_v31 0.56 [0.46, 0.65] 1.88 0.401 0.491 31.7
ctrl_v31_ff 0.47 [0.38, 0.56] 1.73 0.550 0.308 31.4
ctrl_v31_poshead 0.16 [0.10, 0.22] 1.80 0.081 -0.011 31.6

VAE reconstruction on each band

The frozen encoder+decoder on frames from datasets collected at each band height, so an other-band drop can be attributed to V or to C.

dataset band recon MSE mean hidden run (frames)
data/v31/val [0.13, 0.63] 0.00006 24.6
data/v31/short [0.13, 0.45] 0.00010 12.2
data/v31/long [0.13, 0.78] 0.00006 30.9

Dream-vs-real transfer

Pearson r between the smoothed best-of-generation dream fitness and the periodic real interception count, per training run (dream_vs_real_all.png, and dream_vs_real.png in each run directory).

run r (smoothed) r (raw) best real int./ep final dream fitness dream env steps real env steps wall clock (s)
ctrl_v31 0.62 0.58 1.33 165.3 15,360,000 196,800 742
ctrl_v31_tau1 -0.16 -0.07 1.58 148.5 15,360,000 196,800 721
ctrl_v31_ff -0.33 -0.32 0.96 131.9 15,360,000 196,800 693
ctrl_v31_poshead 0.73 0.70 1.58 159.0 15,360,000 196,800 737
ctrl_v31_allbands -0.27 -0.26 1.08 143.4 15,360,000 196,800 722
ctrl_v31_z_only 0.45 0.38 1.12 161.6 15,360,000 196,800 682
ctrl_v31_real 0.93 0.65 1.54 1.1 0 1,067,200 1997

GIFs