{
  "version": "v2",
  "possession": {
    "controllers": [
      {
        "id": "player_controls",
        "kind": "possession",
        "bind": {
          "object": "Player"
        },
        "mode": "exclusive",
        "inputs": {
          "keyboard": true,
          "gamepad": true
        },
        "keys": {
          "left": ["a", "arrowleft"],
          "right": ["d", "arrowright"],
          "forward": ["w", "arrowup"],
          "back": ["s", "arrowdown"],
          "jump": ["space"],
          "boost": ["e"],
          "spinLeft": ["u"],
          "spinRight": ["o"]
        },
        "gamepad": {
          "index": 0,
          "axes": {
            "moveX": 0,
            "moveZ": 1
          },
          "buttons": {
            "jump": 0,
            "boost": 1,
            "spinLeft": 4,
            "spinRight": 5
          },
          "deadzone": 0.15
        },
        "map": {
          "speedXZ": 8,
          "jumpVy": 5,
          "torqueY": 16,
          "boostScale": 1.6
        }
      }
    ]
  },
  "policy": {
    "models": [
      {
        "id": "cube_driver_v1",
        "shape": {
          "input": 7,
          "hidden": [32, 16],
          "output": 6,
          "activations": ["relu", "relu"],
          "head": "softmax"
        },
        "snapshotKey": "cube_driver.snapshot:v1",
        "seed": 2222,
        "recreateIfShapeDiffers": true
      }
    ],
    "controllers": [
      {
        "id": "ai_drives_cube",
        "kind": "policy",
        "bind": {
          "object": "Crate"
        },
        "clock": {
          "rateHz": 20
        },
        "policy": {
          "model": {
            "id": "cube_driver_v1",
            "ensureIfMissing": true,
            "shape": {
              "input": 7,
              "hidden": [32, 16],
              "output": 6,
              "activations": ["relu", "relu"],
              "head": "softmax"
            },
            "snapshotKey": "cube_driver.snapshot:v1"
          },
          "obs": {
            "botPos": "truth://Crate/position",
            "tgtPos": "truth://Player/position",
            "selfVel": "truth://Crate/velocity"
          },
          "input": [
            "clamp((tgtPos[0]-botPos[0])/6,-1,1)",
            "clamp((tgtPos[1]-botPos[1])/6,-1,1)",
            "clamp((tgtPos[2]-botPos[2])/6,-1,1)",
            "clamp(selfVel[0]*0.5,-1,1)",
            "clamp(selfVel[1]*0.5,-1,1)",
            "clamp(selfVel[2]*0.5,-1,1)",
            "1"
          ],
          "action": {
            "type": "discrete",
            "table": [
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: 200, y: 0, z: 0 }" }
                ]
              },
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: -200, y: 0, z: 0 }" }
                ]
              },
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: 0, y: 0, z: 200 }" }
                ]
              },
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: 0, y: 0, z: -200 }" }
                ]
              },
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: 0, y: 200, z: 0 }" }
                ]
              },
              {
                "effectors": [
                  { "type": "wake" },
                  { "type": "addForce", "expr": "{ x: 0, y: -200, z: 0 }" }
                ]
              }
            ]
          }
        }
      }
    ]
  }
}
