lemverse icon indicating copy to clipboard operation
lemverse copied to clipboard

Loading a level client-side is CPU-intensive server-side

Open ramnes opened this issue 1 year ago • 4 comments

We are seeing some levels that take something like 20+ seconds to load on a 2021 M1 MacBook Air (Chrome).

It doesn't happen on empty levels. It seems that the more tiles a level has, the longer it takes to load, which makes sense. What I don't explain is why it takes so much time to load on our instance when other levels with as many tiles on app.lemverse.com seem to load very fast.

The issue seems to be on the client side (all HTTP requests complete quite quickly); but that's weird because then it doesn't make sense that the loading time depends on the instance it's connected to.

We have planned to investigate the issue, so don't feel obligated to spend time on this, but any clues would be appreciated!

ramnes avatar Aug 18 '22 09:08 ramnes

I've been looking for solutions to this problem quite a bit. The problem comes mainly from the Tiles collection.

Each cell is a Tile document, a level has by default 8 layers and per layer 100x100 cells. This makes a maximum synchronization of 80000 documents to load, even if a level of 100x100 has on average 16000 documents, it is already huge.

The solutions I have in mind:

Change the structure of a level

We should delete the Tiles collection and have the following syntax on the level:

{
  "_id": "lvl_x",
  "layers": [
    { tiles: [0, 100000, 60000, ... ] }
    { tiles: [5, 4, 8747, ... ] }
    { tiles: [2, 20, 2535, ... ] }
    { tiles: [3, 2399, 84682, ... ] }
  ]
}

The problem with this solution is that we lose the reactivity of Meteor when editing the level but the loading time will be much less important and the server will not have to monitor the X document of the tiles

Generate the level server side

The idea would be to have the whole map static (except the entities). Images would be generated on the server side.

  • A layer under the character
  • A layer above the character

Each level would be split in chunks, it's the same way Google Maps works.

Advantages:

  • Instant loading of the level
  • Less textures on the client side (no need to load all tilesets) and the generated images will be ~100kb max
  • Less greedy rendering for the client: a few images to display rather than several GPU calls
  • The culling pass will not have to go through the whole tilemap to know what is on the screen, this is the most greedy part on the client side currently

Disadvantages :

  • Loss of responsiveness when editing

Donorhan avatar Aug 18 '22 10:08 Donorhan

Supreme leader Dono, this sound like an elegant solution.

Am a lemverse power user with a macbook 16 inch that’s good to bbq on when I use lemverse on my laptop whilst not being plugged in.

Drains battery like crazy to. So much so we started to use it less cause we have to protect our remaining batteries when not plugged in for a longer period of time.

Thanks for fixing this guys. So love your product. Thanks for all the work. Love to see it grow too.

On Thu, 18 Aug 2022 at 12:34, Dono @.***> wrote:

I've been looking for solutions to this problem quite a bit. The problem comes mainly from the Tiles collection.

Each cell is a Tile document, a level has by default 8 layers and per layer 100x100 cells. This makes a maximum synchronization of 80000 documents to load, even if a level of 100x100 has on average 16000 documents, it is already huge.

The solutions I have in mind: Change the structure of a level

We should delete the Tiles collection and have the following syntax on the level:

{ "_id": "lvl_x", "layers": [ { tiles: [0, 100000, 60000, ... ] } { tiles: [5, 4, 8747, ... ] } { tiles: [2, 20, 2535, ... ] } { tiles: [3, 2399, 84682, ... ] } ] }

The problem with this solution is that we lose the reactivity of Meteor when editing the level but the loading time will be much less important and the server will not have to monitor the X document of the tiles Generate the level server side

The idea would be to have the whole map static (except the entities). Images would be generated on the server side.

  • A layer under the character
  • A layer above the character

Each level would be split in chunks, it's the same way Google Maps works.

Advantages:

  • Instant loading of the level
  • Less textures on the client side (no need to load all tilesets) and the generated images will be ~100kb max
  • Less greedy rendering for the client: a few images to display rather than several GPU calls
  • The culling pass will not have to go through the whole tilemap to know what is on the screen, this is the most greedy part on the client side currently

Disadvantages :

  • Loss of responsiveness when editing

— Reply to this email directly, view it on GitHub https://github.com/l3mpire/lemverse/issues/80#issuecomment-1219326923, or unsubscribe https://github.com/notifications/unsubscribe-auth/A2OPTEKBOM5A6ZGVIEAEMOTVZYGULANCNFSM564QMMOQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Stephane Maes

Founder

CEO/CRO +32 498 71 91 82 <+32%20498%2071%2091%2082> @.*** www.salesgladiators.eu [image: linkedin] https://www.linkedin.com/in/oliviertytgat/ Book a meeting @.***/>

ste-mae avatar Aug 18 '22 11:08 ste-mae

We found a workaround by giving more CPU to lemverse, which appeared to be the bottleneck here. It seems that a user loading a level is very CPU-intensive for lemverse on the server-side, and that's the real issue to fix.

ramnes avatar Aug 31 '22 10:08 ramnes

It's probably related to tile synchronization which requires a constant link between the client and the server 😢. I think that removing the subscribe to tiles and managing the edition with simple events out of observe Meteor would fix the problem for both client and server

Donorhan avatar Sep 01 '22 07:09 Donorhan