internal static void Initialize(ILockstepEventsHandler[] helpers, NetworkHelper networkHelper)
        {
            PlayRate = FixedMath.One;
            //PauseCount = 0;

            if (!Loaded)
            {
                Setup();
                Loaded = true;
            }



            DefaultMessageRaiser.EarlyInitialize();

            LSDatabaseManager.Initialize();
            LSUtility.Initialize(1);
            InfluenceCount = 0;
            Time.timeScale = 1f;

            Stalled = true;

            FrameCount          = 0;
            InfluenceFrameCount = 0;
            MainNetworkHelper   = networkHelper;
            AgentController.Initialize();
            ClientManager.Initialize(MainNetworkHelper);

            BehaviourHelperManager.Initialize(helpers);

            GridManager.Initialize();


            CoroutineManager.Initialize();
            FrameManager.Initialize();

            CommandManager.Initialize();


            PhysicsManager.Initialize();
            PlayerManager.Initialize();
            SelectionManager.Initialize();
            InfluenceManager.Initialize();
            ProjectileManager.Initialize();

            DefaultMessageRaiser.LateInitialize();
            BehaviourHelperManager.LateInitialize();
            if (onInitialize != null)
            {
                onInitialize();
            }
        }
        public static void Setup()
        {
            IProjectileDataProvider prov;

            if (LSDatabaseManager.TryGetDatabase <IProjectileDataProvider>(out prov))
            {
                IProjectileData[] projectileData = prov.ProjectileData;
                for (int i = 0; i < projectileData.Length; i++)
                {
                    IProjectileData item = projectileData[i];
                    CodeDataMap.Add(item.Name, item);
                    ProjectilePool.Add(item.Name, new FastStack <LSProjectile>());
                }
            }
        }
        void SaveAgents()
        {
                        #if UNITY_EDITOR
            LSAgent [] allAgents = GameObject.FindObjectsOfType <LSAgent> ();
            FastList <EnvironmentAgentInfo> agentsBuffer = new FastList <EnvironmentAgentInfo> ();

            IAgentDataProvider database;

            if (LSDatabaseManager.TryGetDatabase <IAgentDataProvider> (out database))
            {
                var agentData = database.AgentData;
                Dictionary <GameObject, string> prefabCodeMap = new Dictionary <GameObject, string> ();
                foreach (var item in agentData)
                {
                    prefabCodeMap.Add(item.GetAgent().gameObject, item.Name);
                }
                foreach (var agent in allAgents)
                {
                    GameObject prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(agent.gameObject) as GameObject;
                    string     agentCode;
                    if (prefabCodeMap.TryGetValue(prefab, out agentCode))
                    {
                        Vector3d             pos       = new Vector3d(agent.transform.position);
                        Vector2d             rot       = Vector2d.CreateRotation(agent.transform.eulerAngles.y * Mathf.Deg2Rad);
                        EnvironmentAgentInfo agentInfo = new EnvironmentAgentInfo(
                            agentCode,
                            agent,
                            pos,
                            rot
                            );
                        agentsBuffer.Add(agentInfo);
                    }
                    else
                    {
                        Debug.LogError(agent + " does not exist in 'Agents' database");
                    }
                }
                this._environmentAgents = agentsBuffer.ToArray();
            }
            else
            {
                Debug.LogError("No database");
            }
                        #endif
        }
        public static void Setup()
        {
            IEffectDataProvider database;

            if (LSDatabaseManager.TryGetDatabase <IEffectDataProvider>(out database))
            {
                IEffectData[] effectData = database.EffectData;
                EffectPool  = new Dictionary <string, FastStack <LSEffect> >(effectData.Length);
                CodeDataMap = new Dictionary <string, IEffectData>(effectData.Length);
                for (int i = 0; i < effectData.Length; i++)
                {
                    IEffectData dataItem = effectData [i];
                    string      code     = (string)dataItem.Name;
                    EffectPool.Add(code, new FastStack <LSEffect>());
                    CodeDataMap.Add(code, dataItem);
                }
            }
        }
        public static void Setup()
        {
            IInputDataProvider provider;

            if (LSDatabaseManager.TryGetDatabase <IInputDataProvider> (out provider))
            {
                InputDataItem[] inputData = provider.InputData;
                for (int i = inputData.Length - 1; i >= 0; i--)
                {
                    InputDataItem item = inputData[i];
                    ushort        id   = (ushort)(i + 1);
                    string        code = inputData[i].Name;
                    InputMap.Add(code, id);
                    InputDataMap.Add(code, item);
                }
                Setted = true;
            }
        }
        public static void Initialize(GameManager gameManager)
        {
            MainGameManager = gameManager;


            SimulationTimer.Reset();
            SimulationTimer.Start();
            LSDatabaseManager.Initialize();
            LSUtility.Initialize(1);
            Interfacing.Initialize();
            InfluenceCount = 0;
            Time.timeScale = 1f;
            Stalled        = true;

            FrameCount          = 0;
            InfluenceFrameCount = 0;

            GridManager.Generate();
            GridManager.Initialize();

            TeamManager.Initialize();

            CoroutineManager.Initialize();
            FrameManager.Initialize();

            CommandManager.Initialize();
            BehaviourHelper.GlobalInitialize();

            AgentController.Initialize();
            TeamManager.LateInitialize();

            PhysicsManager.Initialize();
            PlayerManager.Initialize();
            SelectionManager.Initialize();
            InfluenceManager.Initialize();
            ProjectileManager.Initialize();

            LoadSceneObjects();

            Started = true;
            ClientManager.Initialize();
        }
        public static void Setup()
        {
            IInputDataProvider provider;

            //TODO: Implement this pattern for all database retrieval
            if (!LSDatabaseManager.TryGetDatabase <IInputDataProvider>(out provider))
            {
                Debug.LogError("IInputDataProvider unavailable.");
            }

            InputDataItem[] inputData = provider.InputData;
            for (int i = inputData.Length - 1; i >= 0; i--)
            {
                InputDataItem item = inputData[i];
                ushort        id   = (ushort)(i + 1);
                string        code = inputData[i].Name;
                InputMap.Add(code, id);
                InputDataMap.Add(code, item);
            }
            Setted = true;
        }
        // public static string[] AvatarCodes;

        #endregion

        #region MonoBehavior
        public static void Setup()
        {
            IAgentDataProvider agentDatabase;

            if (LSDatabaseManager.TryGetDatabase <IAgentDataProvider>(out agentDatabase))
            {
                AgentData  = agentDatabase.AgentData;
                AgentCodes = new string[AgentData.Length];

                AgentController.CachedAgents = new Dictionary <string, FastStack <LSAgent> >(AgentData.Length);

                OrganizerObject = LSUtility.CreateEmpty().transform;
                OrganizerObject.gameObject.name = "OrganizerObject";
                OrganizerObject.gameObject.SetActive(false);

                GameObject.DontDestroyOnLoad(OrganizerObject);
                for (int i = 0; i < AgentData.Length; i++)
                {
                    IAgentData interfacer = AgentData[i];
                    string     agentCode  = interfacer.Name;
                    AgentCodes[i] = agentCode;

                    AgentController.CachedAgents.Add(agentCode, new FastStack <LSAgent>(2));
                    AgentCodeInterfacerMap.Add(agentCode, interfacer);
                    AgentCodeIndexMap.Add(agentCode, (ushort)i);
                }
            }
            else
            {
                Debug.Log("Database does not provide AgentData. Make sure it implements IAgentDataProvider.");
            }

            IWorldObjectDataProvider worldObjectDatabase;

            if (LSDatabaseManager.TryGetDatabase <IWorldObjectDataProvider>(out worldObjectDatabase))
            {
                WorldObjectData  = worldObjectDatabase.WorldObjectData;
                WorldObjectCodes = new string[AgentData.Length];

                for (int i = 0; i < WorldObjectData.Length; i++)
                {
                    IWorldObjectData interfacer      = WorldObjectData[i];
                    string           worldObjectCode = interfacer.Name;
                    WorldObjectCodes[i] = worldObjectCode;

                    WorldObjectCodeInterfacerMap.Add(worldObjectCode, interfacer);
                }
            }
            else
            {
                Debug.Log("Database does not provide WorldObjectData. Make sure it implements IWorldObjectDataProvider.");
            }

            IAvatarDataProvider avatarDatabase;

            if (LSDatabaseManager.TryGetDatabase <IAvatarDataProvider>(out avatarDatabase))
            {
                AvatarData = avatarDatabase.AvatarData;
                Avatars    = new Texture2D[AvatarData.Length];

                for (int i = 0; i < AvatarData.Length; i++)
                {
                    IAvatarData interfacer = AvatarData[i];
                    Texture2D   avatar     = interfacer.GetAvatar();
                    //  AvatarCodes[i] = avatarCode;
                    Avatars[i] = avatar;
                    // AvatarCodeInterfacerMap.Add(avatarCode, interfacer);
                }
            }
            else
            {
                Debug.Log("Database does not provide WorldObjectData. Make sure it implements IWorldObjectDataProvider.");
            }
        }