Game Not Working After Update

My game that has been live for about a month has broken in the last week. I haven’t touched it in that time, so I am assuming a recent update broke it.

The assets in the game move at a certain speed when the game starts. When people score the items move faster and the newly instantiated items inherit that new faster speed. It looks like somehow that script broke. I just found out this was happening from a client text and won’t have time to jump In and debug until tomorrow.

I will attach a video of the game in its current state. This game has had over 300k views and 300k minutes of dwell time over the last month so it is being seen by a lot of people and I would appreciate getting help to fix this quickly.

Here is a link to the game:

continuum.8thwall.app/maverik-redbull-2025/

Project has been shared with support.

Ok I think I fixed the issue here is the code on the rotating objects before my update

// This is a component file. You can use this file to define a custom component for your project.
// This component will appear as a custom component in the editor.

import * as ecs from '@8thwall/ecs'  // This is how you access the ecs library.
const {THREE} = window as any

const RotateContainer = ecs.registerComponent({
  name: 'rotateContainer',
  schema: {
    rotationSpeed: ecs.f32,  // still needed to pass initial value
    poolContainer: ecs.eid,
    activeContainer: ecs.eid,
    childEntity: ecs.eid,
  },
  schemaDefaults: {
    rotationSpeed: 0.3,
  },
  data: {
    rotationSpeed: ecs.f32,
  },
  add: (world, component) => {
    const {schema} = component
    const {data} = component
    data.rotationSpeed = schema.rotationSpeed  // Initialize from schema
  },
  stateMachine: ({world, eid, dataAttribute, schemaAttribute}) => {
    const spawnObject = ecs.defineTrigger()
    const {poolContainer, activeContainer, childEntity} = schemaAttribute.get(eid)
    const data = dataAttribute.cursor(eid)
    const SpawnEntity = (e) => {
      world.setParent(eid, activeContainer)
      const position = e.data.lane
      let newX
      if (position === 0) {
        newX = -4.5
      } else if (position === 1) {
        newX = 0
      } else {
        newX = 4.5
      }
      ecs.Position.set(world, eid, {
        x: newX,
        y: 0,
        z: 0,
      })
      ecs.Quaternion.set(world, eid, {
        x: 0,
        y: 0,
        z: 0,
        w: 1,
      })
      spawnObject.trigger()
    }
    ecs.defineState('inactive').initial()
      .onEnter(() => {
        world.setParent(eid, poolContainer)
        ecs.Position.set(world, eid, {
          x: 0,
          y: 0,
          z: 0,
        })
      })
      .listen(world.events.globalId, 'updateRotationSpeed', (e) => {
        data.rotationSpeed = e.data.speed
      })
      .listen(eid, 'spawn', SpawnEntity)
      .onTrigger(spawnObject, 'active')
    ecs.defineState('active')
      .onEvent('destroy', 'inactive')
      .onEnter(() => {
        world.events.dispatch(childEntity, 'toMoving')
      })
      .onExit(() => {
        world.events.dispatch(childEntity, 'toIdle')
      })
      .onTick(() => {
        const dt = world.time.delta / 1000
        const speed = data.rotationSpeed
        const q = ecs.Quaternion.get(world, eid) ?? {x: 0, y: 0, z: 0, w: 1}
        const axis = new THREE.Vector3(speed, 0, 0)
        const angle = axis.length() * dt

        if (angle > 0) {
          axis.normalize()
          const deltaQuat = new THREE.Quaternion().setFromAxisAngle(axis, angle)
          const currentQuat = new THREE.Quaternion(q.x, q.y, q.z, q.w)
          currentQuat.multiply(deltaQuat)
          ecs.Quaternion.set(world, eid, {
            x: currentQuat.x,
            y: currentQuat.y,
            z: currentQuat.z,
            w: currentQuat.w,
          })
        }
      })
      .listen(world.events.globalId, 'updateRotationSpeed', (e) => {
        data.rotationSpeed = e.data.speed
      })
  },
})

