mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Add multiple performance settings
This commit is contained in:
parent
9e76606674
commit
9085f32ec3
@ -12,6 +12,7 @@ export const CHANGELOG = [
|
|||||||
"Fix rare crash regarding the buildings toolbar (by isaisstillalive)",
|
"Fix rare crash regarding the buildings toolbar (by isaisstillalive)",
|
||||||
"Fixed some phrases (by EnderDoom77)",
|
"Fixed some phrases (by EnderDoom77)",
|
||||||
"Zoom towards mouse cursor (by Dimava)",
|
"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 the soundtrack again, it is now 40 minutes in total!",
|
||||||
"Updated and added new translations (Thanks to all contributors!)",
|
"Updated and added new translations (Thanks to all contributors!)",
|
||||||
"Allow editing waypoints (by isaisstillalive)",
|
"Allow editing waypoints (by isaisstillalive)",
|
||||||
|
@ -46,6 +46,7 @@ export const globalConfig = {
|
|||||||
// Map
|
// Map
|
||||||
mapChunkSize: 16,
|
mapChunkSize: 16,
|
||||||
mapChunkOverviewMinZoom: 0.9,
|
mapChunkOverviewMinZoom: 0.9,
|
||||||
|
mapChunkWorldSize: null, // COMPUTED
|
||||||
|
|
||||||
// Belt speeds
|
// Belt speeds
|
||||||
// NOTICE: Update webpack.production.config too!
|
// NOTICE: Update webpack.production.config too!
|
||||||
@ -110,6 +111,8 @@ export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|||||||
// Automatic calculations
|
// Automatic calculations
|
||||||
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
|
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
|
||||||
|
|
||||||
|
globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
|
||||||
|
|
||||||
// Dynamic calculations
|
// Dynamic calculations
|
||||||
if (globalConfig.debug.disableMapOverview) {
|
if (globalConfig.debug.disableMapOverview) {
|
||||||
globalConfig.mapChunkOverviewMinZoom = 0;
|
globalConfig.mapChunkOverviewMinZoom = 0;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { InGameState } from "../states/ingame";
|
|
||||||
import { Application } from "../application";
|
import { Application } from "../application";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
import { BufferMaintainer } from "../core/buffer_maintainer";
|
import { BufferMaintainer } from "../core/buffer_maintainer";
|
||||||
import { disableImageSmoothing, enableImageSmoothing, registerCanvas } from "../core/buffer_utils";
|
import { disableImageSmoothing, enableImageSmoothing, registerCanvas } from "../core/buffer_utils";
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
@ -10,12 +8,16 @@ import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
|
|||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
|
import { Rectangle } from "../core/rectangle";
|
||||||
|
import { randomInt } from "../core/utils";
|
||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
import { Savegame } from "../savegame/savegame";
|
import { Savegame } from "../savegame/savegame";
|
||||||
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
||||||
|
import { InGameState } from "../states/ingame";
|
||||||
import { AutomaticSave } from "./automatic_save";
|
import { AutomaticSave } from "./automatic_save";
|
||||||
import { MetaHubBuilding } from "./buildings/hub";
|
import { MetaHubBuilding } from "./buildings/hub";
|
||||||
import { Camera } from "./camera";
|
import { Camera } from "./camera";
|
||||||
|
import { DynamicTickrate } from "./dynamic_tickrate";
|
||||||
import { EntityManager } from "./entity_manager";
|
import { EntityManager } from "./entity_manager";
|
||||||
import { GameSystemManager } from "./game_system_manager";
|
import { GameSystemManager } from "./game_system_manager";
|
||||||
import { HubGoals } from "./hub_goals";
|
import { HubGoals } from "./hub_goals";
|
||||||
@ -23,15 +25,12 @@ import { GameHUD } from "./hud/hud";
|
|||||||
import { KeyActionMapper } from "./key_action_mapper";
|
import { KeyActionMapper } from "./key_action_mapper";
|
||||||
import { GameLogic } from "./logic";
|
import { GameLogic } from "./logic";
|
||||||
import { MapView } from "./map_view";
|
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 { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||||
import { SoundProxy } from "./sound_proxy";
|
import { SoundProxy } from "./sound_proxy";
|
||||||
import { GameTime } from "./time/game_time";
|
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");
|
const logger = createLogger("ingame/core");
|
||||||
|
|
||||||
@ -233,10 +232,6 @@ export class GameCore {
|
|||||||
tick(deltaMs) {
|
tick(deltaMs) {
|
||||||
const root = this.root;
|
const root = this.root;
|
||||||
|
|
||||||
if (root.hud.parts.processingOverlay.hasTasks() || root.hud.parts.processingOverlay.isRunning()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract current real time
|
// Extract current real time
|
||||||
root.time.updateRealtimeNow();
|
root.time.updateRealtimeNow();
|
||||||
|
|
||||||
@ -326,14 +321,6 @@ export class GameCore {
|
|||||||
const root = this.root;
|
const root = this.root;
|
||||||
const systems = root.systemMgr.systems;
|
const systems = root.systemMgr.systems;
|
||||||
|
|
||||||
const taskRunner = root.hud.parts.processingOverlay;
|
|
||||||
if (taskRunner.hasTasks()) {
|
|
||||||
if (!taskRunner.isRunning()) {
|
|
||||||
taskRunner.process();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.root.dynamicTickrate.onFrameRendered();
|
this.root.dynamicTickrate.onFrameRendered();
|
||||||
|
|
||||||
if (!this.shouldRender()) {
|
if (!this.shouldRender()) {
|
||||||
@ -357,15 +344,16 @@ export class GameCore {
|
|||||||
|
|
||||||
// Compute optimal zoom level and atlas scale
|
// Compute optimal zoom level and atlas scale
|
||||||
const zoomLevel = root.camera.zoomLevel;
|
const zoomLevel = root.camera.zoomLevel;
|
||||||
|
const lowQuality = root.app.settings.getAllSettings().lowQualityTextures;
|
||||||
const effectiveZoomLevel =
|
const effectiveZoomLevel =
|
||||||
(zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
|
(zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
|
||||||
|
|
||||||
let desiredAtlasScale = "0.1";
|
let desiredAtlasScale = "0.1";
|
||||||
if (effectiveZoomLevel > 0.75) {
|
if (effectiveZoomLevel > 0.75 && !lowQuality) {
|
||||||
desiredAtlasScale = "1";
|
desiredAtlasScale = "1";
|
||||||
} else if (effectiveZoomLevel > 0.5) {
|
} else if (effectiveZoomLevel > 0.5 && !lowQuality) {
|
||||||
desiredAtlasScale = "0.75";
|
desiredAtlasScale = "0.75";
|
||||||
} else if (effectiveZoomLevel > 0.25) {
|
} else if (effectiveZoomLevel > 0.25 && !lowQuality) {
|
||||||
desiredAtlasScale = "0.5";
|
desiredAtlasScale = "0.5";
|
||||||
} else if (effectiveZoomLevel > 0.1) {
|
} else if (effectiveZoomLevel > 0.1) {
|
||||||
desiredAtlasScale = "0.25";
|
desiredAtlasScale = "0.25";
|
||||||
@ -380,7 +368,7 @@ export class GameCore {
|
|||||||
root: root,
|
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);
|
context.clearRect(0, 0, root.gameWidth, root.gameHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import { TrailerMaker } from "./trailer_maker";
|
|||||||
|
|
||||||
import { Signal } from "../../core/signal";
|
import { Signal } from "../../core/signal";
|
||||||
import { DrawParameters } from "../../core/draw_parameters";
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
import { HUDProcessingOverlay } from "./parts/processing_overlay";
|
|
||||||
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
||||||
import { HUDBuildingPlacer } from "./parts/building_placer";
|
import { HUDBuildingPlacer } from "./parts/building_placer";
|
||||||
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
||||||
@ -57,7 +56,6 @@ export class GameHUD {
|
|||||||
*/
|
*/
|
||||||
initialize() {
|
initialize() {
|
||||||
this.parts = {
|
this.parts = {
|
||||||
processingOverlay: new HUDProcessingOverlay(this.root),
|
|
||||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||||
wiresToolbar: new HUDWiresToolbar(this.root),
|
wiresToolbar: new HUDWiresToolbar(this.root),
|
||||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||||
|
@ -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"],
|
|
||||||
`
|
|
||||||
<span class="prefab_LoadingTextWithAnim">
|
|
||||||
Computing
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,7 +63,7 @@ export class HUDScreenshotExporter extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
logger.log("ChunkSizePixels:", chunkSizePixels);
|
logger.log("ChunkSizePixels:", chunkSizePixels);
|
||||||
|
|
||||||
const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize);
|
const chunkScale = chunkSizePixels / globalConfig.mapChunkWorldSize;
|
||||||
logger.log("Scale:", chunkScale);
|
logger.log("Scale:", chunkScale);
|
||||||
|
|
||||||
logger.log("Allocating buffer, if the factory grew too big it will crash here");
|
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 ...");
|
logger.log("Got buffer, rendering now ...");
|
||||||
|
|
||||||
const visibleRect = new Rectangle(
|
const visibleRect = new Rectangle(
|
||||||
minChunk.x * globalConfig.mapChunkSize * globalConfig.tileSize,
|
minChunk.x * globalConfig.mapChunkWorldSize,
|
||||||
minChunk.y * globalConfig.mapChunkSize * globalConfig.tileSize,
|
minChunk.y * globalConfig.mapChunkWorldSize,
|
||||||
dimensions.x * globalConfig.mapChunkSize * globalConfig.tileSize,
|
dimensions.x * globalConfig.mapChunkWorldSize,
|
||||||
dimensions.y * globalConfig.mapChunkSize * globalConfig.tileSize
|
dimensions.y * globalConfig.mapChunkWorldSize
|
||||||
);
|
);
|
||||||
const parameters = new DrawParameters({
|
const parameters = new DrawParameters({
|
||||||
context,
|
context,
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import { GameRoot, enumLayer } from "./root";
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { createLogger } from "../core/logging";
|
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 { Vector } from "../core/vector";
|
||||||
import { BaseItem } from "./base_item";
|
import { BaseItem } from "./base_item";
|
||||||
import { enumColors } from "./colors";
|
import { enumColors } from "./colors";
|
||||||
@ -39,6 +44,15 @@ export class MapChunk {
|
|||||||
/** @type {Array<Entity>} */
|
/** @type {Array<Entity>} */
|
||||||
this.containedEntities = [];
|
this.containedEntities = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which entities this chunk contains, sorted by layer
|
||||||
|
* @type {Object<enumLayer, Array<Entity>>}
|
||||||
|
*/
|
||||||
|
this.containedEntitiesByLayer = {
|
||||||
|
[enumLayer.regular]: [],
|
||||||
|
[enumLayer.wires]: [],
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store which patches we have so we can render them in the overview
|
* Store which patches we have so we can render them in the overview
|
||||||
* @type {Array<{pos: Vector, item: BaseItem, size: number }>}
|
* @type {Array<{pos: Vector, item: BaseItem, size: number }>}
|
||||||
@ -403,8 +417,9 @@ export class MapChunk {
|
|||||||
assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY);
|
assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY);
|
||||||
|
|
||||||
if (oldContents) {
|
if (oldContents) {
|
||||||
// Remove from list
|
// Remove from list (the old contents must be reigstered)
|
||||||
fastArrayDeleteValueIfContained(this.containedEntities, oldContents);
|
fastArrayDeleteValueIfContained(this.containedEntities, oldContents);
|
||||||
|
fastArrayDeleteValueIfContained(this.containedEntitiesByLayer[layer], oldContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer === enumLayer.regular) {
|
if (layer === enumLayer.regular) {
|
||||||
@ -417,6 +432,10 @@ export class MapChunk {
|
|||||||
if (this.containedEntities.indexOf(contents) < 0) {
|
if (this.containedEntities.indexOf(contents) < 0) {
|
||||||
this.containedEntities.push(contents);
|
this.containedEntities.push(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.containedEntitiesByLayer[layer].indexOf(contents) < 0) {
|
||||||
|
this.containedEntitiesByLayer[layer].push(contents);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,13 +69,14 @@ export class MapChunkView extends MapChunk {
|
|||||||
redrawMethod: this.generateOverlayBuffer.bind(this),
|
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.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
parameters.context.drawImage(sprite, this.x * dims, this.y * dims, dims, dims);
|
parameters.context.drawImage(sprite, this.x * dims, this.y * dims, dims, dims);
|
||||||
parameters.context.imageSmoothingEnabled = true;
|
parameters.context.imageSmoothingEnabled = true;
|
||||||
|
|
||||||
|
// Draw patch items
|
||||||
if (this.root.currentLayer === enumLayer.regular) {
|
if (this.root.currentLayer === enumLayer.regular) {
|
||||||
for (let i = 0; i < this.patches.length; ++i) {
|
for (let i = 0; i < this.patches.length; ++i) {
|
||||||
const patch = this.patches[i];
|
const patch = this.patches[i];
|
||||||
|
@ -195,6 +195,7 @@ export class MapView extends BaseMap {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.root.app.settings.getAllSettings().disableTileGrid) {
|
||||||
const dpi = this.backgroundCacheDPI;
|
const dpi = this.backgroundCacheDPI;
|
||||||
parameters.context.scale(1 / dpi, 1 / dpi);
|
parameters.context.scale(1 / dpi, 1 / dpi);
|
||||||
|
|
||||||
@ -206,6 +207,7 @@ export class MapView extends BaseMap {
|
|||||||
parameters.visibleRect.h * dpi
|
parameters.visibleRect.h * dpi
|
||||||
);
|
);
|
||||||
parameters.context.scale(dpi, dpi);
|
parameters.context.scale(dpi, dpi);
|
||||||
|
}
|
||||||
|
|
||||||
this.drawVisibleChunks(parameters, MapChunkView.prototype.drawBackgroundLayer);
|
this.drawVisibleChunks(parameters, MapChunkView.prototype.drawBackgroundLayer);
|
||||||
|
|
||||||
@ -233,16 +235,16 @@ export class MapView extends BaseMap {
|
|||||||
for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) {
|
for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) {
|
||||||
parameters.context.fillStyle = "#ffaaaa";
|
parameters.context.fillStyle = "#ffaaaa";
|
||||||
parameters.context.fillRect(
|
parameters.context.fillRect(
|
||||||
chunkX * globalConfig.mapChunkSize * globalConfig.tileSize,
|
chunkX * globalConfig.mapChunkWorldSize,
|
||||||
chunkY * globalConfig.mapChunkSize * globalConfig.tileSize,
|
chunkY * globalConfig.mapChunkWorldSize,
|
||||||
globalConfig.mapChunkSize * globalConfig.tileSize,
|
globalConfig.mapChunkWorldSize,
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
parameters.context.fillRect(
|
parameters.context.fillRect(
|
||||||
chunkX * globalConfig.mapChunkSize * globalConfig.tileSize,
|
chunkX * globalConfig.mapChunkWorldSize,
|
||||||
chunkY * globalConfig.mapChunkSize * globalConfig.tileSize,
|
chunkY * globalConfig.mapChunkWorldSize,
|
||||||
3,
|
3,
|
||||||
globalConfig.mapChunkSize * globalConfig.tileSize
|
globalConfig.mapChunkWorldSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,9 +162,6 @@ export class GameRoot {
|
|||||||
// Called right after game is initialized
|
// Called right after game is initialized
|
||||||
postLoadHook: /** @type {TypedSignal<[]>} */ (new Signal()),
|
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()),
|
shapeDelivered: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||||
itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()),
|
itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()),
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item
|
|||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class LeverSystem extends GameSystemWithFilter {
|
export class LeverSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -31,14 +32,11 @@ export class LeverSystem extends GameSystemWithFilter {
|
|||||||
* @param {MapChunkView} chunk
|
* @param {MapChunkView} chunk
|
||||||
*/
|
*/
|
||||||
drawChunk(parameters, chunk) {
|
drawChunk(parameters, chunk) {
|
||||||
const contents = chunk.contents;
|
const contents = chunk.containedEntitiesByLayer[enumLayer.regular];
|
||||||
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
for (let i = 0; i < contents.length; ++i) {
|
||||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
const entity = contents[i];
|
||||||
const entity = contents[x][y];
|
|
||||||
|
|
||||||
if (entity && entity.components.Lever) {
|
if (entity && entity.components.Lever) {
|
||||||
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
|
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
|
||||||
|
|
||||||
const origin = entity.components.StaticMapEntity.origin;
|
const origin = entity.components.StaticMapEntity.origin;
|
||||||
sprite.drawCached(
|
sprite.drawCached(
|
||||||
parameters,
|
parameters,
|
||||||
@ -51,4 +49,3 @@ export class LeverSystem extends GameSystemWithFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { GameSystem } from "../game_system";
|
|
||||||
import { DrawParameters } from "../../core/draw_parameters";
|
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
|
import { GameSystem } from "../game_system";
|
||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
|
import { THEME } from "../theme";
|
||||||
|
|
||||||
export class MapResourcesSystem extends GameSystem {
|
export class MapResourcesSystem extends GameSystem {
|
||||||
/**
|
/**
|
||||||
@ -10,8 +11,41 @@ export class MapResourcesSystem extends GameSystem {
|
|||||||
* @param {MapChunkView} chunk
|
* @param {MapChunkView} chunk
|
||||||
*/
|
*/
|
||||||
drawChunk(parameters, 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;
|
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;
|
const layer = chunk.lowerLayer;
|
||||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||||
const row = layer[x];
|
const row = layer[x];
|
||||||
@ -33,8 +67,8 @@ export class MapResourcesSystem extends GameSystem {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource();
|
// parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource();
|
||||||
parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize);
|
// parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize);
|
||||||
lowerItem.draw(
|
lowerItem.draw(
|
||||||
worldX + globalConfig.halfTileSize,
|
worldX + globalConfig.halfTileSize,
|
||||||
worldY + globalConfig.halfTileSize,
|
worldY + globalConfig.halfTileSize,
|
||||||
@ -43,6 +77,40 @@ export class MapResourcesSystem extends GameSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
parameters.context.globalAlpha = 1;
|
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];
|
||||||
|
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||||
|
const item = row[y];
|
||||||
|
if (item) {
|
||||||
|
context.fillStyle = item.getBackgroundColorAsResource();
|
||||||
|
context.fillRect(x, y, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,11 +153,6 @@ export class GameTime extends BasicSerializableObject {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we queued async tasks, perform them next frame and do not update anymore
|
|
||||||
if (this.root.hud.parts.processingOverlay.hasTasks()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const logger = createLogger("application_settings");
|
|||||||
export const enumCategories = {
|
export const enumCategories = {
|
||||||
general: "general",
|
general: "general",
|
||||||
userInterface: "userInterface",
|
userInterface: "userInterface",
|
||||||
|
performance: "performance",
|
||||||
advanced: "advanced",
|
advanced: "advanced",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,20 +148,6 @@ export const allApplicationSettings = [
|
|||||||
(app, id) => app.updateAfterUiScaleChanged(),
|
(app, id) => app.updateAfterUiScaleChanged(),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new BoolSetting(
|
|
||||||
"fullscreen",
|
|
||||||
enumCategories.general,
|
|
||||||
/**
|
|
||||||
* @param {Application} app
|
|
||||||
*/
|
|
||||||
(app, value) => {
|
|
||||||
if (app.platformWrapper.getSupportsFullscreen()) {
|
|
||||||
app.platformWrapper.setFullscreen(value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
!IS_DEMO
|
|
||||||
),
|
|
||||||
|
|
||||||
new BoolSetting(
|
new BoolSetting(
|
||||||
"soundsMuted",
|
"soundsMuted",
|
||||||
enumCategories.general,
|
enumCategories.general,
|
||||||
@ -178,6 +165,20 @@ export const allApplicationSettings = [
|
|||||||
(app, value) => app.sound.setMusicMuted(value)
|
(app, value) => app.sound.setMusicMuted(value)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
new BoolSetting(
|
||||||
|
"fullscreen",
|
||||||
|
enumCategories.general,
|
||||||
|
/**
|
||||||
|
* @param {Application} app
|
||||||
|
*/
|
||||||
|
(app, value) => {
|
||||||
|
if (app.platformWrapper.getSupportsFullscreen()) {
|
||||||
|
app.platformWrapper.setFullscreen(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
!IS_DEMO
|
||||||
|
),
|
||||||
|
|
||||||
new BoolSetting(
|
new BoolSetting(
|
||||||
"enableColorBlindHelper",
|
"enableColorBlindHelper",
|
||||||
enumCategories.general,
|
enumCategories.general,
|
||||||
@ -187,7 +188,6 @@ export const allApplicationSettings = [
|
|||||||
(app, value) => null
|
(app, value) => null
|
||||||
),
|
),
|
||||||
|
|
||||||
// GAME
|
|
||||||
new BoolSetting("offerHints", enumCategories.userInterface, (app, value) => {}),
|
new BoolSetting("offerHints", enumCategories.userInterface, (app, value) => {}),
|
||||||
|
|
||||||
new EnumSetting("theme", {
|
new EnumSetting("theme", {
|
||||||
@ -220,16 +220,6 @@ export const allApplicationSettings = [
|
|||||||
(app, id) => null,
|
(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", {
|
new EnumSetting("scrollWheelSensitivity", {
|
||||||
options: scrollWheelSensitivities.sort((a, b) => a.scale - b.scale),
|
options: scrollWheelSensitivities.sort((a, b) => a.scale - b.scale),
|
||||||
valueGetter: scale => scale.id,
|
valueGetter: scale => scale.id,
|
||||||
@ -258,6 +248,20 @@ export const allApplicationSettings = [
|
|||||||
new BoolSetting("compactBuildingInfo", enumCategories.userInterface, (app, value) => {}),
|
new BoolSetting("compactBuildingInfo", enumCategories.userInterface, (app, value) => {}),
|
||||||
new BoolSetting("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}),
|
new BoolSetting("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}),
|
||||||
new BoolSetting("rotationByBuilding", 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) {
|
export function getApplicationSettingById(id) {
|
||||||
@ -288,6 +292,10 @@ class SettingsStorage {
|
|||||||
|
|
||||||
this.enableColorBlindHelper = false;
|
this.enableColorBlindHelper = false;
|
||||||
|
|
||||||
|
this.lowQualityMapResources = false;
|
||||||
|
this.disableTileGrid = false;
|
||||||
|
this.lowQualityTextures = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object.<string, number>}
|
* @type {Object.<string, number>}
|
||||||
*/
|
*/
|
||||||
@ -487,7 +495,7 @@ export class ApplicationSettings extends ReadWriteProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCurrentVersion() {
|
getCurrentVersion() {
|
||||||
return 18;
|
return 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {{settings: SettingsStorage, version: number}} data */
|
/** @param {{settings: SettingsStorage, version: number}} data */
|
||||||
@ -565,6 +573,21 @@ export class ApplicationSettings extends ReadWriteProxy {
|
|||||||
data.version = 18;
|
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();
|
return ExplainedResult.good();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
if (this.stage === stages.s10_gameRunning) {
|
||||||
this.core.tick(dt);
|
this.core.tick(dt);
|
||||||
}
|
}
|
||||||
|
@ -670,6 +670,7 @@ settings:
|
|||||||
general: General
|
general: General
|
||||||
userInterface: User Interface
|
userInterface: User Interface
|
||||||
advanced: Advanced
|
advanced: Advanced
|
||||||
|
performance: Performance
|
||||||
|
|
||||||
versionBadges:
|
versionBadges:
|
||||||
dev: Development
|
dev: Development
|
||||||
@ -759,9 +760,9 @@ settings:
|
|||||||
light: Light
|
light: Light
|
||||||
|
|
||||||
refreshRate:
|
refreshRate:
|
||||||
title: Simulation Target
|
title: Tick Rate
|
||||||
description: >-
|
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:
|
alwaysMultiplace:
|
||||||
title: Multiplace
|
title: Multiplace
|
||||||
@ -798,6 +799,22 @@ settings:
|
|||||||
description: >-
|
description: >-
|
||||||
Disables the warning dialogs brought up when cutting/deleting more than 100 entities.
|
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:
|
keybindings:
|
||||||
title: Keybindings
|
title: Keybindings
|
||||||
hint: >-
|
hint: >-
|
||||||
|
Loading…
Reference in New Issue
Block a user