Babylon.js Browser 3D MMO RPG - Devlog

Really cool project @Maiu!

What are your goals regarding the visual aspects of the project? I’ve been working on an optimized 3d rpg graphics asset pack for Babylon.js, and I’d love to help out if you happen to want someone else to do a graphics pass.

Great work! Really interested to see how the project develops.

1 Like

Thanks @gamedevgrunt !
For now as I’m only one who’s developing game and my knowledge about graphics is close to zero (my sole graphics experience is editing models Y rotation to make them consistent :smiley: ) I’m sticking to whatever I find free on the web, which will serve pursope of presenting ‘information’ :slight_smile:
Regarding project I was thinking about low poly (but not square :slight_smile: ), cartoon’ish style. Not too much in either way’s. Still to be decided about the details.

I’d really appreciate help :hearts:! But to make it happen I think the project needs to be at the level with more mechanics, more features etc. Definitely We can talk about it in the future :hearts:

1 Like

Hey again!

Last two days I was working on syncing server and client clocks and on top of it I implemented entity interpolation. On the video I’m presenting You situation when server network tick is set to 4 which means it sends messages to players each 250ms, which is simulating quite significant lags.
Without interpolation movement is super shaky and after enabling it it looks very good taking into consideration 250 ms lags.

Next I’ll work on client side prediction and reconciliation which will make similar difference but for the player.

1 Like

Hey
Recently I was implementing entities interpolation and next on the plate was client side prediction, which is smoothing player movements and increase responsiveness (predicting player movement before response from the server is received). To make it work I also needed slightly redesign movement mechanics. Code is spagettii… but looks like it works :smiley:
After I’ll decide about combat mechanics and general game play style. I’ll revisit my work, refactor it and add some improvements which i had in mind

On the video I’m presenting effect of three algorithms:

  • player movement prediction
  • player movement reconciliation with the server response
  • player position extrapolation (between physics ticks 20/s)

I’m simulating latency by setting server network tick 4/s which effectively making server to send all messages each 250ms. It’s not like in real world but i have some insights how it’d work.
In general I think it work ok. It’s minimizing lags effects quite significantly.

I thinking about adding to the entity interpolation similar mechanism which i have in player position reconciliation, which is not updating to position received from the server instantly but makes smooth transition across few simulation ticks (imagine elastic band). Perhaps adding it for all the entities will create too much overhead but adding it for enemy players would be nice. I’d increase experience significantly not only for players experiencing lags but others which interact with them.

Right now I’ll be working on collisions mechanics and in parallel I’ll add some monsters to perform some tests and maybe share some new posts.
To make collisions work in a way I want I will need to create map editor with some custom coding which will calculate all the data for collisions checks and in future for veeeery cool :smiley: rendering optimisation - some spoiler I’m thinking about creating one huge open world instead of smaller zones. Will see what will happen…

Hope You like it!

3 Likes

Hello
I’m working on POC (prove of concept) implementation of monsters system. I managed to achieve first milestone which is loading entities into engine.
And finally i have occasion to show You how my hash grid area of interest is working.
Engine is refreshing area of interest data each second and it sends info to the clients to show/remove entity. There’re two visibility ranges. First is lower (eg 50 units) it describes distance below which entity should be visible and second visibility range (eg 100 units) is bigger and it’s use to hide entities. This way I’m avoiding sending create/remove entity command when some entity is on the edge of visibility and potentially I’d have to show/hide and resend entity each spatial hash grid update.

Keep in mind that it’s not working on radius but on bounding boxes (rectangles) and entities visibility is not symmetrical. This implementation is far more efficient and actually not having it symmetrical doesn’t change anything. Eventually I’ll setup it to comfortable range and players will no care about it.

Entities are instantiated/disposed on the demand and I’m quite curious how performance will look like when instead of disposing meshes I’d put them into mesh pool for later use. For sure I’ll test it in the future.

3 Likes

Hey :slight_smile:
Currently I’m working on collisions detection. For now I’m using SAT 2D and later in future maybe I’ll change it to something different (maybe navmesh, will se…). To make creation of map and collisions data a little bit more automatic I prepared very simple map editor. Which prints in the output whole map config with collisions data etc… in json format.
Collisions detection still have few bugs mostly related to the calculating collision response, when I’ll fix it I’ll share next video.

3 Likes

Hello again,
Since last post I added two new things to my game. First is global chat and the second is collision detection based on SAT 2D algorithm.
Player is simple point and obstacles can have collision shapes of circle or rectangles with arbitrary orientation.
Still there are some bugs mostly with calculating collisions response on the edges of the rectangles but it works quite good, for the first iteration it’s enough.
Still don’t know how I will handle collisions/navigation in the future. I will need something simple with capabilities for integrating with path finding and line of sight algorithms. I need to do some research and think it through.

Next update will be probably about monster system. I want to add walking, chasing, attacking, death and spawning monsters.

4 Likes

Hey,
I’m working on monster system and I’m starting to see first effects. Still there’re some things to improve and bugs to fix.

2 Likes

Hello,
Finally I finished work on first prototype of monsters AI module. Monsters have several states: IDLE, PATROL, DEAD, FLEEING, COMBAT.
Idle monsters are non active even when someone attack them. Patrolling ones are walking around and checking each 0.5s is they have someone to attack in a range if yes then they start chase target (combat state) and attack when in range. Dead are obvious and fleeing is triggered when monster is enough far away from the position where it switched into combat state.
I also added death to the monsters after 120s they respawn.
Implementation have some bugs and AI it’s just bunch of ugly if’s but It enables further development and testing. I will go back to this after some time and try to improve it.

From the technical point of view it’s designed in a way that monsters service is independent from the main engine loop. It can be deployed on separate machine, I hope this will very significantly unload main engine in the future, I’ll be able to afford very inefficient AI implementation without compromising game performance.
Monsters are pretty much like players but are not connected by websocket’s proxy but by internal api (redis pub-sub in future, right now I’m working on the mock for simplicity but have prepared redis and mocked implementation).
Monsters service keep replicated state of the whole simulation and ‘AI agent’ is responsible for handling all monsters logic.

And spoiler only for Babylon.js :smiley:
Yesterday for the first time I deployed game into web server. I took me few hours to build prod versions of client and server (setup build config, server addresses etc.). To be honest this is my first app in my life which i deployed by myself :stuck_out_tongue: First what i noticed that my game was using almost 100% of CPU of tc2-micro aws instance (0 entities in simulation). I had previous observation from my local development that there’s a problem but I postponed fixing.
Today I downloaded and ran java profiler with a hope that I will find problem. What I notice that w of the threads are active 100% all the time. After taking look into game loop code I notice big problem. I didn’t have any sleep time in the loops, so it was using all the resource it have (processor core). After introducing short sleep into loop. local CPU usage dropped from around 34% to around 1%. On aws right now I’m observing cpu usage around 8% which is nice I think.

I tested few things with my friend and also talked about character controller and general gameplay. We found few bugs, for example when chat is full newest messages are not visible. Still there’re a lot of things before public demo but it’s one step closer :slight_smile:
I’m pasting ‘historical’ screenshot from this event :stuck_out_tongue: (PS. aws instance is closed so You wont be able to enter to the game :P)

3 Likes

Impressive work @Maiu its great seeing your progress. I’m going to have to step up my game to keep up with your progress :stuck_out_tongue:

1 Like

Thanks :slight_smile:
I think I still not at 50% of what You already have in your project so You can sleep calmly :joy:
I have few bigger topics which will take me a lot of time.

I still not yet decided about final gameplay. I’m not sure if go with 8 way WASD and spells casted with right mouse click(keyboard only for selecting spells), probably this option will force targeting only on mouse hoover.
Second option is to go with regular WASD and camera behind the character. regular targeting and spells casted on key press.
Hard to decide, these are two totally different gameplays. At the beginning I wanted to go with first option but right now I’m not sure. I want gameplay to feel dynamic second option might be better but…
Maybe there’s 3rd option I dont know.
This is blocking some further works so I’ll need to decide in soon future about it. it will be hard to reverse so I want to make conscious decision about it

2 Likes

Hey!
For the past few days I was thinking about movement style in my game and finally I made a decision. I’ll stick to the initial plans with WASD movement and diablo2 like camera with rotation/zoom capabilities.
Regarding progress, today I slightly improved in game chat. I increased width, added time to the messages fixes bug with visibility of newest messages and added messages overflow protection to potentially do not leak memory in the future.

3 Likes

Hello,
This week I spent mostly on thinking about future gameplay. I did several tests and prototypes, I know much more then before and I gain some knowledge about limitations and problems which gameplay related stuff brings into the game.

From the stuff that is visible I managed to improve targeting marking. I added new target mark under the mesh and outline around it.
Recently I had some problems and most of the area of the meshes didn’t triggered cursorOver/cursorPick events, it was occurring for random entities and i didn’t manage to replicate it in the babylonjs playground. To not spend to much time on this problem which might be related to the mesh itself I fixed it with a hack. Each entity has assigned cylinder which is user for picking and it works quite good :slight_smile:
I made first steps into abilities. Since now each class has 2 abilities (only definitions not implemented yet), which are fetched from the server with all related data: icons, descriptions, animations names etc… Also there’s tooltip with spell description - again i didn’t manage to make tooltip showing next to the icon so i picked ad hoc solution and it’s displayed in the middle of the screen.
The last thing which I added are tabs in the settings panel.

Last 3 days i spent on rewriting player controller system , adding key bindings and handling user inputs with some more structured way. I broke movement and combat and for now it’s not working :p. I hope this version(4th or 5th one) which I’m working on will be final and soon I’ll be able to continue working on the abilities.

2 Likes

Hi again :slight_smile:
Today I managed to finish redesigning player controller system. I fixed movement and added again attacks (just sending message to the server without anything else). And finally after week I’m unblocked and can proceed with the cool stuff :slight_smile:

I sat down for a while in the evening today and I added settings tab for sound management. I connected inputs manager with the UI, created simple global countdown animation and mechanism for protecting from button spamming on the UI level (backend stuff still needs to be implemented).

Also I rewrote combat text system. Previously I was displaying damage on dynamic textures belonging to the meshes which was not good idea. when attacking far enemy, dmg was not visible too good. Right now text is displayed on the global UI and to optimise stuff a little bit I added combatTextBlock objects pool and I’m reusing textBlock’s after they disappear from the screen.

Right now I’ll focus most of the forces on the combat system and in the meantime just to recover from thinking maybe I’ll introduce small ‘delights’ into the game :slight_smile:

See You soon :stuck_out_tongue:

1 Like

Hey!
Super short update from the progress. I added message clouds over players in range, when posting in the chat.

Combat system slowly in progress…

2 Likes

Hello friends!
Long time no update from me. My goal was to prepare nice generic combat system with proper combat locomotion, spells mechanics, visual effects, cooldowns, time synchronization between players etc. I spent some time on thinking about design and I figured out solutions for most of the problems and…

I created 2-3 abilities for each of the character classes (knight, wizard, archer). So what i have is direct attack into the target, aoe (circle or part of the circle) attacks, aoe with dot effects, projectiles, multi projectiles (triple shot), projectile with aoe effect (explosive shot) and I think that’s all.

Something was blocking me and I couldn’t focus on the design. So finally I end up with spaghetti code glued with duck tape :joy: Code is super ugly and there are no combat locomotion (going to the target etc). Mechanics are super basic and are not fully functional, eg. projectiles are not synchronized properly and there’s no mechanic for removing them (visual removing) after hit into enemy.

At least I discovered new problems before unavoidable refactoring. I will address these problems in the future - after adding few features to the game I’m planning bigger refactoring, writing tests and stability/performance work. But still I have a lot of to do.

For now I’m sharing short video with first visual effect of the ability. When I’ll add visual effects for rest of the abilities I’ll share more.

Greeting! Happy Coding :slight_smile:

3 Likes

It is progressing nicely !!! Congrats !!!

2 Likes

That’s look so cool @Maiu Looking forward to seeing the progress!

1 Like

Hey :slight_smile:
I managed to finish basic visual effects for spells. Even I handled removing projectiles after it hit the target (spaghetti code on top of spaghetti :joy: )
This is promised demo:

1 Like

I have two ideas.

Apply force on fireball attack
If a fireball hits a unit with enough health, the unit stands still. If it dies from the hit, it should be blown away by the impact to show the fireball’s power. Let’s calculate the angle between the object and the player’s direction:

const angle = Vector3.GetAngleBetweenVectors(shootedObject, playerDirection, new Vector3(0, 1, 0))
const impulseDirection = shootedObject.add(new Vector3(0, Math.sin(angle) * 0.1, 0)).normalize()

And then apply the impulse to the object:

physicsImpostor.applyImpulse(impulseDirection.scale(force), object.getAbsolutePosition())
object.actionManager.processTrigger(ActionManager.NothingTrigger, context)

Disappear after death
One more idea to slowly disappear units after death. You can run them async function.

For example MeshAnimator.ts static class for call it from anywhere:

async animateVisibility(mesh: AbstractMesh, from: number = 1, to: number = 0, animationSpeedRatio: number = 1): Promise<void> {
    return new Promise<void>((resolve) => {
      if (mesh) {
        const alphaAnimation = new Animation(
          'alphaAnimation',
          'visibility',
          this.fps,
          Animation.ANIMATIONTYPE_FLOAT,
          Animation.ANIMATIONLOOPMODE_CONSTANT,
        )

        const keys = [
          { frame: 0, value: from },
          { frame: this.fps, value: to },
        ]

        alphaAnimation.setKeys(keys)
        mesh.animations.push(alphaAnimation)

        const onAnimationEnd = () => {
          if (alphaAnimation) {
            mesh.animations = mesh.animations.filter((anim) => anim !== alphaAnimation)
          }
          animation.onAnimationEndObservable.removeCallback(onAnimationEnd)
          resolve()
        }

        const animation = mesh.getScene().beginAnimation(mesh, 0, this.fps, false, animationSpeedRatio, onAnimationEnd)
      } else {
        resolve()
      }
    })
  }

  async animateSubMeshesVisibility(mesh: AbstractMesh, from: number = 1, to: number = 0, animationSpeedRatio: number = 1) {
    return new Promise<void>(async (resolve) => {
      let childMeshes = mesh.getChildMeshes()
      for (let index in childMeshes) {
        let subMesh = childMeshes[index]
        await this.animateVisibility(subMesh, from, to, animationSpeedRatio)
      }
      resolve()
    })
  }

and call it from handler:

  slowDispose(mesh: AbstractMesh) {
    MeshAnimator.animateSubMeshesVisibility(mesh, 1, 0, 0.05).then(() => {
      mesh.dispose()
    })
  }

  fastDispose(mesh: AbstractMesh) {
    MeshAnimator.animateSubMeshesVisibility(mesh, 1, 0, 0.5).then(() => {
      mesh.dispose()
    })
  }

After unit death you can call slowDispose, and they will disappear smoothly. Looking for new updates. Can’t wait when we play together in this multiplayer game. :+1: :handshake:

2 Likes