[OPEN SOURCE] Multiplayer 3D RPG Using Colyseus

Orion, how you doin?
I joke you not when I tell you that checking your repo last commit its one of my first things in the morning, great work and very fun to follow.

And I just created this account to ask you this:
Have you thought about implementing a tiled-based movement?
Id love to see your approach to that!

I think any combat system (pvp/pve) would be positively affected by it. In my personal opinion, is overall funnier when you are not just a free hitbox spinning and colliding around.

If not, any insight in how can I achieve something like that myself? I could make a fork.

Thank you!

edit: im also thinking about Minecraft and how chunks are loaded/managed. Even when entities have free-movement everything is inside a grid (with lot of benefits).

There is Noa engine - GitHub - fenomas/noa: Experimental voxel game engine. , based on Babylon engine. While it may have a lot of benefits it also has its own limitations.

@ozmuye thanks for the kind words, and welcome to this awesome forum. I’m glad people are enjoying watching my progress :slight_smile:

To be honest, I’ve never considered tile based movement, but I would say it should end being easier to implement in multiplayer than a “free hitbox running around” as you say : no need for a navmesh, less affected by lag, and more I’m sure.

I’ve never done this, but here’s how I would go about it to get the basic tile base movement done:

  • on the server, make a virtual grid that represent your world and the positions where entities are allowed to be (sounds simple, but start simple like a cube of 10x10)
  • on the client, send to the server every arrow key press event
  • on the server, use that key press event to determine the next tile position,
  • on the client, lerp from current tile position to updated tile position
  • in the end, it’s not that different from I’m doing anyway.

About the loading/unloading of entities in a range around the players or in a grid, I know I’m going to have to dive into that one day, but I’m not sure I’m good enough to tackle this one yet. I would not even know where to start. :upside_down_face:

Thanks! I’ll try.

About the loading/unloading of entities in a range around the players or in a grid, I know I’m going to have to dive into that one day, but I’m not sure I’m good enough to tackle this one yet. I would not even know where to start. :upside_down_face:

On that, I would do something not too crazy.
(hidden cause I wouldn’t dare to off-topic this master-piece of thread)

Summary

Define a square chunk size (preferable a little bigger than player’s desired viewport + some margins). If you are at a border, load neighbors too. To a maximum of 4 loaded chunks in a corner scenario.

What do you get? A GRID! :smiley: haha

You load all the entities in those chunks. Every time you modify an entity you can easily calculate if this entity is “touching” any border and broadcast the new state to all three neighbors chunks (and itself).

This way you can jump borders back and forth without problem and you also give other players some time to load your awesome skin.

Then, when you are too far away from a chunk, forget about it and everything it has. Kill them. Make space from whats next. You can add some quadrant magic to it if you like maths. I do not.

Quick update:

  • did a massive refactoring ( merged entity and player classes and states on both the server and the client and extended player class from the base entity class, it was something that needed to be done for a long time )
  • added the concept of race with attributes (in my example: Bear, Unicorn, Hobbit Player)
  • added an animationSpeed to each “race” to achieve better looking animation
  • some bug fixing
1 Like

Haha, very funny :slight_smile:

I like your solution thanks, and I will work on something similar to that in the future.

Until then, I found a “very basic” solution to only load entities in a range around a player, which works pretty well, and I can now have many more entities loaded than before.

// only enable entities in a range around the player
for (let sessionId in this.entities) {
    const entity = this.entities[sessionId];

    // set entity to disable by default
    entity.mesh.setEnabled(false); 

    // only check type "entity"
    if(entity.type === 'entity'){

        // find distance to player
        let entityPos = entity.position();
        let playerPos = this._currentPlayer.position();
        let distanceFromPlayer = Vector3.Distance(playerPos, entityPos);

        // if in allowed range, set as enabled
        if(distanceFromPlayer < 15){
            entity.mesh.setEnabled(true); 
        }
    }
}

Another good-scaling solution: divide map into chunks and load objects only from chunks which around the player(Area of Interest [PDF] Simulation of Area of Interest Management for Massively Multiplayer Online Games Using OPNET | Semantic Scholar ).

2 Likes

Thanks, I will look into that.

I spent a while trying to integrate YUKA to use for the enemy AI with no success as it all become so cimplicated, so I started to work on adding my own enemy AI and after a day work, I’m very happy with the result:

  • default is all enemies wanders around
  • at all times, I have a function that determines the closest player for each entity
  • if a player get’s in a certain range, it starts chasing that player until either
    – it gets in range, an then starts attacking player or
    – player manage to get away and the enemy returns to wandering

It was the first time doing “AI”, and I enjoyed it very much, and it’s great to see enemies coming alive :slight_smile:




even with 100 entities and recording a video, framerate is still rather good :slight_smile:

4 Likes

After a few fights with ES6 tree shaking and webpack, I managed to bring my bundle.js from 16mo to 550kb gzipped. Demo should be a little quicker to load now :slight_smile:

4 Likes

This is exciting! Great work!

Have you did any stress testing on mobile yet?

1 Like

Nope, not yet. I have just tried on my iphone xs ( 2018) and it runs very smooth at 60fps per second… :slight_smile:

1 Like

Morning all,

Nothing is easy, but I’m currently quite happy with the ai behaviour, and have started working on next feature, the abity to select & attack units with a fireball ( very simple in single player games but in an networked environment, it’s so hard to get right ).

Currently, you can press digit1 on keyboard and then click on any unit and a firebal will spawn every second until unit is dead, but I’m not very happy with it as it doesnt feel very user friendly. So I’m gonna go with a more standard approach,

