Page 3 of 3 FirstFirst 123
Results 21 to 26 of 26
  1. #21
    Join Date
    Feb 2015
    Location
    Turkiye
    Posts
    18
    The source code i work now is the exact same as the chapter 1-2-3's and your photon 4 upgrade code. The only difference is the name "SebilgiMOBA" instead of "BuzzMMO". I'll give the code for the above youtube video presentation and i'll prepare a video which shows necessary adjustments step by step approach. (When you see the code you may think it's not the ideal way but it's well enough for me) For future plan, firstly, i must say, for me it was crucial at least understanding the core concept behind the Nelson's code. Seeing other player movements in every client would be enough for me. I don't plan going any further. Photon's new deterministic quantum server client will be my next goal. After almost two years of replicating Nelson's framework i've learnt so much and i'm happy where i am now.Many thanks for your effort and explanations here in forums about MMO.

  2. #22
    Join Date
    Aug 2010
    Posts
    133
    I actually just spent the time over the holidays to fully separate the framework and game into completely different DLLs. This makes it easier to have a framework that others can leverage, a demo game experience, and then what ever you want to build with it in its own project. I have had synchronized moving working for a while now, but I am still planning to continue working on this.

    Current Project List
    • MMO.Build.Tasks - Don't use anymore, but have not removed yet
    • MMO.Build.Tools - Hoping to remove this as well and change to a new code generate method
    • MMO.Framework.Base
    • MMO.Framework.Client
    • MMO.Framework.Client.DotNet
    • MMO.Framework.Client.Unity
    • MMO.Framework.Server
    • MMO.Game.Base.Components - Still contains some [ComponentInterface] Systems, but I am hoping to move this out to the Common namespace
    • MMO.Game.Client.DotNet.Console
    • MMO.Game.Client.Unity
    • MMO.Game.Common.Server - Creating common dlls instead of a single base. Clients to server need differnt info than server to server
    • MMO.Game.Data
    • MMO.Game.Launcher
    • MMO.Game.Server.Login - New for MMO Login Server
    • MMO.Game.Server.Master
    • MMO.Game.Server.Region
    • MMO.Game.Tests - I will probably create a Test Project for every DLL instead of having 1 Test Project
    • MMO.Game.Web - Going to fully rebuild this project in the future


    Next Steps - In basic order of where I want to take this
    • Refactor MMO.Game.Base.Components in the MMO.Game.Common.Server and MMO.Game.Common.ServerClient namespaces.
    • Bail on MOBA and move to MMO based (starting this)
    • Create a character selection system (already in basic working form)
    • Move away from SQL to an actor framework or something similar like MS Orleans
    • Host everything in Azure
    • Create a tiny demo world where players can connect to
    • Create some basic AI NPCs
    • Figure out path finding as our server emulation does not understand Unity physics and path finding


    Major Changes
    Move away from zones and look into graph based approaches that can be scaled horizontally to be more efficient. My main idea here would be a world that works more like cell phone towers in real life that allow people to connect to multiple and move through an area by dynamically switching servers seamlessly.
    Last edited by am385; 01-19-2018 at 03:37 PM.

  3. #23
    Join Date
    Feb 2015
    Location
    Turkiye
    Posts
    18

    How to see other player's movements




    Client side codes,
    MainControl.cs:

    Code:
    using Assets.Code.GameServer;
    using Assets.Code.GameServer.Systems;
    using SebilgiMOBA.Base.Async;
    using SebilgiMOBA.Base.Components.Systems.Region;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    namespace Assets.Code
    {
    
        public class MainControl : ReceiveGameServer
        {
            public GameObject cubePrefab;
    
            private GameObject cube;
            private GameServer.GameServer _gameServer;
            private IGameInfoServer gis;
            
            public override void SetGameServer(GameServer.GameServer server)
            {
                _gameServer = server;
            }
    
            void Start()
            {
                SceneManager.SetActiveScene(SceneManager.GetSceneB  yName("Level1"));
                cube = Instantiate(cubePrefab);
            }
    
            void Update()
            {
                if (Input.GetKeyDown("right"))
                {
                    gis = _gameServer.Systems.Systems.Get<GameInfo>().Proxy;
                    int number = 0;
                    Deferred<int> temp = gis.LearnId();
                    temp.OnSuccess(res =>
                    {
                        number=res.Result;
                        cube.name = number.ToString();
                        cube.transform.Find("text").GetComponent<TextMesh>().text = number.ToString();
                        gis.ConfirmPos(number, cube.transform.position.x);
                    });
    
                    cube.transform.Translate(new Vector3(0.1f, 0, 0));
    
                }
            }
    
        }
    
    }
    GameInfo.cs

    Code:
    using System.Linq;
    using Assets.Code.Infrastructure;
    using SebilgiMOBA.Base.Components;
    using SebilgiMOBA.Base.Components.Systems.Region;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    namespace Assets.Code.GameServer.Systems
    {
        public class GameInfo : UnitySystemBase<IGameInfoServer, IGameInfoClient>
            , IGameInfoClient
        {
            public void AddPlayer(GamePlayerDetails player)
            {
                Debug.Log(player);
            }
    
            public void UpdatePlayer(GamePlayerDetails player)
            {
                Debug.Log(player);
            }
    
            public void MovePlayer(int id, float pos)
            {
                GameObject[] objs = SceneManager.GetSceneByName("Level1").GetRootGameObjects();
                if (!objs.FirstOrDefault(t => t.name == id.ToString()))
                {
                    GameObject trnew = (GameObject) Instantiate(Resources.Load("Prefabs/Cube"));
                    trnew.name = id.ToString();
                    trnew.transform.Find("text").GetComponent<TextMesh>().text = id.ToString();
                    trnew.transform.Translate(new Vector3(pos - trnew.transform.position.x, 0, 0));
                }
                else
                {
                    Transform tr = objs.First(t => t.name == id.ToString()).transform;
                    tr.Translate(new Vector3(pos - tr.transform.position.x, 0, 0));
    
                }
            }
        }
    }

    Server side codes,
    GameInfo.cs:

    Code:
    using SebilgiMOBA.Base.Async;
    
    namespace SebilgiMOBA.Base.Components.Systems.Region
    {
        [ComponentInterface]
        public interface IGameInfoServer
        {
            Deferred<int> LearnId();
            Deferred ConfirmPos(int id, float pos);
        }
    
        [ComponentInterface]
        public interface IGameInfoClient
        {
            void AddPlayer(GamePlayerDetails player);
            void UpdatePlayer(GamePlayerDetails player);
            void MovePlayer(int id, float pos);
        }
    }

    GameInfoSystem.cs:

    Code:
    using SebilgiMOBA.Base.Async;
    using SebilgiMOBA.Base.Components.Systems.Region;
    
    namespace SebilgiMOBA.Server.Region.Systems
    {
        public class GameInfoSystem : PlayerSystemBase<IGameInfoServer, IGameInfoClient>
            , IGameInfoServer
        {
            private PlayerInGame pInGame;
            public PlayerInGame PInGame { get => pInGame; set => pInGame = value; }
    
            private RunningGame rg;
            public RunningGame Rg { get => rg; set => rg = value; }
    
            public Deferred<int> LearnId()
            {
                Deferred<int> temp = new Deferred<int>();
                temp.SetResult(true, null, PInGame.Details.Id);
                return temp;
            }
    
            public Deferred ConfirmPos(int id, float pos)
            {
                Rg.ConfirmPos(id, pos);
                return Deferred.Success();
            }
        }
    }
    RunningGame.cs:

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using SebilgiMOBA.Base;
    using SebilgiMOBA.Base.Components;
    using SebilgiMOBA.Base.Components.Systems.Region;
    using SebilgiMOBA.Data.Services;
    using SebilgiMOBA.Server.Region.Systems;
    
    namespace SebilgiMOBA.Server.Region
    {
        public class RunningGame : IDisposable
        {
            private readonly GameEntityService _service;
            private readonly Dictionary<int, PlayerInGame> _players;
            private readonly IGameInfoClient _proxy;
    
            public event Action<RunningGame> OnDestroyed;
            public GameInstance GameInstance { get; }
    
            public RunningGame(GameEntityService service, GameServerContext application
                , GameParameters parameters)
            {
                _service = service;
                var config = application.Config.GameServer;
                var gameEntity = service.CreateGame(config.UniqueId, parameters);
                GameInstance = new GameInstance(gameEntity.Id, gameEntity.LevelName, config.UdpConnection);
                _players = new Dictionary<int, PlayerInGame>();
                _proxy = BroadcastProxy<IGameInfoClient>.Create(application, _players
                    .Where(t => t.Value.IsConnected)
                    .Select(t => t.Value.PlayerConnection.Context.Transport));
    
                foreach (var player in parameters.PlayerDetails)
                {
                    _players.Add(player.Id, new PlayerInGame(new GamePlayerDetails
                    {
                        Id=player.Id,
                        Name=player.Name,
                        Hero=player.Hero,
                        Team=player.Team,
                        HasAbandoned = false,
                        IsConnected = false
                    }));
                }
            }
    
            public void Dispose()
            {
                OnDestroyed?.Invoke(this);
                _service.DestroyGame(GameInstance.Id);
            }
    
            public void AddPlayer(PlayerContextGame context)
            {
                if (context.Systems.Contains<GameInfoSystem>())
                    throw new RpcException("Player is already in a game");
    
                //TODO: SYNC WITH GAME LOOP
    
                context.Disconnected += PlayerDisconnected;
                var system = context.Systems.Create<GameInfoSystem>();
                system.Rg = this;
                var player = _players[context.UserDetails.Id];
                player.PlayerConnected(system);
                system.PInGame = player;
                _proxy.AddPlayer(player.Details);
    
                foreach (var otherPlayer in _players.Values)
                {
                    if (!otherPlayer.IsConnected || otherPlayer==player)
                        continue;
                    system.Proxy.AddPlayer(otherPlayer.Details);
                }
    
            }
    
            public void ConfirmPos(int id, float pos)
            {
                foreach (var player in _players.Values)
                    player.PlayerConnection.Proxy.MovePlayer(id, pos);
            }
    
            private void PlayerDisconnected(ClientContext context)
            {
                //TODO: SYNC WITH GAME LOOP
    
                var player = _players[context.UserDetails.Id];
                player.PlayerDisonnected();
                _proxy.UpdatePlayer(player.Details);
            }
    
        }
    }

  4. #24
    Join Date
    Feb 2014
    Posts
    275
    I am really happy to see others working on moving the buzzmmo code onwards. Please keep us updated.

    byagcioglu:
    Excellent. The video made it very clear how you do it. Of course it's a proof of concept and I immediately thought of a dozen things to add - but that's to be expected - starting with some code to inform a newly entered player of the world state so it doesn't require movement before the update is sent - I only mention that to prove I watched it

    am385:
    I am glad you are trashing the moba's lobby and join systems. I was getting annoyed with that and eventually thought it needed some statics to hold the lobby list and the game details. Having each player maintain their own lists seems awkward to me, but then again I am still a novice coder. It will be interesting to see how you switch to the character selection / creation screen at login. Your code is rapidly evolving away from Nelson's.


    How do you both feel about Nelson's use of codegeneration to create the data id's instead of hardcoding it?

  5. #25
    Join Date
    Feb 2015
    Location
    Turkiye
    Posts
    18
    How to create a very simplified client from scratch (step by step)
    I share this because it makes easier to understand the client main structure.


    oldngrey: honestly i don't have any idea about alternative way to his method of codegeneration to create the data id's instead of hardcoding it.

  6. #26
    Join Date
    Feb 2015
    Location
    Turkiye
    Posts
    18
    I'll examine the Master Server Framework (MSF) from the assetstore which has wiki page and i'll give my opinions about it. it is free and opensource.

    https://assetstore.unity.com/package...ramework-71391

    Here is a test :
    Last edited by byagcioglu; 02-16-2018 at 03:18 AM.

Page 3 of 3 FirstFirst 123

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •