Cap RailroadLayer Maximum Texture Size (#3584)

Resolves #3582

## Description:

Almost exactly the same fix as #3574 , just to RailroadLayer instead of
StuctureLayer.

While browsers like Firefox will report their maximum texture size of
16384, going over 8192 causes extreme VRAM usage and massive FPS drops.
This issue is slightly more elusive as the RailroadLayer texture is not
rendered until the first railroad is created, meaning FPS will suddenly
drop mid-game.

This PR sets the RailroadLayer texture size to cap at 8192, while
keeping near-exact scales. The result is increased performance, reduced
VRAM Usage, (especially in larger maps), and the resolution of the
unplayable performance issues when RailroadLayer is present, with zero
noticeable degradation.

All tested on Giant World, where the issues were first spotted, but
applies to all maps.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

Discord: @EnderBoy9217
This commit is contained in:
David
2026-04-23 11:39:03 -07:00
committed by GitHub
parent 4fd162415a
commit 236f611f61
+27 -6
View File
@@ -155,12 +155,30 @@ export class RailroadLayer implements Layer {
if (context === null) throw new Error("2d context not supported");
this.context = context;
// Firefox's GPU limit is 8192, only known browser issue
const maxTextureSize = 8192;
const scaleX = maxTextureSize / this.game.width();
const scaleY = maxTextureSize / this.game.height();
const targetScale = Math.min(2, scaleX, scaleY);
this.canvas.width = Math.max(
1,
Math.floor(this.game.width() * targetScale),
);
this.canvas.height = Math.max(
1,
Math.floor(this.game.height() * targetScale),
);
// Enable smooth scaling
this.context.imageSmoothingEnabled = true;
this.context.imageSmoothingQuality = "high";
this.canvas.width = this.game.width() * 2;
this.canvas.height = this.game.height() * 2;
// Scale context so existing *2 rendering math continues to work automatically
this.context.scale(
this.canvas.width / (this.game.width() * 2),
this.canvas.height / (this.game.height() * 2),
);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [_, rail] of this.existingRailroads) {
@@ -215,10 +233,13 @@ export class RailroadLayer implements Layer {
return;
}
const srcX = visLeft * 2;
const srcY = visTop * 2;
const srcW = visWidth * 2;
const srcH = visHeight * 2;
const actualScaleX = this.canvas.width / this.game.width();
const actualScaleY = this.canvas.height / this.game.height();
const srcX = visLeft * actualScaleX;
const srcY = visTop * actualScaleY;
const srcW = visWidth * actualScaleX;
const srcH = visHeight * actualScaleY;
const dstX = -this.game.width() / 2 + visLeft;
const dstY = -this.game.height() / 2 + visTop;