Random devblog

04/09/2020 09:58 KraHen#1
So, in the last couple of weeks because of all the stuff that's going on lately I am stuck in my house and I was looking for something to do besides work and play games. I realized that I never actually made a playable server, I always worked on making bases stable/interesting, trying out new concepts. This projects goal is to actually implement gameplay features that I am not really familiar with (which is most of them, really). It is also a refresher for me on C# since I haven't been really working in it for a long time.

Special thanks and credits go out to CptSky for his CO2_CORE_DLL project which I am using heavily, also Redux and COPS for reference. The source will not be made public, the code is pretty much just my base + a lot of stuff ported over. The goal is to create a stable and unique classic-ish server.

I will be updating my progress here, please feel free to give any tips/hints regarding implementing some systems, I really have no idea what I'm doing.

Current status :
  • CI integration and Dockerfiles for Windows and Linux builds
  • Login server, registration - integrated with some popular CMS software so I can make hosting the site later easier, also have public plugins and support so I can just drag and drop features. Is it lazy? Yes. Does it come with years of security patches and whatnot? Also yes.
  • Game login, encryption
  • Character creation
  • Screen system
  • Walking, jumping (DMAP checks not implemented yet)
  • Portals
  • NPC and player spawns
  • NPC scripting (Python)
  • Custom gameplay loop - the whole server follows the classic game loop, currently running at 60FPS. This allows me to spread out updates over multiple frames later on, also easily allows to control server load and enables a lot of standard gamedev patterns to be used during implementation
  • Inventory
  • Equipping items
  • Stat calculation
  • Basic melee attacks (hardcoded to do 69 damage currently, nice)
  • Most weapon skills, targeted attack spells, FB/SS
  • Chat - talk and whisper
  • Item scripting
  • Monster spawns + monster AI, heavily multithreaded
  • Leveling + Prof/Skill XP gain
  • Basic TC item upgrades
  • Warehouses
  • Some NPCs and items implemented

Latest screenshot with not much going on :

The focus right now is to finish the PvP attack system by adding some skills and bow attacks.

Again, if anyone has some tips, gotchas, or just wants to comment their two cents, please feel free!
04/09/2020 12:33 Super Aids#2
Quote:
hardcoded to do 69 damage
nice
04/10/2020 09:33 KraHen#3
Added profs and skills. Finished damage calculation for skills and physical damage, dodge and bow attacks still TODO. Implemented FB/SS, single target skills (Thunder, Tornado, etc), some weapon skills (Phoenix, Rage, Snow).

Implemented status effects and basic transformations, people can die now.

I'm considering setting up a hosted test environment so some alpha PvP can be had.
04/10/2020 19:37 Latyos#4
First of all good luck in your journey. I'm also developing something on the side for fun but haven't finished half the stuff you already finished yet (because of my inexperience in conquer).

I first used Python for NPC scripting as well (pretty much copy+paste from Albetros). Then I switched to LUA with MoonSharp (because it was more convenient for me). Then I completely switched over to .NET Core 3 and I have my NPC script compile and run dynamically. So when I change source code, it compiles binary again, unloads the old one and loads the new one.

Edit: If you are interested, you can read more about it [Only registered and activated users can see links. Click Here To Register...], with a working POC code
04/10/2020 20:45 Super Aids#5
Quote:
Originally Posted by Latyos View Post
First of all good luck in your journey. I'm also developing something on the side for fun but haven't finished half the stuff you already finished yet (because of my inexperience in conquer).

I first used Python for NPC scripting as well (pretty much copy+paste from Albetros). Then I switched to LUA with MoonSharp (because it was more convenient for me). Then I completely switched over to .NET Core 3 and I have my NPC script compile and run dynamically. So when I change source code, it compiles binary again, unloads the old one and loads the new one.

Edit: If you are interested, you can read more about it [Only registered and activated users can see links. Click Here To Register...], with a working POC code
Instead of following Albetros you should follow my source. It's same version and it's far better and isn't absolute shit like that project.

My source also dynamically compiles things like events, items, tournaments etc. and not just NPC scripts.

[Only registered and activated users can see links. Click Here To Register...]

Github: [Only registered and activated users can see links. Click Here To Register...]
04/11/2020 08:50 Latyos#6
Quote:
Originally Posted by Super Aids View Post
Instead of following Albetros you should follow my source. It's same version and it's far better and isn't absolute shit like that project.

My source also dynamically compiles things like events, items, tournaments etc. and not just NPC scripts.

[Only registered and activated users can see links. Click Here To Register...]

Github: [Only registered and activated users can see links. Click Here To Register...]
Even though the project I'm working on is following microservices architecture as well, I find it hard to take another source with same architecture as a reference. Because they are simply too complex to read, follow, understand and implement yourself.

On a quick glance though, your Auth implementation seems better than what I and Albetros uses. So I might end up copy+pasta some stuff :kappa: Anyways, thanks for the reference, really appreciated.
04/11/2020 09:11 Spirited#7
@[Only registered and activated users can see links. Click Here To Register...], that's a lot of progress since we last talked - awesome. Just out of curiosity, are you running docker during development or is that just for CI/deployments? Docker really annoyed me on Windows and just bloated my development with unnecessary cloud-scaling dependencies... so now I have configuration environments. I'd be interested to know what your experience has been and what containers you're using.

