protected override void OnUpdate()
    {
        // Clear Damage Applied Events
        GetSingletonBuffer <EventExplosion>().Clear();

        DynamicBuffer <SystemRequestExplosion> explosionRequestBuffer = GetSingletonBuffer <SystemRequestExplosion>();

        if (explosionRequestBuffer.Length > 0)
        {
            NativeArray <SystemRequestExplosion> requests = explosionRequestBuffer.ToNativeArray(Allocator.Temp);
            explosionRequestBuffer.Clear();
            NativeList <DistanceHit> hits = new NativeList <DistanceHit>(Allocator.Temp);

            foreach (SystemRequestExplosion request in requests)
            {
                if (request.DestroyTiles)
                {
                    DestroyTiles(request.Position, request.Radius);
                }

                if (CommonReads.Physics.OverlapCircle(Accessor, request.Position, request.Radius, hits))
                {
                    CommonWrites.RequestDamage(Accessor, hits, request.Damage);

                    if (request.Damage > 0)
                    {
                        // request impulses for every hit
                        foreach (DistanceHit hit in hits)
                        {
                            if (!HasComponent <PhysicsVelocity>(hit.Entity))
                            {
                                continue;
                            }

                            _applyImpulseSystem.RequestImpulseRadial(new RadialImpulseRequestData()
                            {
                                StrengthMin = IMPULSE_MIN,
                                StrengthMax = IMPULSE_MAX,
                                IgnoreMass  = false,
                                Position    = request.Position,
                                Radius      = request.Radius,
                                Target      = hit.Entity
                            });
                        }
                    }
                }

                _newExplosionEvents.Add(new EventExplosion()
                {
                    Position = request.Position, Radius = request.Radius
                });
            }

            var explosionEvents = GetSingletonBuffer <EventExplosion>();
            foreach (EventExplosion evnt in _newExplosionEvents)
            {
                explosionEvents.Add(evnt);
            }
            _newExplosionEvents.Clear();
        }
    }
    // Add new cheat classes here!

    public void HandleCheat(SimCheatInput cheat)
    {
        switch (cheat)
        {
        case SimInputCheatToggleInvincible toggleInvicible:
        {
            Entity groupHeader = GetSingletonEntity <PlayerGroupDataTag>();

            if (EntityManager.Exists(groupHeader))
            {
                const int DISTANT_FUTURE = 9999999;
                if (TryGetComponent(groupHeader, out InvincibleUntilTime invincibleUntilTime))
                {
                    EntityManager.AddComponentData(groupHeader, new InvincibleUntilTime()
                        {
                            Time = invincibleUntilTime.Time == DISTANT_FUTURE ? 0 : DISTANT_FUTURE
                        });
                }
                else
                {
                    EntityManager.AddComponentData(groupHeader, new InvincibleUntilTime()
                        {
                            Time = DISTANT_FUTURE
                        });
                }
            }
            break;
        }

        case SimInputCheatDamageSelf damagePlayer:
        {
            Entity player = CommonReads.FindPlayerEntity(Accessor, damagePlayer.PlayerId);

            if (EntityManager.Exists(player) &&
                EntityManager.TryGetComponentData(player, out ControlledEntity pawn))
            {
                if (damagePlayer.Damage > 0)
                {
                    CommonWrites.RequestDamage(Accessor, pawn, damagePlayer.Damage);
                }
                else
                {
                    CommonWrites.RequestHeal(Accessor, pawn, -damagePlayer.Damage);
                }
            }
            break;
        }

        case SimInputCheatAddAllItems addAllItems:
        {
            Entity player = CommonReads.FindPlayerEntity(Accessor, addAllItems.PlayerId);

            if (EntityManager.Exists(player) &&
                EntityManager.TryGetComponentData(player, out ControlledEntity pawn))
            {
                if (HasComponent <InventoryCapacity>(pawn))
                {
                    SetComponent <InventoryCapacity>(pawn, 999);
                }

                var itemBankSystem = Accessor.GetExistingSystem <GlobalItemBankSystem>();
                var allItems       = itemBankSystem.GetAllItemPrefabs();

                NativeArray <(Entity item, int stack)> itemTransfers = new NativeArray <(Entity item, int stack)>(allItems.Length, Allocator.Temp);

                for (int i = 0; i < allItems.Length; i++)
                {
                    itemTransfers[i] = (allItems[i], 99);
                }

                ItemTransationBatch itemTransationBatch = new ItemTransationBatch()
                {
                    Source         = null,
                    Destination    = pawn,
                    ItemsAndStacks = itemTransfers,
                    OutResults     = default
                };

                CommonWrites.ExecuteItemTransaction(Accessor, itemTransationBatch);
            }
            break;
        }

        case SimInputCheatTeleport teleport:
        {
            Entity player = CommonReads.FindPlayerEntity(Accessor, teleport.PlayerId);

            if (EntityManager.Exists(player) &&
                EntityManager.TryGetComponentData(player, out ControlledEntity pawn))
            {
                CommonWrites.RequestTeleport(Accessor, pawn, teleport.Destination);
            }
            break;
        }

        case SimInputCheatRemoveAllCooldowns _:
        {
            if (HasSingleton <NoCooldownTag>())
            {
                EntityManager.DestroyEntity(GetSingletonEntity <NoCooldownTag>());
            }
            else
            {
                Entity entity = EntityManager.CreateEntity();
                EntityManager.AddComponentData(entity, new NoCooldownTag());
            }

            break;
        }

        case SimInputCheatImpulseSelf impulseSelf:
        {
            Entity player = CommonReads.FindPlayerEntity(Accessor, impulseSelf.PlayerId);

            if (EntityManager.Exists(player) &&
                EntityManager.TryGetComponentData(player, out ControlledEntity pawn))
            {
                PhysicsVelocity vel = EntityManager.GetComponentData <PhysicsVelocity>(pawn);
                vel.Linear += impulseSelf.ImpulseValue;
                SetComponent <PhysicsVelocity>(pawn, vel);
            }
            break;
        }

        case SimInputCheatSoloPlay soloPlay:
        {
            Entity player = CommonReads.FindPlayerEntity(Accessor, soloPlay.PlayerId);

            if (!HasComponent <ControlledEntity>(player))
            {
                return;
            }

            // _________________________________________ Find Pawns _________________________________________ //
            Entity currentPawn  = Entity.Null;
            Entity newPawn      = Entity.Null;
            int    newPawnIndex = soloPlay.PawnIndex;

            if (EntityManager.TryGetComponentData(player, out ControlledEntity pawn))
            {
                currentPawn = pawn;
            }

            Entities.ForEach((Entity entity, in PlayerGroupMemberIndex memberIndex) =>
                {
                    if (memberIndex == newPawnIndex)
                    {
                        newPawn = entity;
                    }
                }).Run();


            // _________________________________________ Update Possession _________________________________________ //
            if (currentPawn != Entity.Null)
            {
                SetComponent <Controllable>(currentPawn, default);
            }

            if (newPawn != Entity.Null)
            {
                SetComponent <Controllable>(newPawn, player);
            }

            SetComponent <ControlledEntity>(player, newPawn);

            // _________________________________________ Disable Auto Attack on Others _________________________________________ //
            Entities.WithAll <PlayerGroupMemberIndex>()
            .ForEach((Entity entity, DynamicBuffer <InventoryItemReference> inventory) =>
                {
                    // implementation note: Keep 'EntityManager.HasComponent', otherwise it will cause an "invalidated by a structural change" exception
                    var items = inventory.ToNativeArray(Allocator.Temp);
                    if (entity != newPawn)
                    {
                        foreach (var item in items)
                        {
                            if (EntityManager.HasComponent <AutoAttackProgress>(item.ItemEntity))
                            {
                                EntityManager.RemoveComponent <AutoAttackProgress>(item.ItemEntity);
                            }
                        }
                    }
                    else
                    {
                        foreach (var item in items)
                        {
                            if (!EntityManager.HasComponent <AutoAttackProgress>(item.ItemEntity) && EntityManager.HasComponent <ShouldAutoAttack>(item.ItemEntity))
                            {
                                EntityManager.AddComponent <AutoAttackProgress>(item.ItemEntity);
                            }
                        }
                    }
                }).WithoutBurst()
            .WithStructuralChanges()
            .Run();

            break;
        }
        }
    }