export {RotateContainer}

and here it is post update:

// This is a component file. You can use this file to define a custom component for your project.
// This component will appear as a custom component in the editor.

import * as ecs from '@8thwall/ecs'  // This is how you access the ecs library.
const {THREE} = window as any

const RotateContainer = ecs.registerComponent({
  name: 'rotateContainer',
  schema: {
    rotationSpeed: ecs.f32,  // still needed to pass initial value
    poolContainer: ecs.eid,
    activeContainer: ecs.eid,
    childEntity: ecs.eid,
  },
  schemaDefaults: {
    rotationSpeed: 0.3,
  },
  data: {
    rotationSpeed: ecs.f32,
  },
  add: (world, component) => {
    const {schema} = component
    const {data} = component
    data.rotationSpeed = schema.rotationSpeed  // Initialize from schema
  },
  stateMachine: ({world, eid, dataAttribute, schemaAttribute}) => {
    const spawnObject = ecs.defineTrigger()
    const {poolContainer, activeContainer, childEntity} = schemaAttribute.get(eid)
    const dataGet = dataAttribute.get(eid)
    const SpawnEntity = (e) => {
      world.setParent(eid, activeContainer)
      const position = e.data.lane
      let newX
      if (position === 0) {
        newX = -4.5
      } else if (position === 1) {
        newX = 0
      } else {
        newX = 4.5
      }
      ecs.Position.set(world, eid, {
        x: newX,
        y: 0,
        z: 0,
      })
      ecs.Quaternion.set(world, eid, {
        x: 0,
        y: 0,
        z: 0,
        w: 1,
      })
      spawnObject.trigger()
    }
    ecs.defineState('inactive').initial()
      .onEnter(() => {
        world.setParent(eid, poolContainer)
        ecs.Position.set(world, eid, {
          x: 0,
          y: 0,
          z: 0,
        })
      })
      .listen(world.events.globalId, 'updateRotationSpeed', (e) => {
        dataAttribute.cursor(eid).rotationSpeed = e.data.speed
      })
      .listen(eid, 'spawn', SpawnEntity)
      .onTrigger(spawnObject, 'active')
    ecs.defineState('active')
      .onEvent('destroy', 'inactive')
      .onEnter(() => {
        world.events.dispatch(childEntity, 'toMoving')
      })
      .onExit(() => {
        world.events.dispatch(childEntity, 'toIdle')
      })
      .onTick(() => {
        const dt = world.time.absoluteDelta / 1000
        const speed = dataGet.rotationSpeed
        const q = ecs.Quaternion.get(world, eid) ?? {x: 0, y: 0, z: 0, w: 1}
        const axis = new THREE.Vector3(speed, 0, 0)
        const angle = axis.length() * dt

        if (angle > 0) {
          axis.normalize()
          const deltaQuat = new THREE.Quaternion().setFromAxisAngle(axis, angle)
          const currentQuat = new THREE.Quaternion(q.x, q.y, q.z, q.w)
          currentQuat.multiply(deltaQuat)
          ecs.Quaternion.set(world, eid, {
            x: currentQuat.x,
            y: currentQuat.y,
            z: currentQuat.z,
            w: currentQuat.w,
          })
        }
      })
      .listen(world.events.globalId, 'updateRotationSpeed', (e) => {
        dataAttribute.cursor(eid).rotationSpeed = e.data.speed
      })
  },
})

export {RotateContainer}

So the big difference is in the way i was handling const {data} = dataAttribute.cursor(eid) in the state machine. in the old version I was doing it like that. I had 2 ways I was using it, one as a set and one as a get. I swapped all of the gets to const dataGet = dataAttribute.get(eid) and in the code am now setting using dataAttribute.cursor(eid) directly and it seems to be working.

essentially my data was never changing over to the new data before and now it is. It may have been my fault because I was using some sort of Dangling Listeners to start but it is weord that one day it was working and the next it wasn’t.