Also, can you talk more about this custom gameplay loop of yours? How does that contribute?
04/11/2020 12:01 KraHen#8
Regarding script usage - scripts are not lazy-loaded, in fact they are compiled. In case they have to be reloaded, they are double buffered, but tbh that really isn't a concern since I don't plan to do live updates to scripts, it's just a safety measure that allows me to sleep at night. Currently they are used only for NPCs and Items, but as Super Aids said, they will most likely be used for events later on as well, if I ever get to that. I am definitely not switching over to LUA or it will trigger my PTSD. Why Python? Just cuz.

Quote:
Originally Posted by Spirited View Post
@[Only registered and activated users can see links. Click Here To Register...], that's a lot of progress since we last talked - awesome. Just out of curiosity, are you running docker during development or is that just for CI/deployments? Docker really annoyed me on Windows and just bloated my development with unnecessary cloud-scaling dependencies... so now I have configuration environments. I'd be interested to know what your experience has been and what containers you're using.

Also, can you talk more about this custom gameplay loop of yours? How does that contribute?
Thanks, tbh I had way more time than I usually do and the amount of public examples to use as references is just staggering. I've had very similar experiences, so no, I don't really use it for development, on Windows that is. I have an old laptop though that I sometimes pop out and do coding on my couch, and in that case I do use Ubuntu and Docker, but honestly usually that's when I have to write boilerplate that doesn't really need a lot of debugging. TLDR : Docker for deployment, cross platform builds and integration/regression testing.

About the gameplay loop, certainly. The very core is simple, on the main thread I have the loop running that then calls updates for manager classes that handle their own component updates. E.g. combat actors get updates, etc. If you ever wrote Unity code, it's looking very similar, albeit I haven't used proper components yet since I haven't seen the reason to - except for packet handlers. Each handler is practically a component, and you can just refer to them inbetween each other if you need to, e.g. :
Quote:
var itemHandler = player.GetHandler<ItemHandler>();
// no more giant fucking switch
The player update, for instance, is sending one packet in the queue / frame. This would limit spending time on a single player with a lot of stuff in his queue and make sure everyone gets updated at roughly the same pace.

The nice thing about having it though is enabling patterns that I am familiar with, and will be easy to do the mob system later on - which was the primary reason I went with this in the first place. I can allocate a thread pool for multithreaded updates and handle AI the same way you would handle them in any other game. With this, if you have more costly updates - e.g. pathfinding, you an implement it so it only does one step at a time, then allocate a budget - let's say in milliseconds, or in number of frames - for it to take, then spread it out over multiple frames so it doesn't block its respective thread for too long. Honestly it's not that different from using a standard timer, it just enables me to specify the order of the updates easily and make the code more to my liking.

[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]

It's much better explained here if anyone is curious, I can also recommend the book in general.

Stuff like this becomes more natural (at least to me) to write.

In the meantime, shops have been added and buying/selling items.

I've been starting to think about a website, but I suck at design, so I looked over some folks who are selling the flashy standard MMO private server sites, which look nice but I found only a handful. If anyone knows good resources on this, tell me plz.
04/11/2020 18:16 Super Aids#9
Quote:
Originally Posted by KraHen View Post
I am definitely not switching over to LUA or it will trigger my PTSD.
Arrays starting at 1 is enough to trigger my PTSD.
04/11/2020 21:57 KraHen#10
So alongside a few minor changes, I have gotten around implementing monsters + monster spawns, and making the whole update process multithreaded. A nice side effect is that there is no dedicated monster thread, attack thread, whatever-the-fuck thread, there are only jobs and bulks of these. First players get processed, then monster AI happens in a frame. That's it. This is an area where I would like to ask for opinions of implementation. Currently what I have is the following :

Each map contains N monster spawns, which it automatically updates, if there are players on the map. Each monster spawn updates their respective monsters, which right now only consists on processing fadeout and reviving them to keep up the spawn monster count. The whole process is handled by a threadpool (which was literally 2 lines to do, thanks to the Update pattern), with one chunk of work consisting of handling one monster spawn. The shortcoming of this is that all mob spawns are updated right now, there is no spatial partitioning implemented yet.

How do you guys usually handle this? Right now I have the following in mind : Change the screen system to implement basic spatial partitioning, creating 20*20 (TBD) cells in each map, and when a move happens, update only the nearest neighbouring cells and its respective entities, thus marking them as active - and their respective spawns as active. This seems to be straightforward enough and a massive improvement over the current test-against-everything-in-map implementation.

UPDATE : Yeah this works fine, but not trivial to get right so it only updated what is absolutely has to. Right now with with like 500 mobs on the screen the CPU usage is around 0.3%. Mob AI now implemented, Guards turned off temporarily because there's no blue names yet and they turned into murder hobos.