How to optimize this procedurall generated 2d platformer made with threejs?

This is the game.html file:
2d platformer v155.html (15.7 KB)
When i test it it goes slower, and slowler, and crashes. Idk about this but its too weird, like the code gets alive. IDK about gettings it, but at least we made the platformer, so… it’s possible to optimize it? Thanks anyway!

EDIT1: Im improving it with all my efforts, but… it doesnt cause any result.

EDIT2: FPS Count:
image

EDIT 3 MB Count, ascendind per use:
image

EDIT 4:
I made Y-Greeding finally on this chunk, and the results are the same:
2d platformer v195.html (13.5 KB)

You’re calling renderer.resize() in one of your render loops.

You should only call that when the window has actually been resized.

Then also you have 2 requestAnimationFrames running, which isn’t great.

Inside :
render2=()=>{

You are:
imgPurpleCoin=new Image()
imgPurpleCoin.src=“purple coin 4.png”

you definitely don’t want to do that in the render function…
This is making it try to load a new image 60 times a second…
That is probably what is killing your framerate…

Instead, do that once at start time…

If you want more help with this whole thing, you could put it in a glitch and we can all poke at it.

1 Like

:twisted_rightwards_arrows: Premise:
In both histogram gaps, there is a wedge which is inversely identical. This leak/growth is your timer GC loop for unused blocks. To prove this in isolation, stand still and there will be no issue…? FYI memory may grow regardless of your code, from surreptitious code injections.
:warning: Action 1:
If player stops, i.e. movement delta is <1, perform thorough GC. This may entail async/await to ensure function hoist in a single-threaded loop. Excepting moving players or clouds, rebuild the entire world store…? Yes (not) production code but allow cleanup.
:snake: Action 2:
Radius may be refactored as a cone-of-visibility… to weight cleanup of the forward-facing FOV less than the rear. Assuming player trends on a path…? Join two biased influence spheres and perform cleanup as before (or use three vectors). This technique consumes gaps appropriately as the character moves.

Peak values,
Hillsk87 64 3 21 0

Hello. I tried greeding, but the meshes out of render distance doesnt dissapear:

This is my html file:

2d platformer v195.html (13.5 KB)

EDIT 1:

Im on wrong html file, so I have corrected the outer area:

But after amount of time it crashes.

Do u say to use a PrevX and check the distance for if it is enough near, change PrevX and generate the terrain around the camera or generate terrain when players move?

EDIT 1: I have prepared that, but it crashed my game.

EDIT 2: I added:

		prevX1=0
		setInterval(()=>{
			if(Math.abs(prevX1-camera.position.x)>10){
				prevX1=camera.position.x
				init2()
			}
		},1000/60)
		init2()

But it doesnt worked for fixing the lag.

EDIT 3: I merged into X and Y axis the back geometry, and it didnt showed any result.

EDIT 4: I set the camera.position.z for smaller distance with the terrain and I deleted all out of camera borders, and didnt get any result.

  • before a mesh is removed, also dispose of its map materials.
  • disable texture interpolation and renderer aliasing. You may also find micro-optimizations in depth sorting.
  • Perlin noise array is regenerated every second. Can values be pre-populated on init, or as required by player movement?
  • animationframe can save some conditions as a variable to reduce code and cpu use. Also, some for loops can be combined.
  • a second canvas GUI is clearing a lot, which can be disproportionately slow. Can this be HTML/CSS?
  • use InstancedMesh if possible, or a texture atlas. Or revise to use clones of block prototypes, i.e. _ProtoPipe.
2 Likes

I tried all except instancedMesh. With instanced mesh the scene mades unmodificable, and i dont want it for a small count of geometries game… but thanks anyway…

  • Modify get_catched_coins > distance() to check x, then y (nested if). Z is irrelevant for a side-scrolling platformer, and you may exit early. The setInterval can complete faster, or with less latency.
  • Restrict renderer size to a constant related to game assets… and letterbox with css. Using window innerWidth makes extra work for render. For example: 8x8 pixel art with tiles 64 x 32 is 512x256. Also, your player xy will not slide if you resize the window.

Yes, i corrected some of that before you are saying this, to Math.abs(cube.position.x-block1.position.x) ((Cube position is the player position)). Also, there are things like check_solid which needs that distance function, i cant correct because that code needs x,y,z axis to work…

So the another thing youre saying, im now gonna try it.

EDIT 1:

<canvas id="c2"width="1024"height=“512”>

Its correct?

EDIT 2:

The second thing (the 1024x512 canvas) keeps the same fps than 1000x500 canvas

EDIT 3:

I change the distance function to this:

distance=(obj1,obj2)=>{
return (((obj1.x-obj2.x)**2+(obj1.y-obj2.y)**2)**0.5)
}

and it gets the same fps.

EDIT 4:

I changed distance to this:

distance=(obj1,obj2)=>{
return ((Math.abs(obj1.x-obj2.x)+Math.abs(obj1.y-obj2.y)))
}

And it didnt get any result, the same fps.

EDIT 5:

I had reset the cache and the game broke, so i returned to distance event…

EDIT 6:

I had replaced the function as your instructions says but getted a bug when coins didnt dissapear. I mean on: Math.abs() instead of distance() function.

  • Renderer does not get dimensions from canvas. Your init should setSize, and it’s up to you to keep in sync (i.e. onResize).
  • rename to distance2 if reserved, I couldn’t find it in HTML: if (x1-x2<2) if (y1-y2<2) return true
  • have you tried to throttle fps. Maybe retro 30fps will be more acceptable, with unpredictable Fresnel noise?

1.- I never change my canvas because player can spy farther than others resizing the threejs canvas.
2.- No. Its not if(x1-x2<2), its if(abs(x1-x2)<2) because x1-x2 can be negative or positive, but the absolute value its positive always, perfect for calc distance fields like squares, but thanks for trying to help me anyways :smiley:
3.- Throttle fps is similar to stats.js, i preffer stats.js . Idk about unpredictable Fresnel noise. I will search it.

  1. You’re right, I only meant if you set size on canvas element, the renderer is not necessarily derived from that.
  2. You’re right, I only meant a nested waterfall.
  3. You’re right, I only meant to sync timer intervals. Stats is a monitor, whereas throttle maintains a framerate. Sorry Perlin noise, not Fresnel… I think the coins are from Perlin noise? They could be InstancedMesh and set the count every 1 second to avoid object recreation.

If the problem is texture resource management… just don’t use textures. If you’re looking for a more performant way to handle assets. Voxel remakes of Mario and Zelda (Crossy Road?) use actual “voxel” geometry. There’s also a good pixel filter effect in the Examples you could apply.

Coins can be ShapeGeometry (a yellow oval or octagon extruded). That simplifies InstancedMesh, to change collided coins index color purple (no texture). You can even rotate coins, or do other fun things (shadows?).

You can treat grass the same… flat-shaded primitives. With even less LOC you can add variation (wind?). 1 geometry per block reduces 6 textures for pipe.

I don’t mean to imply rewrite in a day. The generative Perlin noise makes me think of modern (Boomer :face_with_diagonal_mouth:?) techniques. Generative Voxel Doom blood has more voxels than stars in the sky.

Benevolent Affordances,
Starsky 'sk8star" Hutch

I think this problem is imposible. I didnt tried 2d canvas, but i dont think 2d canvas is faster than this.

You’re right, I only meant to bisect the framerate issue. Is it Perlin blocks or texture programs? A quick test to bisect the issue would be to (1) remove Perlin noise and (2) remove textures. Overall, timing and draws is the fundamental problem and solution… which would benefit from instancing, atlas, or primitive geometry.

Edit: I did not see multiplayer elements linked to suggest nondeterministic spying.

Sometimes new code reaches a breakpoint where performance churn is disproportionately ramped by the speed bump…?

I now have tried making barrancs, like this:

And it optimized the rendering event, but not too much. I think we are near to evade the crash.

EDIT 1: Its now as you see in this img:

Interesting, how in image #1 the rightmost block appears to clip the barrancs. I do not recall game logic for perpetual intersections… or is it the FOV?

Interesting, how in image #2 the gooba has a shallow transparent inset under it on the blomcks.

Interesting, how most barrancs stripes repeat is misaligned. Perhaps the Perlin noise kernel exceeds the cluster window. In other words, could you conduct a straw-poll count: how many barrancs are reported versus what you observe visually? It may be orders of magnitude different… requiring a different approach to parallax effect.

Yes, i improved that, now the coins generates upper than camera limits who had been before.
The lag increased a little when I added that middle blocks…
Nothing more to say.

EDIT: I make a huge render distance game, same laggy or more, but at least show the entire game mechanics:

45-60 is decent. Does stats start/update method not surround running code accurately? I see no game controls or playing demo. You cound remove material transparency on the brown block, there is a alphatest pixel below threshold. Congrats?

Its 30-60 fps x_x but aniways, i use stats.js for my script and I use too 3 canvas:
c1=Player info.
c2=Main game.
c3=stats.js
Sorry if i dont the things good, but idk about instancing mesh, its a complex way to produce blocks. Apart of that, idk about another optimization.