From 9085f32ec368147ec68c17cf5408f6d2adba8064 Mon Sep 17 00:00:00 2001 From: tobspr Date: Fri, 14 Aug 2020 09:38:48 +0200 Subject: [PATCH] Add multiple performance settings --- src/js/changelog.js | 1 + src/js/core/config.js | 3 + src/js/game/core.js | 36 ++---- src/js/game/hud/hud.js | 2 - src/js/game/hud/parts/processing_overlay.js | 112 ----------------- src/js/game/hud/parts/screenshot_exporter.js | 10 +- src/js/game/map_chunk.js | 23 +++- src/js/game/map_chunk_view.js | 5 +- src/js/game/map_view.js | 36 +++--- src/js/game/root.js | 3 - src/js/game/systems/lever.js | 31 +++-- src/js/game/systems/map_resources.js | 122 +++++++++++++++---- src/js/game/time/game_time.js | 5 - src/js/profile/application_settings.js | 71 +++++++---- src/js/states/ingame.js | 11 -- translations/base-en.yaml | 21 +++- 16 files changed, 239 insertions(+), 253 deletions(-) delete mode 100644 src/js/game/hud/parts/processing_overlay.js diff --git a/src/js/changelog.js b/src/js/changelog.js index 420d07c0..07902b80 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -12,6 +12,7 @@ export const CHANGELOG = [ "Fix rare crash regarding the buildings toolbar (by isaisstillalive)", "Fixed some phrases (by EnderDoom77)", "Zoom towards mouse cursor (by Dimava)", + "Added multiple settings to optimize the performance", "Updated the soundtrack again, it is now 40 minutes in total!", "Updated and added new translations (Thanks to all contributors!)", "Allow editing waypoints (by isaisstillalive)", diff --git a/src/js/core/config.js b/src/js/core/config.js index 4295c3af..3f6362c1 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -46,6 +46,7 @@ export const globalConfig = { // Map mapChunkSize: 16, mapChunkOverviewMinZoom: 0.9, + mapChunkWorldSize: null, // COMPUTED // Belt speeds // NOTICE: Update webpack.production.config too! @@ -110,6 +111,8 @@ export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // Automatic calculations globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5; +globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize; + // Dynamic calculations if (globalConfig.debug.disableMapOverview) { globalConfig.mapChunkOverviewMinZoom = 0; diff --git a/src/js/game/core.js b/src/js/game/core.js index fd5ab68e..7bba81bd 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -1,8 +1,6 @@ /* typehints:start */ -import { InGameState } from "../states/ingame"; import { Application } from "../application"; /* typehints:end */ - import { BufferMaintainer } from "../core/buffer_maintainer"; import { disableImageSmoothing, enableImageSmoothing, registerCanvas } from "../core/buffer_utils"; import { globalConfig } from "../core/config"; @@ -10,12 +8,16 @@ import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager"; import { DrawParameters } from "../core/draw_parameters"; import { gMetaBuildingRegistry } from "../core/global_registries"; import { createLogger } from "../core/logging"; +import { Rectangle } from "../core/rectangle"; +import { randomInt } from "../core/utils"; import { Vector } from "../core/vector"; import { Savegame } from "../savegame/savegame"; import { SavegameSerializer } from "../savegame/savegame_serializer"; +import { InGameState } from "../states/ingame"; import { AutomaticSave } from "./automatic_save"; import { MetaHubBuilding } from "./buildings/hub"; import { Camera } from "./camera"; +import { DynamicTickrate } from "./dynamic_tickrate"; import { EntityManager } from "./entity_manager"; import { GameSystemManager } from "./game_system_manager"; import { HubGoals } from "./hub_goals"; @@ -23,15 +25,12 @@ import { GameHUD } from "./hud/hud"; import { KeyActionMapper } from "./key_action_mapper"; import { GameLogic } from "./logic"; import { MapView } from "./map_view"; -import { GameRoot, enumLayer } from "./root"; +import { defaultBuildingVariant } from "./meta_building"; +import { ProductionAnalytics } from "./production_analytics"; +import { enumLayer, GameRoot } from "./root"; import { ShapeDefinitionManager } from "./shape_definition_manager"; import { SoundProxy } from "./sound_proxy"; import { GameTime } from "./time/game_time"; -import { ProductionAnalytics } from "./production_analytics"; -import { randomInt } from "../core/utils"; -import { defaultBuildingVariant } from "./meta_building"; -import { DynamicTickrate } from "./dynamic_tickrate"; -import { Rectangle } from "../core/rectangle"; const logger = createLogger("ingame/core"); @@ -233,10 +232,6 @@ export class GameCore { tick(deltaMs) { const root = this.root; - if (root.hud.parts.processingOverlay.hasTasks() || root.hud.parts.processingOverlay.isRunning()) { - return true; - } - // Extract current real time root.time.updateRealtimeNow(); @@ -326,14 +321,6 @@ export class GameCore { const root = this.root; const systems = root.systemMgr.systems; - const taskRunner = root.hud.parts.processingOverlay; - if (taskRunner.hasTasks()) { - if (!taskRunner.isRunning()) { - taskRunner.process(); - } - return; - } - this.root.dynamicTickrate.onFrameRendered(); if (!this.shouldRender()) { @@ -357,15 +344,16 @@ export class GameCore { // Compute optimal zoom level and atlas scale const zoomLevel = root.camera.zoomLevel; + const lowQuality = root.app.settings.getAllSettings().lowQualityTextures; const effectiveZoomLevel = (zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness; let desiredAtlasScale = "0.1"; - if (effectiveZoomLevel > 0.75) { + if (effectiveZoomLevel > 0.75 && !lowQuality) { desiredAtlasScale = "1"; - } else if (effectiveZoomLevel > 0.5) { + } else if (effectiveZoomLevel > 0.5 && !lowQuality) { desiredAtlasScale = "0.75"; - } else if (effectiveZoomLevel > 0.25) { + } else if (effectiveZoomLevel > 0.25 && !lowQuality) { desiredAtlasScale = "0.5"; } else if (effectiveZoomLevel > 0.1) { desiredAtlasScale = "0.25"; @@ -380,7 +368,7 @@ export class GameCore { root: root, }); - if (G_IS_DEV && (globalConfig.debug.testCulling || globalConfig.debug.hideFog)) { + if (G_IS_DEV && globalConfig.debug.testCulling) { context.clearRect(0, 0, root.gameWidth, root.gameHeight); } diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index eb1f215e..88ae859a 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -8,7 +8,6 @@ import { TrailerMaker } from "./trailer_maker"; import { Signal } from "../../core/signal"; import { DrawParameters } from "../../core/draw_parameters"; -import { HUDProcessingOverlay } from "./parts/processing_overlay"; import { HUDBuildingsToolbar } from "./parts/buildings_toolbar"; import { HUDBuildingPlacer } from "./parts/building_placer"; import { HUDBlueprintPlacer } from "./parts/blueprint_placer"; @@ -57,7 +56,6 @@ export class GameHUD { */ initialize() { this.parts = { - processingOverlay: new HUDProcessingOverlay(this.root), buildingsToolbar: new HUDBuildingsToolbar(this.root), wiresToolbar: new HUDWiresToolbar(this.root), blueprintPlacer: new HUDBlueprintPlacer(this.root), diff --git a/src/js/game/hud/parts/processing_overlay.js b/src/js/game/hud/parts/processing_overlay.js deleted file mode 100644 index 95383dfd..00000000 --- a/src/js/game/hud/parts/processing_overlay.js +++ /dev/null @@ -1,112 +0,0 @@ -import { DynamicDomAttach } from "../dynamic_dom_attach"; -import { BaseHUDPart } from "../base_hud_part"; -import { makeDiv } from "../../../core/utils"; -import { Signal } from "../../../core/signal"; -import { InputReceiver } from "../../../core/input_receiver"; -import { createLogger } from "../../../core/logging"; - -const logger = createLogger("hud/processing_overlay"); - -export class HUDProcessingOverlay extends BaseHUDPart { - constructor(root) { - super(root); - this.tasks = []; - this.computeTimeout = null; - - this.root.signals.performAsync.add(this.queueTask, this); - - this.allTasksFinished = new Signal(); - this.inputReceiver = new InputReceiver("processing-overlay"); - - this.root.signals.aboutToDestruct.add(() => - this.root.app.inputMgr.destroyReceiver(this.inputReceiver) - ); - } - - createElements(parent) { - this.element = makeDiv( - parent, - "rg_HUD_ProcessingOverlay", - ["hudElement"], - ` - - Computing - - ` - ); - } - - initialize() { - this.domWatcher = new DynamicDomAttach(this.root, this.element, { - timeToKeepSeconds: 0, - }); - } - - queueTask(task, name) { - if (!this.root.gameInitialized) { - // Tasks before the game started can be done directlry - task(); - return; - } - task.__name = name; - this.tasks.push(task); - } - - hasTasks() { - return this.tasks.length > 0; - } - - isRunning() { - return this.computeTimeout !== null; - } - - processSync() { - const now = performance.now(); - while (this.tasks.length > 0) { - const workload = this.tasks[0]; - workload.call(); - this.tasks.shift(); - } - const duration = performance.now() - now; - if (duration > 100) { - logger.log("Tasks done slow (SYNC!) within", (performance.now() - now).toFixed(2), "ms"); - } - } - - process() { - this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReceiver); - - this.domWatcher.update(true); - if (this.tasks.length === 0) { - logger.warn("No tasks but still called process"); - return; - } - - if (this.computeTimeout) { - assert(false, "Double compute queued"); - clearTimeout(this.computeTimeout); - } - - this.computeTimeout = setTimeout(() => { - const now = performance.now(); - while (this.tasks.length > 0) { - const workload = this.tasks[0]; - workload.call(); - this.tasks.shift(); - } - const duration = performance.now() - now; - if (duration > 100) { - logger.log("Tasks done slow within", (performance.now() - now).toFixed(2), "ms"); - } - - this.domWatcher.update(false); - - this.root.app.inputMgr.makeSureDetached(this.inputReceiver); - - clearTimeout(this.computeTimeout); - this.computeTimeout = null; - - this.allTasksFinished.dispatch(); - }); - } -} diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 19c644e9..a3310204 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -63,7 +63,7 @@ export class HUDScreenshotExporter extends BaseHUDPart { } logger.log("ChunkSizePixels:", chunkSizePixels); - const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize); + const chunkScale = chunkSizePixels / globalConfig.mapChunkWorldSize; logger.log("Scale:", chunkScale); logger.log("Allocating buffer, if the factory grew too big it will crash here"); @@ -79,10 +79,10 @@ export class HUDScreenshotExporter extends BaseHUDPart { logger.log("Got buffer, rendering now ..."); const visibleRect = new Rectangle( - minChunk.x * globalConfig.mapChunkSize * globalConfig.tileSize, - minChunk.y * globalConfig.mapChunkSize * globalConfig.tileSize, - dimensions.x * globalConfig.mapChunkSize * globalConfig.tileSize, - dimensions.y * globalConfig.mapChunkSize * globalConfig.tileSize + minChunk.x * globalConfig.mapChunkWorldSize, + minChunk.y * globalConfig.mapChunkWorldSize, + dimensions.x * globalConfig.mapChunkWorldSize, + dimensions.y * globalConfig.mapChunkWorldSize ); const parameters = new DrawParameters({ context, diff --git a/src/js/game/map_chunk.js b/src/js/game/map_chunk.js index 84b9e47a..d42e8eb6 100644 --- a/src/js/game/map_chunk.js +++ b/src/js/game/map_chunk.js @@ -1,7 +1,12 @@ import { GameRoot, enumLayer } from "./root"; import { globalConfig } from "../core/config"; import { createLogger } from "../core/logging"; -import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "../core/utils"; +import { + clamp, + fastArrayDeleteValueIfContained, + make2DUndefinedArray, + fastArrayDeleteValue, +} from "../core/utils"; import { Vector } from "../core/vector"; import { BaseItem } from "./base_item"; import { enumColors } from "./colors"; @@ -39,6 +44,15 @@ export class MapChunk { /** @type {Array} */ this.containedEntities = []; + /** + * Which entities this chunk contains, sorted by layer + * @type {Object>} + */ + this.containedEntitiesByLayer = { + [enumLayer.regular]: [], + [enumLayer.wires]: [], + }; + /** * Store which patches we have so we can render them in the overview * @type {Array<{pos: Vector, item: BaseItem, size: number }>} @@ -403,8 +417,9 @@ export class MapChunk { assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY); if (oldContents) { - // Remove from list + // Remove from list (the old contents must be reigstered) fastArrayDeleteValueIfContained(this.containedEntities, oldContents); + fastArrayDeleteValueIfContained(this.containedEntitiesByLayer[layer], oldContents); } if (layer === enumLayer.regular) { @@ -417,6 +432,10 @@ export class MapChunk { if (this.containedEntities.indexOf(contents) < 0) { this.containedEntities.push(contents); } + + if (this.containedEntitiesByLayer[layer].indexOf(contents) < 0) { + this.containedEntitiesByLayer[layer].push(contents); + } } } } diff --git a/src/js/game/map_chunk_view.js b/src/js/game/map_chunk_view.js index 845fd331..17d4d4b8 100644 --- a/src/js/game/map_chunk_view.js +++ b/src/js/game/map_chunk_view.js @@ -69,13 +69,14 @@ export class MapChunkView extends MapChunk { redrawMethod: this.generateOverlayBuffer.bind(this), }); - const dims = globalConfig.mapChunkSize * globalConfig.tileSize; + const dims = globalConfig.mapChunkWorldSize; + // Draw chunk "pixel" art parameters.context.imageSmoothingEnabled = false; - parameters.context.drawImage(sprite, this.x * dims, this.y * dims, dims, dims); parameters.context.imageSmoothingEnabled = true; + // Draw patch items if (this.root.currentLayer === enumLayer.regular) { for (let i = 0; i < this.patches.length; ++i) { const patch = this.patches[i]; diff --git a/src/js/game/map_view.js b/src/js/game/map_view.js index 62039468..c98e7c4b 100644 --- a/src/js/game/map_view.js +++ b/src/js/game/map_view.js @@ -195,17 +195,19 @@ export class MapView extends BaseMap { ); } - const dpi = this.backgroundCacheDPI; - parameters.context.scale(1 / dpi, 1 / dpi); - - parameters.context.fillStyle = this.cachedBackgroundPattern; - parameters.context.fillRect( - parameters.visibleRect.x * dpi, - parameters.visibleRect.y * dpi, - parameters.visibleRect.w * dpi, - parameters.visibleRect.h * dpi - ); - parameters.context.scale(dpi, dpi); + if (!this.root.app.settings.getAllSettings().disableTileGrid) { + const dpi = this.backgroundCacheDPI; + parameters.context.scale(1 / dpi, 1 / dpi); + + parameters.context.fillStyle = this.cachedBackgroundPattern; + parameters.context.fillRect( + parameters.visibleRect.x * dpi, + parameters.visibleRect.y * dpi, + parameters.visibleRect.w * dpi, + parameters.visibleRect.h * dpi + ); + parameters.context.scale(dpi, dpi); + } this.drawVisibleChunks(parameters, MapChunkView.prototype.drawBackgroundLayer); @@ -233,16 +235,16 @@ export class MapView extends BaseMap { for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { parameters.context.fillStyle = "#ffaaaa"; parameters.context.fillRect( - chunkX * globalConfig.mapChunkSize * globalConfig.tileSize, - chunkY * globalConfig.mapChunkSize * globalConfig.tileSize, - globalConfig.mapChunkSize * globalConfig.tileSize, + chunkX * globalConfig.mapChunkWorldSize, + chunkY * globalConfig.mapChunkWorldSize, + globalConfig.mapChunkWorldSize, 3 ); parameters.context.fillRect( - chunkX * globalConfig.mapChunkSize * globalConfig.tileSize, - chunkY * globalConfig.mapChunkSize * globalConfig.tileSize, + chunkX * globalConfig.mapChunkWorldSize, + chunkY * globalConfig.mapChunkWorldSize, 3, - globalConfig.mapChunkSize * globalConfig.tileSize + globalConfig.mapChunkWorldSize ); } } diff --git a/src/js/game/root.js b/src/js/game/root.js index df0db09e..3279c693 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -162,9 +162,6 @@ export class GameRoot { // Called right after game is initialized postLoadHook: /** @type {TypedSignal<[]>} */ (new Signal()), - // Can be used to trigger an async task - performAsync: /** @type {TypedSignal<[function]>} */ (new Signal()), - shapeDelivered: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()), itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()), diff --git a/src/js/game/systems/lever.js b/src/js/game/systems/lever.js index 2c6718dd..c8ebf1a2 100644 --- a/src/js/game/systems/lever.js +++ b/src/js/game/systems/lever.js @@ -4,6 +4,7 @@ import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item import { MapChunkView } from "../map_chunk_view"; import { globalConfig } from "../../core/config"; import { Loader } from "../../core/loader"; +import { enumLayer } from "../root"; export class LeverSystem extends GameSystemWithFilter { constructor(root) { @@ -31,23 +32,19 @@ export class LeverSystem extends GameSystemWithFilter { * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { - const contents = chunk.contents; - for (let y = 0; y < globalConfig.mapChunkSize; ++y) { - for (let x = 0; x < globalConfig.mapChunkSize; ++x) { - const entity = contents[x][y]; - - if (entity && entity.components.Lever) { - const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff; - - const origin = entity.components.StaticMapEntity.origin; - sprite.drawCached( - parameters, - origin.x * globalConfig.tileSize, - origin.y * globalConfig.tileSize, - globalConfig.tileSize, - globalConfig.tileSize - ); - } + const contents = chunk.containedEntitiesByLayer[enumLayer.regular]; + for (let i = 0; i < contents.length; ++i) { + const entity = contents[i]; + if (entity && entity.components.Lever) { + const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff; + const origin = entity.components.StaticMapEntity.origin; + sprite.drawCached( + parameters, + origin.x * globalConfig.tileSize, + origin.y * globalConfig.tileSize, + globalConfig.tileSize, + globalConfig.tileSize + ); } } } diff --git a/src/js/game/systems/map_resources.js b/src/js/game/systems/map_resources.js index 7d8b2ced..ba898813 100644 --- a/src/js/game/systems/map_resources.js +++ b/src/js/game/systems/map_resources.js @@ -1,7 +1,8 @@ -import { GameSystem } from "../game_system"; -import { DrawParameters } from "../../core/draw_parameters"; import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { GameSystem } from "../game_system"; import { MapChunkView } from "../map_chunk_view"; +import { THEME } from "../theme"; export class MapResourcesSystem extends GameSystem { /** @@ -10,39 +11,106 @@ export class MapResourcesSystem extends GameSystem { * @param {MapChunkView} chunk */ drawChunk(parameters, chunk) { + const basicChunkBackground = this.root.buffers.getForKey({ + key: "chunkres", + subKey: chunk.renderKey, + w: globalConfig.mapChunkSize, + h: globalConfig.mapChunkSize, + dpi: 1, + redrawMethod: this.generateChunkBackground.bind(this, chunk), + }); + + parameters.context.imageSmoothingEnabled = false; + parameters.context.drawImage( + basicChunkBackground, + chunk.tileX * globalConfig.tileSize, + chunk.tileY * globalConfig.tileSize, + globalConfig.mapChunkWorldSize, + globalConfig.mapChunkWorldSize + ); + parameters.context.imageSmoothingEnabled = true; + parameters.context.globalAlpha = 0.5; + if (this.root.app.settings.getAllSettings().lowQualityMapResources) { + // LOW QUALITY: Draw patch items only + for (let i = 0; i < chunk.patches.length; ++i) { + const patch = chunk.patches[i]; + + patch.item.draw( + chunk.x * globalConfig.mapChunkWorldSize + patch.pos.x * globalConfig.tileSize, + chunk.y * globalConfig.mapChunkWorldSize + patch.pos.y * globalConfig.tileSize, + parameters, + Math.min(80, 40 / parameters.zoomLevel) + ); + } + } else { + // HIGH QUALITY: Draw all items + const layer = chunk.lowerLayer; + for (let x = 0; x < globalConfig.mapChunkSize; ++x) { + const row = layer[x]; + const worldX = (chunk.tileX + x) * globalConfig.tileSize; + for (let y = 0; y < globalConfig.mapChunkSize; ++y) { + const lowerItem = row[y]; + if (lowerItem) { + const worldY = (chunk.tileY + y) * globalConfig.tileSize; + + if ( + !parameters.visibleRect.containsRect4Params( + worldX, + worldY, + globalConfig.tileSize, + globalConfig.tileSize + ) + ) { + // Clipped + continue; + } + + // parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource(); + // parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize); + lowerItem.draw( + worldX + globalConfig.halfTileSize, + worldY + globalConfig.halfTileSize, + parameters + ); + } + } + } + } + parameters.context.globalAlpha = 1; + } + + /** + * + * @param {MapChunkView} chunk + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + generateChunkBackground(chunk, canvas, context, w, h, dpi) { + if (this.root.app.settings.getAllSettings().disableTileGrid) { + // The map doesn't draw a background, so we have to + + context.fillStyle = THEME.map.background; + context.fillRect(0, 0, w, h); + } else { + context.clearRect(0, 0, w, h); + } + + context.globalAlpha = 0.5; const layer = chunk.lowerLayer; for (let x = 0; x < globalConfig.mapChunkSize; ++x) { const row = layer[x]; - const worldX = (chunk.tileX + x) * globalConfig.tileSize; for (let y = 0; y < globalConfig.mapChunkSize; ++y) { - const lowerItem = row[y]; - if (lowerItem) { - const worldY = (chunk.tileY + y) * globalConfig.tileSize; - - if ( - !parameters.visibleRect.containsRect4Params( - worldX, - worldY, - globalConfig.tileSize, - globalConfig.tileSize - ) - ) { - // Clipped - continue; - } - - parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource(); - parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize); - lowerItem.draw( - worldX + globalConfig.halfTileSize, - worldY + globalConfig.halfTileSize, - parameters - ); + const item = row[y]; + if (item) { + context.fillStyle = item.getBackgroundColorAsResource(); + context.fillRect(x, y, 1, 1); } } } - parameters.context.globalAlpha = 1; } } diff --git a/src/js/game/time/game_time.js b/src/js/game/time/game_time.js index 7d0c310d..9b418d4c 100644 --- a/src/js/game/time/game_time.js +++ b/src/js/game/time/game_time.js @@ -153,11 +153,6 @@ export class GameTime extends BasicSerializableObject { ); break; } - - // If we queued async tasks, perform them next frame and do not update anymore - if (this.root.hud.parts.processingOverlay.hasTasks()) { - break; - } } } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 2167c77c..f3f61c4a 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -19,6 +19,7 @@ const logger = createLogger("application_settings"); export const enumCategories = { general: "general", userInterface: "userInterface", + performance: "performance", advanced: "advanced", }; @@ -148,34 +149,34 @@ export const allApplicationSettings = [ }), new BoolSetting( - "fullscreen", + "soundsMuted", enumCategories.general, /** * @param {Application} app */ - (app, value) => { - if (app.platformWrapper.getSupportsFullscreen()) { - app.platformWrapper.setFullscreen(value); - } - }, - !IS_DEMO + (app, value) => app.sound.setSoundsMuted(value) ), - new BoolSetting( - "soundsMuted", + "musicMuted", enumCategories.general, /** * @param {Application} app */ - (app, value) => app.sound.setSoundsMuted(value) + (app, value) => app.sound.setMusicMuted(value) ), + new BoolSetting( - "musicMuted", + "fullscreen", enumCategories.general, /** * @param {Application} app */ - (app, value) => app.sound.setMusicMuted(value) + (app, value) => { + if (app.platformWrapper.getSupportsFullscreen()) { + app.platformWrapper.setFullscreen(value); + } + }, + !IS_DEMO ), new BoolSetting( @@ -187,7 +188,6 @@ export const allApplicationSettings = [ (app, value) => null ), - // GAME new BoolSetting("offerHints", enumCategories.userInterface, (app, value) => {}), new EnumSetting("theme", { @@ -220,16 +220,6 @@ export const allApplicationSettings = [ (app, id) => null, }), - new EnumSetting("refreshRate", { - options: ["60", "75", "100", "120", "144", "165", "250", G_IS_DEV ? "10" : "500"], - valueGetter: rate => rate, - textGetter: rate => rate + " Hz", - category: enumCategories.advanced, - restartRequired: false, - changeCb: (app, id) => {}, - enabled: !IS_DEMO, - }), - new EnumSetting("scrollWheelSensitivity", { options: scrollWheelSensitivities.sort((a, b) => a.scale - b.scale), valueGetter: scale => scale.id, @@ -258,6 +248,20 @@ export const allApplicationSettings = [ new BoolSetting("compactBuildingInfo", enumCategories.userInterface, (app, value) => {}), new BoolSetting("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}), new BoolSetting("rotationByBuilding", enumCategories.advanced, (app, value) => {}), + + new EnumSetting("refreshRate", { + options: ["60", "75", "100", "120", "144", "165", "250", "500"], + valueGetter: rate => rate, + textGetter: rate => rate + " Hz", + category: enumCategories.performance, + restartRequired: false, + changeCb: (app, id) => {}, + enabled: !IS_DEMO, + }), + + new BoolSetting("lowQualityMapResources", enumCategories.performance, (app, value) => {}), + new BoolSetting("disableTileGrid", enumCategories.performance, (app, value) => {}), + new BoolSetting("lowQualityTextures", enumCategories.performance, (app, value) => {}), ]; export function getApplicationSettingById(id) { @@ -288,6 +292,10 @@ class SettingsStorage { this.enableColorBlindHelper = false; + this.lowQualityMapResources = false; + this.disableTileGrid = false; + this.lowQualityTextures = false; + /** * @type {Object.} */ @@ -487,7 +495,7 @@ export class ApplicationSettings extends ReadWriteProxy { } getCurrentVersion() { - return 18; + return 21; } /** @param {{settings: SettingsStorage, version: number}} data */ @@ -565,6 +573,21 @@ export class ApplicationSettings extends ReadWriteProxy { data.version = 18; } + if (data.version < 19) { + data.settings.lowQualityMapResources = false; + data.version = 19; + } + + if (data.version < 20) { + data.settings.disableTileGrid = false; + data.version = 20; + } + + if (data.version < 21) { + data.settings.lowQualityTextures = false; + data.version = 21; + } + return ExplainedResult.good(); } } diff --git a/src/js/states/ingame.js b/src/js/states/ingame.js index 33d7e15b..3eea38b7 100644 --- a/src/js/states/ingame.js +++ b/src/js/states/ingame.js @@ -381,17 +381,6 @@ export class InGameState extends GameState { } } - // // Check if we can show an ad - // // DISABLED - // if (this.stage === stages.s10_gameRunning && !this.core.root.hud.parts.processingOverlay.hasTasks()) { - // if (this.app.isRenderable() && this.app.adProvider.getCanShowVideoAd()) { - // this.saveThenGoToState("WatchAdState", { - // nextStateId: "RunningGameState", - // nextStatePayload: this.creationPayload, - // }); - // } - // } - if (this.stage === stages.s10_gameRunning) { this.core.tick(dt); } diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 2b47fc2c..b1a53f21 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -670,6 +670,7 @@ settings: general: General userInterface: User Interface advanced: Advanced + performance: Performance versionBadges: dev: Development @@ -759,9 +760,9 @@ settings: light: Light refreshRate: - title: Simulation Target + title: Tick Rate description: >- - If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow. + The game will automatically adjust the tickrate to be between this target tickrate and half of it. For example, with a tickrate of 60hz, the game will try to stay at 60hz, and if your computer can't handle it it will go down until it eventually reaches 30hz. alwaysMultiplace: title: Multiplace @@ -798,6 +799,22 @@ settings: description: >- Disables the warning dialogs brought up when cutting/deleting more than 100 entities. + lowQualityMapResources: + title: Low Quality Map Resources + description: >- + Simplifies the rendering of resources on the map when zoomed in to improve performance. + It even looks cleaner, so be sure to try it out! + + disableTileGrid: + title: Disable Grid + description: >- + Disabling the tile grid can help with the performance. This also makes the game look cleaner! + + lowQualityTextures: + title: Low quality textures (Ugly) + description: >- + Uses low quality textures to save performance. This will make the game look very ugly! + keybindings: title: Keybindings hint: >-