#Crystal Realms - 2d sandbox mmo game

90 messages ยท Page 1 of 1 (latest)

eternal turtle
#

Hi everyone! I am working on a 2d sandbox mmo game called Crystal Realms. This game has been in development for the past 3 years, but the last update I have switched over to using bevy as the game engine.

The server is also written in rust and has been using the bevy_ecs crate for the past 2 years.

The game already has many features working:

  • Crafting
  • Quests
  • Achievements
  • Potions
  • Parkour mechanics
  • PVP
  • Monsters
  • Trading

The pre-alpha version of the game is available on https://crystalrealmsgame.com or https://marcomeijer.itch.io/crystalrealms and we already have a small community of active players.

We are also planning to release the android version of this game before the end of this year to the google play store.

itch.io

A sandbox platformer mmo

stoic aurora
#

the last update I have switched over to using bevy as the game engine.
What did you use before bevy and how was the switch? ๐Ÿ‘€

eternal turtle
#

I used libgdx before

#

The switch went smoothly, there were a few bugs/missing features of bevy that affected my game. But most of those are fixed now, or will be fixed in 0.15.

abstract arch
#

Looks sick!
What do you use for networking?

eternal turtle
abstract arch
#

Looks like all big projects roll their own high level networking solutions on top of renet ๐Ÿ˜…

eternal turtle
#

Oh yeah, I also have my own networking stuff built on top of renet. I am not even using bevy_renet but just the regular renet.

vernal pewter
eternal turtle
vernal pewter
stoic aurora
#

What does the networking look like other than sending messages trough a layer on top of renet? Is there anything like client prediction involved?

eternal turtle
# stoic aurora What does the networking look like other than sending messages trough a layer on...

Yep there is client prediction. For anything that the client has to predict I basically create a command that implements this trait:

pub trait UndoableCommand: Send + Sync {
    fn execute(&mut self, world: &mut World);

    fn write(&mut self, world: &mut World) -> Message;

    fn undo(&mut self, world: &mut World);

    fn read(&mut self, world: &mut World, stream: &mut dyn Read);
}

The write is to send it to the server, and the read is to see if the server accepted it, or what the server thinks should have happened.

Then all of these commands are added in a command queue. And before processing the messages I receive from the server, I undo all the commands I executed locally, to make sure the server and client execute the things in the same order.

stoic aurora
#

Oh, that's a rather unusual approach but it actually seems a lot less complex to set up and debug than a rollback system, with the drawback being that you need to implement new things manually, but the upside being that it scales by how often things happen rather than by things predicted * tickrate

eternal turtle
stoic aurora
#

Usually when people talk about a rollback system it refers to a system that records state to a history, then when new data comes in, it loads data from that history and reruns every frame that happened since

eternal turtle
#

Yeah thats what I am doing. These commands get added to a history (Well I called it command queue). And whenever new data comes in from the server, I undo everything. And after I process that data I execute everything again.

stoic aurora
#

In the case of recording the state you just have the benefit of not needing to undo anything, at the cost of keeping a lot of histories

eternal turtle
#

Ahh I see, I think in my case that would have been more expensive/complex.

stoic aurora
#

And things going catastrophically wrong over the tiniest bug, my favorite rollback bug is this one I created recently: #1211045598854127636 message

stoic aurora
# eternal turtle Ahh I see, I think in my case that would have been more expensive/complex.

Yea, I can definitely see that. I've been working on a full rollback system for quite a while now and it has been a massive pain. Before this I did what many shooters do, which is basically just take a shortcut by rolling back to a full server snapshot for the player, and only keeping inputs since then + histories for things that aren't predicted. That removes most of the edgecases that can be created, but only predicting the local player turned out to be far too limiting to make the combat I want (action combat that heavily relies on having a bunch of interesting and unique skills)

#

And besides just making the system being a pain, I also had to optimize my game's simulation so it can run say 14 times per frame

versed berry
eternal turtle
eternal turtle
# versed berry Chunks or anything like that?

Chunks are not really needed in this case since worlds are not infinite. Each world is 300x170 blocks (which is more then enough for this type of game, since players often want to fill a whole world with their creations)

versed berry
eternal turtle
abstract arch
#

I wondering what is your experience with Bevy. Do you you the latest version or stick to specific one?
Curious because recently discovered that some big projects don't migrate.

eternal turtle
stoic aurora
eternal turtle
eternal turtle
eternal turtle
#

