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
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
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
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!
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;
}
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;
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();