Forums » Off-Topic and Casual Chatter

Whew! MMOs are a bear!

    • 36 posts
    January 11, 2020 6:11 PM PST

    Hello all, Chroma here,

    Been working on a C# MMO server for a few months and I will say, it's not the coding that's hard, it's the decisions of data structure that is difficult. Been working on this mostly as a test for myself and writing the server in Visual Studio 2019 (C# console) and the client in Unity 2019.x.x. I really like how you can serialize the Unity data (Vector3), send it, and then deserialize that data within a custom class in C#. Had no luck with trying to serialize C# native System.Numerics Vector classes (C#) and wasted quite a bit of time on that...ugh { get; set; } is worthless. Sitting here working this out makes me think of Brad and all the issues his team had back in the late 90s early 00s. I'm sure Brad and myself would have gotten along great and I would have learned a lot from him. So I shall press on writing this vision of an MMO based on folklore and all the stories we heard growing up (three little pigs, baba yaga, but darker!). No threat to Pantheon by far! I am a one man coding army.

    On another note, hope everyone is doing well and prospering in 2020. Godspeed (Aradune).

    -Chroma


    This post was edited by Chroma at January 12, 2020 1:58 PM PST
    • 557 posts
    January 11, 2020 10:11 PM PST

    Interesting post, Chroma.   Tackling an MMO as a solo project is pretty daunting, considering the first M stands for "Massively".   If you are looking for others to test your game, I'm sure you'd find no shortage of experienced volunteers on these forums.

    • 36 posts
    January 12, 2020 1:52 PM PST

    Well when the time comes testers would be greatly appreciated!

    • 1281 posts
    January 18, 2020 6:49 PM PST

    Chroma said:

    Hello all, Chroma here,

    Been working on a C# MMO server for a few months and I will say, it's not the coding that's hard, it's the decisions of data structure that is difficult. Been working on this mostly as a test for myself and writing the server in Visual Studio 2019 (C# console) and the client in Unity 2019.x.x. I really like how you can serialize the Unity data (Vector3), send it, and then deserialize that data within a custom class in C#. Had no luck with trying to serialize C# native System.Numerics Vector classes (C#) and wasted quite a bit of time on that...ugh { get; set; } is worthless. Sitting here working this out makes me think of Brad and all the issues his team had back in the late 90s early 00s. I'm sure Brad and myself would have gotten along great and I would have learned a lot from him. So I shall press on writing this vision of an MMO based on folklore and all the stories we heard growing up (three little pigs, baba yaga, but darker!). No threat to Pantheon by far! I am a one man coding army.

    On another note, hope everyone is doing well and prospering in 2020. Godspeed (Aradune).

    -Chroma

    That's great that you are working on that project.

    If you are interested in learning more about building an MMO, check out Jason Weimann's (Pantheon Developer) YouTube channel. He has a lot of content that talks about best practices regarding data and other factors while building MMO's. His content is all mostly game agnostic, he doesn't really talk about Pantheon, more about developing in general.

    https://www.youtube.com/channel/UCX_b3NNQN5bzExm-22-NVVg/videos

    https://unity3d.college/

    This was the first video of his I watched. Even though I'm not a developer I found this really cool info.

    https://www.youtube.com/watch?v=SNmu5t_oqhE

    For everyone else, he had Kyle Olsen (another Pantheon dev) on his channel a few weeks ago talking about Pantheon a little bit and other MMO stuff. Was a great watch.

    https://www.youtube.com/watch?v=5b6k_ywdjw4

     


    This post was edited by bigdogchris at January 18, 2020 6:52 PM PST
    • 36 posts
    February 19, 2020 8:43 PM PST

    Thanks Chris I will check out the videos. I'm still plugging away at it. Currently spinning myself up on SQLite which is an incredibly easy to use database. I think the hardest part I'm facing right now is design choices and data structures. Also what the server controls and what it lets the client control. I'm currently using JSON to serialize packet payloads and that seems to be working well because you can deserialize them back into the native objects and keep on trucking. But I will say, after working on this for only a month and a half, I can see why it takes years to make an MMO. I currently focusing on the underlying mechanics. I have a test zone I run around in but it's just a basic Unity terrain with some trees. On a good note, I'm really loving C# and becoming very proficient in it to say the least!

    • 36 posts
    February 21, 2020 6:13 PM PST

    So I went from trying to do my own version of EQ to really going back to what got me into RPGs in the first place. The red box set of D&D from 1983. I'm shifing gears and using it as a guide so I can stop doing the content creation and really get into the underlying code to make it work. Trying to stay true to the THAC0 combat mechanics and whatnot. Really would like to see how that early D&D combat system would work in a real-time MMO. Wrote a dice roller that inputs a string (felt it would be more intuitive). It works but I'm still trying to determine how efficient it is. At the moment the working name of the game is Red Box Online. Tried to get that domain but ended up settling with http://redboxmmo.com/.

    // example: int dmg = Roll("1d4+1")

    public static int Roll(string input) {
       string[] dd = input.Split('d');
       int n = int.Parse(dd[0]);
       int die = 0, mod = 0;
       if (!dd[1].Contains('+') && !dd[1].Contains('-')) {
          die = int.Parse(dd[1]);
       } else if (dd[1].Contains('+')) {
          Console.WriteLine("bonus"); // testing
          string[] tmp = dd[1].Split('+');
          die = int.Parse(tmp[0]);
          mod = int.Parse(tmp[1]);
       } else if (dd[1].Contains('-')) {
          Console.WriteLine("penalty");  // testing
          int index = dd[1].IndexOf('-');
          die = int.Parse(dd[1].Substring(0, index));
          mod = int.Parse(dd[1].Substring(index, dd[1].Length - index));
       }
       int result = 0;
       for (int i = 0; i < n; i++) result += _rand.Next(1, die + 1);
       result += mod;
       return result;
    }


    This post was edited by Chroma at February 21, 2020 6:33 PM PST
    • 36 posts
    February 22, 2020 5:26 PM PST

    Wow, back in 1983 there was no THAC0! All players were on the same hit table.

    namespace RedBox {
    public abstract class Common {

       /*
       No armor   9
       Leather    7
       Chain Mail 5
       Plate Mail 3
       Shield    -1
       20 is always a hit, less than 10 is always a miss (no armor)
       */                                        0   1   2   3   4   5   6   7   8   9
       public static int[] charHitRollTable = { 19, 18, 17, 16, 15, 14, 13, 12, 11, 10 };

       public const int maxLevel = 3;

     


    This post was edited by Chroma at February 22, 2020 5:49 PM PST
    • 36 posts
    February 28, 2020 5:09 PM PST

    Was tackling the epic weighted random table thing and after some thinking, came up with a pretty decent solution (I think). Let's say there's a spawn point that has a list of mobs it can spawn. Each mob has a certain percentage chance of spawning. Say 50% of the time "a wolf" will spawn, 30% of the time "a stout wolf" will spawn, and 20% of the time, "Gorefang" would spawn. Hence, a WeightedList was born. Very simple implementation (KISS is my programming modus operandi).

    BTW, replace the brackets "[]" with "<>" below for the _entries List...

    Would be AWESOME if there was a "source code" paste feature!

    class WeightedList {
       private struct Entry {
          public T Item;
          public int Threshold;
       }
       private List[Entry] _entries = new List[Entry]();
       private int _totalWeight;
       public void AddEntry(T item, int weight) {
          _totalWeight += weight;
          _entries.Add(new Entry { Item = item, Threshold = _totalWeight });
       }
       private Random _rand = new Random();
       public T GetRandom() {
          int r = _rand.Next(1, _totalWeight + 1);
          foreach (Entry entry in _entries) {
          if (r <= entry.Threshold) return entry.Item;
       }
       return default;
    }

     

    To use you would do a (remember to replace brackets [] with <>:

    WeightedList[int] lootTable = new WeightedList[int]();

    lootTable.AddEntry(101, 8);

    lootTable.AddEntry(289, 2);

    // 80% chance to spawn item 101 and 20% chance to spawn item 289

    int item = lootTable.GetRandom();

    Console.WriteLine(item);

     

    You could also use a custom class (remember to replace brackets [] with <>:

    WeightedList[Mob] mobList = new WeightedList[Mob]();

    mobList.Add(mob1, 3);

    mobList.Add(mob2, 1);

    // 75% chance to spawn mob1 and 25% chance to spawn mob2

    Mob mob = mobList.GetRandom();

     


    This post was edited by Chroma at February 28, 2020 5:48 PM PST