The game has really been blowing up in indonesia this weekend. Today we reached 200 players online.

stoic aurora
#

Is this a new record? If yes what was the previous peak?

eternal turtle
stoic aurora
#

Nice, how are the servers holding up, or is the game structured in a "players run their own instances" way? ๐Ÿค”

eternal turtle
#

I even forgot to increase the thread count on the server, and even with just two threads it was able to handle 180 players. (the server has 48 threads)

stoic aurora
#

Nice ... So far I've also been hosting my game (which is still in a pre-alpha state so basically no players) on a 5 euro VPS ๐Ÿ˜‚

#

With the whole two cores I have I can handle between 30 and 100 players, would probably be a mistake to release a demo without getting a more legit server ๐Ÿ˜‚

eternal turtle
stoic aurora
#

That's a good point actually ... Also having things like bandwidth caps could easily turn into a way to take a server down

#

I think the host I'm at (hetzner) should provide DDoS protection, tho I'm not sure how good it is

eternal turtle
abstract arch
#

How servers are holding up?

eternal turtle
stoic aurora
#

I guess you're the biggest bevy game now, ahead of even Tiny Glade ๐Ÿ˜‚

eternal turtle
#

It was close a few times before, but today the game reached 1000+ players online at the same time!

#

The past few days I have been fully focused on optimizing the servers, fixing bugs, adding profiling tools and that kind of stuff to handle this increase in players.

stoic aurora
eternal turtle
# stoic aurora So the servers aren't on fire with 1000 players? ๐Ÿ‘€

Nope, after optimizing it, it runs pretty smoothly. My main bottleneck is that I was using one mutex a lot, so a lot of threads spend time idling waiting for it to be unlocked. Another optimization I did was running the server on multiple udp ports. This way I was able to split the code that was responsible for sending networking packets over multiple threads. And when the players first connect I redirect them to one of these ports. (Thanks to renet this was very easy to do, and I didn't even need to update the client)

Sometimes there are lag spikes in popular worlds though when it gets autosaved. The servers cpu usage is at about 70% with this many players, so I definitely need to upgrade the server if I want to allow even more players.

stoic aurora
eternal turtle
# stoic aurora Huh, I thought UDP is already supposed to be thread save without multiple ports ...

I am not sure, maybe it would have been possible. But I don't know how I would have done that using renet. I am basically running 4 instances of renet on my server, and I am not sure if it is possible to run one instance of renet on multiple threads. This also fixed the issue that renet has a limit of 1000 connections. So by running 4 instances I can support up to 4000 players on a single server

stoic aurora
#

Ah of course, not everyone is using a weird custom transport with renet where they can do whatever ... I've been doing that since I switched to renet so it's the only approach I know ๐Ÿ˜…

stoic aurora
#

Hit any other milestones after the 1000+? ๐Ÿค”

eternal turtle
#

But that was about 2 weeks ago, and right after the game got DDoS attacked for a few days which made the playerbase shrink a bit. But right now we still reach a peak of 1300+ players online daily.

#

I am gonna release an update soon, so maybe after that we will hit a new record.

#

Oh and the discord server hit 10k members today! That was a pretty big milestone

gloomy canyon
#

wow! congrats! ๐ŸŽ‰

abstract arch
#

But I guess it's also means that the game is quite popular, congrats!

eternal turtle
#

They host an illegal private server of a similar game as mine, and they probably saw me as competition.

abstract arch
eternal turtle
abstract arch
#

I wonder why reverse-engineering games is fine, but when it comes to servers it's illegal ๐Ÿค”

eternal turtle
abstract arch
#

Ah, makes sense!

stoic aurora
lyric garden
lyric garden
lyric garden
eternal turtle
eternal turtle
eternal turtle
# lyric garden Maybe cloudflare for DDOS protection?

And about that, as far as I understand cloudflare mostly offers tcp protection. Their udp protection is a bit more pricy.

But my new server provider uses gcore for its DDoS protection. And I was able to protect myself against a 870 Gigabit/second DDoS attack without the players noticing anything.

lyric garden
#

Which provider is this superior gcore UDP DDOS protection? I didn't know cloudflare requires an upsell for UDP.

eternal turtle
eternal turtle
#

Its been a while since I posted here, but I have recently released a very big update:

lone ferry
#

are you planning a release on steam?

eternal turtle