Here are my thoughts on how to approach it:

  • ability select unit with left mouse button
    – add a local only highlight to the selected unit
    – make sure server knows which unit is selected ?? (not sure about this one, to be tested)
  • ability to use the keyboard or click on ui to start an attack on selected unit
    – send server click/keyboard events
  • process attack on server only
    – rotate player in direction of target ?? (not sure about this one, to be tested)
    – check on server if current selected unit is in range & player is not in cooldown
    – if already attacking, cancel current setInterval
    – start a setInterval each 1s until unit is dead
    — select unit loses health
    — send player attack confirmation with latest attacker position and selected unit position
  • Process attack on client
    – client can spawn a fireball and move it from startPos to endPos (we have to use server positions because on the client, everyone is “in the future” and positions would be different)

I’m sure I’m forgetting lots of steps but as you can see even for something that seems very simple it can get very quickly quite complicated :slight_smile:

I’m looking forward to get started on easier things if there are such a thing :stuck_out_tongue:

In the meantime, to relax, I started working on the ability bar and I’m not far off, I just need to find a way for each button height to be proportionned to the width else icons looks stretched

3 Likes

@oriongu, I love reading your progress on this thread since the beginning. It is fascinating to see the game is taking life !!! Please, keep sharing !!!

3 Likes

Thanks @sebavan and I’m enjoying sharing.

I’m getting close to having a decent attack, and it feels much better this way.

Updated demo so you can try and let me know if guys prefer: https://t5c.onrender.com

you can lose health

you can die but get respaned so you can die again :slight_smile:

2 Likes

tooltip for abilities

1 Like

I now have a working fireball and a working heal ability :slight_smile:

maybe i’ll add mana pool next so you cannot spam abilities

2 Likes

mana pool added :slight_smile:

that’s it for today

2 Likes

Good Morning,

Ok, so I’m getting to point where I’m going to have to decide where am I going with this project before I go any deeper, indedd I need decide whether it is:

  • an open source project to help & give everyone some sort of good base to start with
  • a personal coding challenge and see how far I can go & learn in the process
  • a potential game I’d like to release / commercialise
  • all three at the same time?

So let’s do a quick retrospective:

  • In august 2022, I decided to put in a bit of time every day into making a game with these goals in mind:
    – could hold 20-25 people playing simultaneously
    – top down rpg similar to t4c (the 4th coming)
  • I started in oct 2022 just playing around with babylon.js and colyseus
  • I posted my first post on november 2022 so I could share my progress
  • 366 commits later and 3 months later, I’m starting to have a solid little prototype working:
    — fully authorative movement with client side prediction and server reconciliation
    — server & client controlled collisions (client reconciles from server)
    — simple scene management & switching
    — networked animated characters
    — networked NPC entities with basic AI
    — health and mana stats
    — 2 working abilities (Fireball + Health)
    — zoning system (ability to teleport to different location)
    — login / character selection/creation scene
    — database persistence
    — global chat

Addionnally, as you all would know, there are alot of things that you cannot really show but are also important:

  • how to format & bundle correctly with webpack and import dependencies to minimize bundle size
  • how to setup a workflow for the level design between blender, unity and babylon
  • how to prepare and export a navmesh
  • how to setup a working demo (that is easily updatable from every github commit)
  • how to organize & structure your code to keep it as dynamic as possible (probably where I spent the most of my time: refactoring loops)
  • How to code in a networked way and make sure client never decides of anything and if he does, reconcile it from the server. Fake it on the client basically :slight_smile:

So in regards to my initial roadmap, I’ve exceeded it and more. The result is that I’m feeling much more confident in my abilities that when I started so I want to be a little smarter into where I put my time and make a plan/roadmap/goal for the future.

I’d love to hear your toughts on this matter? Maybe some of you have been in the same situation? In all cases, I’m going to be thinking about this over the next few week and will get back with a plan/roadmap.

Last but not the least, a big thanks to the whole Babylon.js community for the continuous support & encourgement! You’re the best!

Orion

4 Likes

I enjoy seeing the updates on your project in my github feed, I typically jump to your games website to see the progress towards the end of the night. It’s inspirational.

Having it opensource this entire time I believe helps with maintaining an audience. Perhaps, some community members might jump in to help out in the near future (you never know). It could possibly be a community project if that happens (that would be pretty cool).

But hey I get it; you dump a lot of time into developing and refactoring the code to get it just right. However, there’s still a ton of things you have yet to do and this opensource project could be your guineapig, or better yet your first draft. You can get it to a state where you are somewhat satisfied and then fork into a private repo.

www.draxus.io was my first go at babylonjs, I guess you can consider it my first draft. I did not opensource it since I was learning JavaScript at the same time and the code was a whole lot of spaghetti, super slopy. had multiple attempts to refactor it, and didn’t think it was worthy enough for others to study. It became such a huge monolith that I decided to desert it. I definitely learned a lot though from that project, maybe I’ll come back to in the future. Since then I’ve pursued a new project (which I am still working on in my spare time) and the code is starting to scale just right (meaning no refactoring is really needed).

I say keep it opensource to grow an audience (you’re going to need players when you release it, why not have a couple from babylonjs community)

just my 2 cents :wink:

3 Likes

Let me add @Deltakosh for his open source wisdom and @PirateJC about the turn it could take.

From my point of view, what you achieved is already amazing and you can now only pile more greatness on top of it. I love open source as it is a huge motor for me in both awesomeness (they ll cheer you when things are great) and as a mediocrity shield (they ll help catching early issues so they do not creep too long)

1 Like