1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Squashed commit of the following:

commit ea2f32b3ff
Author: tobspr <tobias.springer1@googlemail.com>
Date:   Tue Feb 15 09:09:30 2022 +0100

    Fix examples

commit 561318b7db
Author: Dimava <dimava2@ya.ru>
Date:   Tue Feb 15 10:31:47 2022 +0300

    mark all abstract functions abstract (#1383)

commit 81d65e5801
Author: WaffleDevsAlt <81845843+WaffleDevsAlt@users.noreply.github.com>
Date:   Tue Feb 15 02:31:02 2022 -0500

    Removes unwanted ], (#1384)

    The ], breaks build, with a core error

commit 4f0af32a5e
Author: Ved_s <53968411+Ved-s@users.noreply.github.com>
Date:   Mon Feb 14 07:14:34 2022 +1100

    Update base-ru.yaml (#1312)

    * Update base-ru.yaml

    I think other's comments about the game should stay in English, as Russian translation cannot precisely describe this

    * Update base-ru.yaml

commit 3f3a2e0981
Author: Daan Breur <git@daanbreur.systems>
Date:   Sun Feb 13 21:11:52 2022 +0100

    NL Translations for Mods and puzzleDLC (#1381)

    * [NL] Mods and puzzleDLC

    * Update base-nl.yaml

    * Update base-nl.yaml

commit c4f26320a4
Author: dobidon <35607008+dobidon@users.noreply.github.com>
Date:   Sun Feb 13 23:11:38 2022 +0300

    Translating new keys (#1380)

commit cb5c3f798a
Author: Pimak <37274338+Pimak@users.noreply.github.com>
Date:   Sun Feb 13 21:11:16 2022 +0100

    Update base-fr.yaml for mods translation (#1377)

commit dee4f23b7e
Author: Sense101 <67970865+Sense101@users.noreply.github.com>
Date:   Sun Feb 13 20:11:02 2022 +0000

    Fix method for adding variants to an existing building (#1378)

commit b7bc2ac1b7
Author: jbelbaz <32191774+jbelbaz@users.noreply.github.com>
Date:   Sun Feb 13 21:10:11 2022 +0100

    Update base-fr.yaml (#1328)

    Change of a few lines in English. I was unable to verify in-game integration ... I hope my work will fit.
    glad to help :D

commit 93b9340ab7
Author: Pimak <37274338+Pimak@users.noreply.github.com>
Date:   Sun Feb 13 21:09:56 2022 +0100

    Update README.md (#1376)

    Small mistake

commit f534a88f80
Author: Bagel03 <70449196+Bagel03@users.noreply.github.com>
Date:   Sun Feb 13 15:09:41 2022 -0500

    Fix that whole export debacle (#1370)

    * Re-add setting exports

    * Update webpack.production.config.js

    * Update mod.js

    * Slight change

    * Update mod.js

    * Update webpack.production.config.js

    * Update webpack.config.js

commit dab4aa9cda
Author: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com>
Date:   Sun Feb 13 14:07:02 2022 -0600

    fix fs-job sanitization (#1375)

commit 4466821557
Author: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Date:   Sun Feb 13 21:06:42 2022 +0100

    Added display hook for getting the signelton and the drawing (#1374)

commit 65ae26cb53
Author: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Date:   Sun Feb 13 21:06:24 2022 +0100

    Added hook for storage can accept item (#1373)

    * Added hook for storage can accept item

    * Fixed order

commit e5742fd577
Author: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Date:   Sun Feb 13 21:06:10 2022 +0100

    Added constant signal resolver hook (#1372)

    * Added constant signal resolver hook

    * Added apply

commit 41c6b1c595
Author: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Date:   Sun Feb 13 21:05:58 2022 +0100

    Added mod processing requirements (#1371)

    * Added mod processing requirements

    * Added missing bind

    * Renamed to mods
This commit is contained in:
DJ1TJOO 2022-02-15 12:02:00 +01:00
parent f3cf68694c
commit 9cb3e0c398
31 changed files with 255 additions and 139 deletions

View File

@ -316,7 +316,7 @@ async function writeFileSafe(filename, contents) {
} }
ipcMain.handle("fs-job", async (event, job) => { ipcMain.handle("fs-job", async (event, job) => {
const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/i, "_"); const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/gi, "_");
const fname = path.join(storePath, filenameSafe); const fname = path.join(storePath, filenameSafe);
switch (job.type) { switch (job.type) {
case "read": { case "read": {

View File

@ -1,3 +1,39 @@
module.exports = function (source, map) { const oneExport = exp => {
return source + `\nexport let $s=(n,v)=>eval(n+"=v")`; return `${exp}=v`; // No checks needed
};
const twoExports = (exp1, exp2) => {
return `n=="${exp1}"?${exp1}=v:${exp2}=v`;
};
const multiExports = exps => {
exps = exps.map(exp => `case "${exp}":${exp}=v;break;`);
return `switch(n){${exps.toString().replaceAll(";,", ";")} }`;
};
const defineFnBody = source => {
const regex = /export (?:let|class) (?<name>\w+)/g;
let names = [...source.matchAll(regex)].map(n => n.groups.name);
switch (names.length) {
case 0:
return false;
case 1:
return oneExport(names[0]);
case 2:
return twoExports(names[0], names[1]);
default:
return multiExports(names);
}
};
/**
*
* @param {string} source
* @param {*} map
* @returns
*/
module.exports = function (source, map) {
const body = defineFnBody(source);
if (!body) return source;
return source + `\nexport const __$S__=(n,v)=>{${body}}`;
}; };

View File

@ -93,6 +93,9 @@ module.exports = ({ watch = false, standalone = false, chineseVersion = false, w
end: "typehints:end", end: "typehints:end",
}, },
}, },
{
loader: path.resolve(__dirname, "mod.js"),
},
], ],
}, },
{ {

View File

@ -131,6 +131,7 @@ module.exports = ({
warnings: true, warnings: true,
}, },
mangle: { mangle: {
reserved: ["__$S__"],
eval: true, eval: true,
keep_classnames: !minifyNames, keep_classnames: !minifyNames,
keep_fnames: !minifyNames, keep_fnames: !minifyNames,
@ -210,6 +211,9 @@ module.exports = ({
test: /\.js$/, test: /\.js$/,
use: [ use: [
// "thread-loader", // "thread-loader",
{
loader: path.resolve(__dirname, "mod.js"),
},
{ {
loader: "babel-loader?cacheDirectory", loader: "babel-loader?cacheDirectory",
options: { options: {

View File

@ -38,7 +38,7 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl
| [mod_settings.js](mod_settings.js) | Shows a dialog counting how often the mod has been launched | Reading and storing mod settings | | [mod_settings.js](mod_settings.js) | Shows a dialog counting how often the mod has been launched | Reading and storing mod settings |
| [storing_data_in_savegame.js](storing_data_in_savegame.js) | Shows how to store custom (structured) data in the savegame | Storing custom data in savegame | | [storing_data_in_savegame.js](storing_data_in_savegame.js) | Shows how to store custom (structured) data in the savegame | Storing custom data in savegame |
| [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods | | [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods |
| [modify_ui.js](modify_ui.js) | Shows how to add custom IU elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS | | [modify_ui.js](modify_ui.js) | Shows how to add custom UI elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS |
| [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events | | [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events |
| [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods | | [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods |

View File

@ -87,7 +87,7 @@ class FluidItem extends shapez.BaseItem {
* @param {number} diameter * @param {number} diameter
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
*/ */
drawItemCenteredClipped(x, y, parameters, diameter = globalConfig.defaultItemDiameter) { drawItemCenteredClipped(x, y, parameters, diameter = shapez.globalConfig.defaultItemDiameter) {
const realDiameter = diameter * 0.6; const realDiameter = diameter * 0.6;
if (!this.cachedSprite) { if (!this.cachedSprite) {
this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`); this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`);
@ -120,19 +120,19 @@ class Mod extends shapez.Mod {
this.modInterface.registerSprite("sprites/fluids/water.png", RESOURCES["water.png"]); this.modInterface.registerSprite("sprites/fluids/water.png", RESOURCES["water.png"]);
// Make the item spawn on the map // Make the item spawn on the map
this.modInterface.runAfterMethod( this.modInterface.runAfterMethod(shapez.MapChunk, "generatePatches", function ({
shapez.MapChunk, rng,
"generatePatches", chunkCenter,
function ({ rng, chunkCenter, distanceToOriginInChunks }) { distanceToOriginInChunks,
// Generate a simple patch }) {
// ALWAYS use rng and NEVER use Math.random() otherwise the map will look different // Generate a simple patch
// every time you resume the game // ALWAYS use rng and NEVER use Math.random() otherwise the map will look different
if (rng.next() > 0.8) { // every time you resume the game
const fluidType = rng.choice(Array.from(Object.keys(enumFluidType))); if (rng.next() > 0.8) {
this.internalGeneratePatch(rng, 4, FLUID_ITEM_SINGLETONS[fluidType]); const fluidType = rng.choice(Array.from(Object.keys(enumFluidType)));
} this.internalGeneratePatch(rng, 4, FLUID_ITEM_SINGLETONS[fluidType]);
} }
); });
this.modInterface.registerItem(FluidItem, itemData => FLUID_ITEM_SINGLETONS[itemData]); this.modInterface.registerItem(FluidItem, itemData => FLUID_ITEM_SINGLETONS[itemData]);
} }

View File

@ -211,6 +211,7 @@ export class GameState {
/** /**
* Should return the html code of the state. * Should return the html code of the state.
* @returns {string} * @returns {string}
* @abstract
*/ */
getInnerHTML() { getInnerHTML() {
abstract; abstract;

View File

@ -11,6 +11,7 @@ export class BaseSprite {
/** /**
* Returns the raw handle * Returns the raw handle
* @returns {HTMLImageElement|HTMLCanvasElement} * @returns {HTMLImageElement|HTMLCanvasElement}
* @abstract
*/ */
getRawTexture() { getRawTexture() {
abstract; abstract;

View File

@ -29,6 +29,7 @@ export class BaseItem extends BasicSerializableObject {
/** /**
* Returns a string id of the item * Returns a string id of the item
* @returns {string} * @returns {string}
* @abstract
*/ */
getAsCopyableKey() { getAsCopyableKey() {
abstract; abstract;
@ -49,9 +50,9 @@ export class BaseItem extends BasicSerializableObject {
/** /**
* Override for custom comparison * Override for custom comparison
* @abstract
* @param {BaseItem} other * @param {BaseItem} other
* @returns {boolean} * @returns {boolean}
* @abstract
*/ */
equalsImpl(other) { equalsImpl(other) {
abstract; abstract;
@ -62,6 +63,7 @@ export class BaseItem extends BasicSerializableObject {
* Draws the item to a canvas * Draws the item to a canvas
* @param {CanvasRenderingContext2D} context * @param {CanvasRenderingContext2D} context
* @param {number} size * @param {number} size
* @abstract
*/ */
drawFullSizeOnCanvas(context, size) { drawFullSizeOnCanvas(context, size) {
abstract; abstract;
@ -86,6 +88,7 @@ export class BaseItem extends BasicSerializableObject {
* @param {number} y * @param {number} y
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
* @param {number=} diameter * @param {number=} diameter
* @abstract
*/ */
drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) { drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
abstract; abstract;

View File

@ -4,6 +4,7 @@ export class Component extends BasicSerializableObject {
/** /**
* Returns the components unique id * Returns the components unique id
* @returns {string} * @returns {string}
* @abstract
*/ */
static getId() { static getId() {
abstract; abstract;

View File

@ -5,6 +5,10 @@ import { typeItemSingleton } from "../item_resolver";
import { ColorItem } from "../items/color_item"; import { ColorItem } from "../items/color_item";
import { ShapeItem } from "../items/shape_item"; import { ShapeItem } from "../items/shape_item";
/** @type {{
* [x: string]: (item: BaseItem) => Boolean
* }} */
export const MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER = {};
export class StorageComponent extends Component { export class StorageComponent extends Component {
static getId() { static getId() {
return "Storage"; return "Storage";
@ -56,11 +60,15 @@ export class StorageComponent extends Component {
const itemType = item.getItemType(); const itemType = item.getItemType();
// Check type matches
if (itemType !== this.storedItem.getItemType()) { if (itemType !== this.storedItem.getItemType()) {
// Check type matches
return false; return false;
} }
if (MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER[itemType]) {
return MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER[itemType].apply(this, [item]);
}
if (itemType === "color") { if (itemType === "color") {
return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color; return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color;
} }

View File

@ -224,6 +224,7 @@ export class Entity extends BasicSerializableObject {
/** /**
* override, should draw the entity * override, should draw the entity
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
* @abstract
*/ */
drawImpl(parameters) { drawImpl(parameters) {
abstract; abstract;

View File

@ -144,6 +144,7 @@ export class GameMode extends BasicSerializableObject {
/** /**
* @param {number} w * @param {number} w
* @param {number} h * @param {number} h
* @abstract
*/ */
adjustZone(w = 0, h = 0) { adjustZone(w = 0, h = 0) {
abstract; abstract;

View File

@ -25,6 +25,7 @@ export class BaseHUDPart {
/** /**
* Should initialize the element, called *after* the elements have been created * Should initialize the element, called *after* the elements have been created
* @abstract
*/ */
initialize() { initialize() {
abstract; abstract;

View File

@ -15,6 +15,11 @@ import trim from "trim";
import { enumColors } from "../../colors"; import { enumColors } from "../../colors";
import { ShapeDefinition } from "../../shape_definition"; import { ShapeDefinition } from "../../shape_definition";
/** @type {{
* [x: string]: (entity: Entity) => BaseItem
* }} */
export const MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER = {};
export class HUDConstantSignalEdit extends BaseHUDPart { export class HUDConstantSignalEdit extends BaseHUDPart {
initialize() { initialize() {
this.root.camera.downPreHandler.add(this.downPreHandler, this); this.root.camera.downPreHandler.add(this.downPreHandler, this);
@ -190,6 +195,10 @@ export class HUDConstantSignalEdit extends BaseHUDPart {
code = trim(code); code = trim(code);
const codeLower = code.toLowerCase(); const codeLower = code.toLowerCase();
if (MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER[codeLower]) {
return MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER[codeLower].apply(this, [entity]);
}
if (enumColors[codeLower]) { if (enumColors[codeLower]) {
return COLOR_ITEM_SINGLETONS[codeLower]; return COLOR_ITEM_SINGLETONS[codeLower];
} }

View File

@ -278,6 +278,7 @@ export class MetaBuilding {
* Should setup the entity components * Should setup the entity components
* @param {Entity} entity * @param {Entity} entity
* @param {GameRoot} root * @param {GameRoot} root
* @abstract
*/ */
setupEntityComponents(entity, root) { setupEntityComponents(entity, root) {
abstract; abstract;

View File

@ -7,6 +7,15 @@ import { isTrueItem } from "../items/boolean_item";
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item"; import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { MapChunkView } from "../map_chunk_view"; import { MapChunkView } from "../map_chunk_view";
/** @type {{
* [x: string]: (item: BaseItem) => BaseItem
* }} */
export const MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER = {};
/** @type {{
* [x: string]: (parameters: import("../../core/draw_parameters").DrawParameters, entity: import("../entity").Entity, item: BaseItem) => BaseItem
* }} */
export const MODS_ADDITIONAL_DISPLAY_ITEM_DRAW = {};
export class DisplaySystem extends GameSystem { export class DisplaySystem extends GameSystem {
constructor(root) { constructor(root) {
super(root); super(root);
@ -32,6 +41,10 @@ export class DisplaySystem extends GameSystem {
return null; return null;
} }
if (MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER[value.getItemType()]) {
return MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER[value.getItemType()].apply(this, [value]);
}
switch (value.getItemType()) { switch (value.getItemType()) {
case "boolean": { case "boolean": {
return isTrueItem(value) ? COLOR_ITEM_SINGLETONS[enumColors.white] : null; return isTrueItem(value) ? COLOR_ITEM_SINGLETONS[enumColors.white] : null;
@ -74,6 +87,14 @@ export class DisplaySystem extends GameSystem {
continue; continue;
} }
if (MODS_ADDITIONAL_DISPLAY_ITEM_DRAW[value.getItemType()]) {
return MODS_ADDITIONAL_DISPLAY_ITEM_DRAW[value.getItemType()].apply(this, [
parameters,
entity,
value,
]);
}
const origin = entity.components.StaticMapEntity.origin; const origin = entity.components.StaticMapEntity.origin;
if (value.getItemType() === "color") { if (value.getItemType() === "color") {
this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered(

View File

@ -594,8 +594,8 @@ export class ModInterface {
* @param {string=} payload.name * @param {string=} payload.name
* @param {string=} payload.description * @param {string=} payload.description
* @param {Vector=} payload.dimensions * @param {Vector=} payload.dimensions
* @param {(root: GameRoot) => [string, string][]} payload.additionalStatistics * @param {(root: GameRoot) => [string, string][]=} payload.additionalStatistics
* @param {(root: GameRoot) => boolean[]} payload.isUnlocked * @param {(root: GameRoot) => boolean[]=} payload.isUnlocked
*/ */
addVariantToExistingBuilding(metaClass, variant, payload) { addVariantToExistingBuilding(metaClass, variant, payload) {
if (!payload.rotationVariants) { if (!payload.rotationVariants) {
@ -671,9 +671,14 @@ export class ModInterface {
})); }));
} }
// Register our variant finally // Register our variant finally, with rotation variants
payload.rotationVariants.forEach(rotationVariant => payload.rotationVariants.forEach(rotationVariant =>
shapez.registerBuildingVariant(internalId, metaClass, variant, rotationVariant) shapez.registerBuildingVariant(
rotationVariant ? internalId + "-" + rotationVariant : internalId,
metaClass,
variant,
rotationVariant
)
); );
} }
} }

View File

@ -112,7 +112,8 @@ export class ModLoader {
// @ts-ignore // @ts-ignore
const module = modules(key); const module = modules(key);
for (const member in module) { for (const member in module) {
if (member === "default") { if (member === "default" || member === "__$S__") {
// Setter
continue; continue;
} }
if (exports[member]) { if (exports[member]) {
@ -124,7 +125,7 @@ export class ModLoader {
return module[member]; return module[member];
}, },
set(v) { set(v) {
throw new Error("Overriding the shapez exports is currently not possible"); module.__$S__(member, v);
}, },
}); });
} }

View File

@ -92,6 +92,7 @@ export class AchievementProviderInterface {
/** /**
* Initializes the achievement provider. * Initializes the achievement provider.
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
initialize() { initialize() {
abstract; abstract;
@ -102,6 +103,7 @@ export class AchievementProviderInterface {
* Opportunity to do additional initialization work with the GameRoot. * Opportunity to do additional initialization work with the GameRoot.
* @param {GameRoot} root * @param {GameRoot} root
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
onLoad(root) { onLoad(root) {
abstract; abstract;
@ -118,6 +120,7 @@ export class AchievementProviderInterface {
* Call to activate an achievement with the provider * Call to activate an achievement with the provider
* @param {string} key - Maps to an Achievement * @param {string} key - Maps to an Achievement
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
activate(key) { activate(key) {
abstract; abstract;
@ -127,6 +130,7 @@ export class AchievementProviderInterface {
/** /**
* Checks if achievements are supported in the current build * Checks if achievements are supported in the current build
* @returns {boolean} * @returns {boolean}
* @abstract
*/ */
hasAchievements() { hasAchievements() {
abstract; abstract;

View File

@ -19,6 +19,7 @@ export class AdProviderInterface {
/** /**
* Returns if this provider serves ads at all * Returns if this provider serves ads at all
* @returns {boolean} * @returns {boolean}
* @abstract
*/ */
getHasAds() { getHasAds() {
abstract; abstract;
@ -29,6 +30,7 @@ export class AdProviderInterface {
* Returns if it would be possible to show a video ad *now*. This can be false if for * Returns if it would be possible to show a video ad *now*. This can be false if for
* example the last video ad is * example the last video ad is
* @returns {boolean} * @returns {boolean}
* @abstract
*/ */
getCanShowVideoAd() { getCanShowVideoAd() {
abstract; abstract;

View File

@ -11,6 +11,7 @@ export class AnalyticsInterface {
/** /**
* Initializes the analytics * Initializes the analytics
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
initialize() { initialize() {
abstract; abstract;

View File

@ -11,6 +11,7 @@ export class GameAnalyticsInterface {
/** /**
* Initializes the analytics * Initializes the analytics
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
initialize() { initialize() {
abstract; abstract;
@ -43,6 +44,7 @@ export class GameAnalyticsInterface {
/** /**
* Activates a DLC * Activates a DLC
* @param {string} dlc * @param {string} dlc
* @abstract
*/ */
activateDlc(dlc) { activateDlc(dlc) {
abstract; abstract;

View File

@ -13,6 +13,7 @@ export class StorageInterface {
/** /**
* Initializes the storage * Initializes the storage
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
initialize() { initialize() {
abstract; abstract;
@ -24,6 +25,7 @@ export class StorageInterface {
* @param {string} filename * @param {string} filename
* @param {string} contents * @param {string} contents
* @returns {Promise<void>} * @returns {Promise<void>}
* @abstract
*/ */
writeFileAsync(filename, contents) { writeFileAsync(filename, contents) {
abstract; abstract;
@ -34,6 +36,7 @@ export class StorageInterface {
* Reads a string asynchronously. Returns Promise<FILE_NOT_FOUND> if file was not found. * Reads a string asynchronously. Returns Promise<FILE_NOT_FOUND> if file was not found.
* @param {string} filename * @param {string} filename
* @returns {Promise<string>} * @returns {Promise<string>}
* @abstract
*/ */
readFileAsync(filename) { readFileAsync(filename) {
abstract; abstract;

View File

@ -81,6 +81,7 @@ export class PlatformWrapperInterface {
* Attempt to open an external url * Attempt to open an external url
* @param {string} url * @param {string} url
* @param {boolean=} force Whether to always open the url even if not allowed * @param {boolean=} force Whether to always open the url even if not allowed
* @abstract
*/ */
openExternalLink(url, force = false) { openExternalLink(url, force = false) {
abstract; abstract;
@ -88,6 +89,7 @@ export class PlatformWrapperInterface {
/** /**
* Attempt to restart the app * Attempt to restart the app
* @abstract
*/ */
performRestart() { performRestart() {
abstract; abstract;
@ -103,6 +105,7 @@ export class PlatformWrapperInterface {
/** /**
* Should set the apps fullscreen state to the desired state * Should set the apps fullscreen state to the desired state
* @param {boolean} flag * @param {boolean} flag
* @abstract
*/ */
setFullscreen(flag) { setFullscreen(flag) {
abstract; abstract;
@ -117,6 +120,7 @@ export class PlatformWrapperInterface {
/** /**
* Attempts to quit the app * Attempts to quit the app
* @abstract
*/ */
exitApp() { exitApp() {
abstract; abstract;

View File

@ -64,6 +64,7 @@ export class BaseSetting {
/** /**
* Returns the HTML for this setting * Returns the HTML for this setting
* @param {Application} app * @param {Application} app
* @abstract
*/ */
getHtml(app) { getHtml(app) {
abstract; abstract;
@ -84,6 +85,7 @@ export class BaseSetting {
/** /**
* Attempts to modify the setting * Attempts to modify the setting
* @abstract
*/ */
modify() { modify() {
abstract; abstract;
@ -107,6 +109,7 @@ export class BaseSetting {
* Validates the set value * Validates the set value
* @param {any} value * @param {any} value
* @returns {boolean} * @returns {boolean}
* @abstract
*/ */
validate(value) { validate(value) {
abstract; abstract;

View File

@ -48,6 +48,7 @@ export class BaseDataType {
/** /**
* Serializes a given raw value * Serializes a given raw value
* @param {any} value * @param {any} value
* @abstract
*/ */
serialize(value) { serialize(value) {
abstract; abstract;
@ -68,6 +69,7 @@ export class BaseDataType {
* @param {object} targetObject * @param {object} targetObject
* @param {string|number} targetKey * @param {string|number} targetKey
* @returns {string|void} String error code or null on success * @returns {string|void} String error code or null on success
* @abstract
*/ */
deserialize(value, targetObject, targetKey, root) { deserialize(value, targetObject, targetKey, root) {
abstract; abstract;
@ -92,6 +94,7 @@ export class BaseDataType {
/** /**
* INTERNAL Should return the json schema representation * INTERNAL Should return the json schema representation
* @abstract
*/ */
getAsJsonSchemaUncached() { getAsJsonSchemaUncached() {
abstract; abstract;
@ -131,6 +134,7 @@ export class BaseDataType {
/** /**
* Should return a cacheable key * Should return a cacheable key
* @abstract
*/ */
getCacheKey() { getCacheKey() {
abstract; abstract;

View File

@ -454,8 +454,9 @@ ingame:
clearItems: Supprimer les objets clearItems: Supprimer les objets
share: Partager share: Partager
report: Signaler report: Signaler
clearBuildings: Effacer les batiments clearBuildings: Effacer les Constructions
resetPuzzle: Reset Puzzle resetPuzzle: Réinitialiser le Puzzle
puzzleEditorControls: puzzleEditorControls:
title: Créateur de Puzzles title: Créateur de Puzzles
instructions: instructions:
@ -475,6 +476,7 @@ ingame:
- 6. Une fois publié <strong>tous les batiments seront - 6. Une fois publié <strong>tous les batiments seront
supprimés</strong> sauf les générateurs et les récepteurs - C'est supprimés</strong> sauf les générateurs et les récepteurs - C'est
la partie ou le joueur est censé se débrouiller seul :) la partie ou le joueur est censé se débrouiller seul :)
puzzleCompletion: puzzleCompletion:
title: Puzzle Résolu ! title: Puzzle Résolu !
titleLike: "Cliquez sur le cœur si vous avez aimé le Puzzle:" titleLike: "Cliquez sur le cœur si vous avez aimé le Puzzle:"
@ -485,7 +487,7 @@ ingame:
nextPuzzle: Puzzle suivant nextPuzzle: Puzzle suivant
puzzleMetadata: puzzleMetadata:
author: Auteur author: Auteur
shortKey: Clée courte shortKey: Raccourci clavier
rating: Niveau de difficulté rating: Niveau de difficulté
averageDuration: Durée moyenne averageDuration: Durée moyenne
completionRate: Taux de réussite completionRate: Taux de réussite
@ -1073,7 +1075,7 @@ settings:
visible en dézoomant. visible en dézoomant.
shapeTooltipAlwaysOn: shapeTooltipAlwaysOn:
title: Info-bulle de forme - Toujours afficher title: Info-bulle de forme - Toujours afficher
description: Si activé une info-bule s'affiche quand vous survolez un batiment description: Si activé, une info-bule s'affiche quand vous survolez un batiment
sinon il faut maintenir 'ALT'. sinon il faut maintenir 'ALT'.
tickrateHz: <amount> Hz tickrateHz: <amount> Hz
newBadge: New! newBadge: New!
@ -1152,10 +1154,10 @@ keybindings:
placementDisableAutoOrientation: Désactiver lorientation automatique placementDisableAutoOrientation: Désactiver lorientation automatique
placeMultiple: Rester en mode placement placeMultiple: Rester en mode placement
placeInverse: Inverser lorientation des convoyeurs placeInverse: Inverser lorientation des convoyeurs
rotateToUp: "Rotate: Point Up" rotateToUp: "Rotation : pointer vers le haut"
rotateToDown: "Rotate: Point Down" rotateToDown: "Rotation : pointer vers le bas"
rotateToRight: "Rotate: Point Right" rotateToRight: "Rotation : pointer vers le droite"
rotateToLeft: "Rotate: Point Left" rotateToLeft: "Rotation : pointer vers le gauche"
constant_producer: Producteur Constant constant_producer: Producteur Constant
goal_acceptor: Récepteur goal_acceptor: Récepteur
block: Bloc block: Bloc
@ -1311,16 +1313,16 @@ puzzleMenu:
un clic droit sur shapez.io dans votre bibliothèque, en sélectionnant un clic droit sur shapez.io dans votre bibliothèque, en sélectionnant
Propriétés > DLC. Propriétés > DLC.
search: search:
action: Chercher action: Recherche
placeholder: Entrez un puzzle ou un nom d'auteur placeholder: Entrez un puzzle ou un nom d'auteur
includeCompleted: Inclure les puzzles terminés includeCompleted: Inclure terminé
difficulties: difficulties:
any: Toutes difficultés any: Toute difficulté
easy: Facile easy: Facile
medium: Moyen medium: Medium
hard: Difficile hard: Dificile
durations: durations:
any: Toutes durées any: Toute durée
short: Court (< 2 min) short: Court (< 2 min)
medium: Normal medium: Normal
long: Long (> 10 min) long: Long (> 10 min)
@ -1353,18 +1355,17 @@ backendErrors:
no-permission: Vous n'êtes pas autorisé à effectuer cette action. no-permission: Vous n'êtes pas autorisé à effectuer cette action.
mods: mods:
title: Mods title: Mods
author: Author author: Auteur
version: Version version: Version
modWebsite: Website modWebsite: Page web
openFolder: Open Mods Folder openFolder: Ouvrir le dossier des mods
folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. folderOnlyStandalone: Ouvrir le dossier des mods est uniquement possible avec la version complète
browseMods: Browse Mods browseMods: Chercher les Mods
modsInfo: To install and manage mods, copy them to the mods folder within the modsInfo: Pour installer et gérer les mods, copier-les dans le dossier Mods dans le répertoire du jeu.
game directory. You can also use the 'Open Mods Folder' button on the Vous pouvez aussi utiliser le bouton 'Ouvrir le dossier des Mods' en haut à droite
top right. noModSupport: Vous avez besoin de la version complète sur Steam pour installer des mods.
noModSupport: You need the standalone version on Steam to install mods.
togglingComingSoon: togglingComingSoon:
title: Coming Soon title: Bientôt disponible
description: Enabling or disabling mods is currently only possible by copying description: Activer ou désactiver un mod est pour le moment possible qu'en
the mod file from or to the mods/ folder. However, being able to copiant le fichier du mod depuis ou vers le dossier des mods. Cependant,
toggle them here is planned for a future update! activer ou désactiver un mod est prévu pour une mise à jour future !

View File

@ -81,9 +81,9 @@ mainMenu:
puzzleDlcWishlist: Voeg nu toe aan je verlanglijst! puzzleDlcWishlist: Voeg nu toe aan je verlanglijst!
puzzleDlcViewNow: Bekijk DLC puzzleDlcViewNow: Bekijk DLC
mods: mods:
title: Active Mods title: Actieve Mods
warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please warningPuzzleDLC: Het spelen van de Puzzle DLC is niet mogelijk met mods. Schakel
disable all mods to play the DLC. alsjeblieft alle mods uit om de DLC te spelen.
dialogs: dialogs:
buttons: buttons:
ok: OK ok: OK
@ -270,12 +270,12 @@ dialogs:
desc: Weet je zeker dat je '<title>' wilt verwijderen? Dit kan niet ongedaan desc: Weet je zeker dat je '<title>' wilt verwijderen? Dit kan niet ongedaan
gemaakt worden! gemaakt worden!
modsDifference: modsDifference:
title: Mod Warning title: Mod Waarschuwing
desc: The currently installed mods differ from the mods the savegame was created desc: The currently installed mods differ from the mods the savegame was created
with. This might cause the savegame to break or not load at all. Are with. This might cause the savegame to break or not load at all. Are
you sure you want to continue? you sure you want to continue?
missingMods: Missing Mods missingMods: Missende Mods
newMods: Newly installed Mods newMods: Nieuw geïnstalleerde Mods
ingame: ingame:
keybindingsOverlay: keybindingsOverlay:
moveMap: Beweeg rond de wereld moveMap: Beweeg rond de wereld
@ -1188,10 +1188,8 @@ tips:
- Knippers knippen altijd verticaal, ongeacht hun oriëntatie. - Knippers knippen altijd verticaal, ongeacht hun oriëntatie.
- De opslagbuffer geeft prioriteit aan de eerste uitvoer. - De opslagbuffer geeft prioriteit aan de eerste uitvoer.
- Investeer tijd om herhaalbare ontwerpen te maken - het is het waard! - Investeer tijd om herhaalbare ontwerpen te maken - het is het waard!
- Invest time to build repeatable designs - it's worth it!
- Je kunt <b>ALT</b> ingedrukt houden om de richting van de geplaatste - Je kunt <b>ALT</b> ingedrukt houden om de richting van de geplaatste
lopende banden om te keren. lopende banden om te keren.
- You can hold <b>ALT</b> to invert the direction of placed belts.
- Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer. - Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer.
- Machines hebben een beperkte snelheid, verdeel ze voor maximale - Machines hebben een beperkte snelheid, verdeel ze voor maximale
efficiëntie. efficiëntie.
@ -1214,7 +1212,6 @@ tips:
mannen. mannen.
- Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules. - Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules.
- Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord. - Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord.
- Have a closer look at the color mixer, and your questions will be answered.
- Use <b>CTRL</b> + Click to select an area. - Use <b>CTRL</b> + Click to select an area.
- Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op - Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op
het scherm. het scherm.
@ -1234,7 +1231,6 @@ tips:
- Druk twee keer op F4 om de tegel van je muis en camera weer te geven. - Druk twee keer op F4 om de tegel van je muis en camera weer te geven.
- Je kan aan de linkerkant op een vastgezette vorm klikken om deze los te - Je kan aan de linkerkant op een vastgezette vorm klikken om deze los te
maken. maken.
- You can click a pinned shape on the left side to unpin it.
puzzleMenu: puzzleMenu:
play: Spelen play: Spelen
edit: Bewerken edit: Bewerken
@ -1280,21 +1276,21 @@ puzzleMenu:
easy: Makkelijk easy: Makkelijk
medium: Medium medium: Medium
hard: Moeilijk hard: Moeilijk
unknown: Unrated unknown: Onbeoordeeld
search: search:
action: Search action: Zoeken
placeholder: Enter a puzzle or author name placeholder: Voer een puzzel- of auteursnaam in
includeCompleted: Include Completed includeCompleted: Inclusief Voltooide
difficulties: difficulties:
any: Any Difficulty any: Elke Moeilijkheidsgraad
easy: Easy easy: Makkelijk
medium: Medium medium: Medium
hard: Hard hard: Moeilijk
durations: durations:
any: Any Duration any: Elke Tijd
short: Short (< 2 min) short: Kort (< 2 min)
medium: Normal medium: Normaal
long: Long (> 10 min) long: Lang (> 10 min)
backendErrors: backendErrors:
ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even. ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even.
invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het
@ -1323,18 +1319,17 @@ backendErrors:
no-permission: Je bent niet gemachtigd om deze actie uit te voeren. no-permission: Je bent niet gemachtigd om deze actie uit te voeren.
mods: mods:
title: Mods title: Mods
author: Author author: Auteur
version: Version version: Versie
modWebsite: Website modWebsite: Website
openFolder: Open Mods Folder openFolder: Open Mods Map
folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. folderOnlyStandalone: Het openen van de mod map is alleen mogelijk bij het gebruiken van de zelfstandige versie.
browseMods: Browse Mods browseMods: Door mods bladeren
modsInfo: To install and manage mods, copy them to the mods folder within the modsInfo: Om mods te installeren en te beheren, kopieert u ze naar de map mods in de
game directory. You can also use the 'Open Mods Folder' button on the spel map. U kunt ook de knop 'Open Mods Map' gebruiken rechtsboven.
top right. noModSupport: Je hebt de zelfstandige versie op Steam nodig om mods te installeren.
noModSupport: You need the standalone version on Steam to install mods.
togglingComingSoon: togglingComingSoon:
title: Coming Soon title: Binnenkort Beschikbaar
description: Enabling or disabling mods is currently only possible by copying description: Mods in- of uitschakelen is momenteel alleen mogelijk door
the mod file from or to the mods/ folder. However, being able to het mod-bestand van of naar de mods map te kopiëren. Echter, in staat zijn om
toggle them here is planned for a future update! ze hier in- of uitteschakelen is gepland voor een toekomstige update!

View File

@ -95,9 +95,9 @@ dialogs:
viewUpdate: Посмотреть Обновление viewUpdate: Посмотреть Обновление
showUpgrades: Показать Улучшения showUpgrades: Показать Улучшения
showKeybindings: Показать Управление (Привязку клавиш) showKeybindings: Показать Управление (Привязку клавиш)
retry: Retry retry: Заново
continue: Continue continue: Подолжить
playOffline: Play Offline playOffline: Играть оффлайн
importSavegameError: importSavegameError:
title: Ошибка импортирования title: Ошибка импортирования
text: Не удалось импортировать сохранение игры. text: Не удалось импортировать сохранение игры.
@ -245,7 +245,7 @@ dialogs:
puzzleShare: puzzleShare:
title: Короткий ключ скопирован title: Короткий ключ скопирован
desc: Короткий ключ головоломки (<key>) был скопирован в буфер обмена! Он может desc: Короткий ключ головоломки (<key>) был скопирован в буфер обмена! Он может
быть введен в меню головолом для доступа к головоломке. быть введен в меню головоломок для доступа к головоломке.
puzzleReport: puzzleReport:
title: Жалоба на головоломку title: Жалоба на головоломку
options: options:
@ -292,7 +292,7 @@ ingame:
clearSelection: Отменить clearSelection: Отменить
pipette: Пипетка pipette: Пипетка
switchLayers: Переключить слои switchLayers: Переключить слои
clearBelts: Clear belts clearBelts: Очистить конвейеры
colors: colors:
red: Красный red: Красный
green: Зеленый green: Зеленый
@ -451,8 +451,8 @@ ingame:
clearItems: Очистить предметы clearItems: Очистить предметы
share: Поделиться share: Поделиться
report: Пожаловаться report: Пожаловаться
clearBuildings: Clear Buildings clearBuildings: Очистить постройки
resetPuzzle: Reset Puzzle resetPuzzle: Сброс головоломки
puzzleEditorControls: puzzleEditorControls:
title: Редактор головоломок title: Редактор головоломок
instructions: instructions:
@ -479,7 +479,7 @@ ingame:
titleRatingDesc: Ваша оценка поможет мне в будущем делать вам лучшие предложения titleRatingDesc: Ваша оценка поможет мне в будущем делать вам лучшие предложения
continueBtn: Продолжить игру continueBtn: Продолжить игру
menuBtn: Меню menuBtn: Меню
nextPuzzle: Next Puzzle nextPuzzle: Следующая головоломка
puzzleMetadata: puzzleMetadata:
author: Автор author: Автор
shortKey: Короткий ключ shortKey: Короткий ключ
@ -709,8 +709,8 @@ buildings:
description: Доставьте фигуру в приемник, чтобы установить их в качестве цели. description: Доставьте фигуру в приемник, чтобы установить их в качестве цели.
block: block:
default: default:
name: Block name: Блок
description: Allows you to block a tile. description: Блокирует это место от установки чего-либо
storyRewards: storyRewards:
reward_cutter_and_trash: reward_cutter_and_trash:
title: Разрезание Фигур title: Разрезание Фигур
@ -1044,11 +1044,11 @@ settings:
title: Размер ресурсов на карте title: Размер ресурсов на карте
description: Устанавливает размер фигур на карте (когда вид достаточно отдалён). description: Устанавливает размер фигур на карте (когда вид достаточно отдалён).
shapeTooltipAlwaysOn: shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings, title: Показывать подсказку фигуры
instead of having to hold 'ALT'. description: Показывать ли подсказку фигуры всегда или только при удержании 'ALT'.
tickrateHz: <amount> Hz tickrateHz: <amount> Гц
newBadge: New! newBadge: Новое!
keybindings: keybindings:
title: Настройки управления title: Настройки управления
hint: "Подсказка: Обязательно используйте CTRL, SHIFT и ALT! Они дают разные hint: "Подсказка: Обязательно используйте CTRL, SHIFT и ALT! Они дают разные
@ -1131,7 +1131,7 @@ keybindings:
goal_acceptor: Приёмник предметов goal_acceptor: Приёмник предметов
block: Блок block: Блок
massSelectClear: Очистить конвейеры massSelectClear: Очистить конвейеры
showShapeTooltip: Show shape output tooltip showShapeTooltip: Показывать подсказку фигуры на выходе
about: about:
title: Об игре title: Об игре
body: >- body: >-
@ -1272,19 +1272,19 @@ puzzleMenu:
dlcHint: Уже купили DLC? Проверьте, что оно активировано, нажав правый клик на dlcHint: Уже купили DLC? Проверьте, что оно активировано, нажав правый клик на
shapez.io в своей библиотеке, и далее Свойства > Доп. Контент shapez.io в своей библиотеке, и далее Свойства > Доп. Контент
search: search:
action: Search action: Поиск
placeholder: Enter a puzzle or author name placeholder: Введите название головоломки или имя автора
includeCompleted: Include Completed includeCompleted: Показывать завершённые
difficulties: difficulties:
any: Any Difficulty any: Любая сложность
easy: Easy easy: Легко
medium: Medium medium: Средне
hard: Hard hard: Сложно
durations: durations:
any: Any Duration any: Любая длительность
short: Short (< 2 min) short: Короткие (< 2 мин.)
medium: Normal medium: Средние
long: Long (> 10 min) long: Долгие (> 10 мин.)
backendErrors: backendErrors:
ratelimit: Вы слишком часто выполняете свои действия. Подождите немного. ratelimit: Вы слишком часто выполняете свои действия. Подождите немного.
invalid-api-key: Не удалось связаться с сервером, попробуйте invalid-api-key: Не удалось связаться с сервером, попробуйте

View File

@ -79,9 +79,9 @@ mainMenu:
puzzleDlcWishlist: İstek listene ekle! puzzleDlcWishlist: İstek listene ekle!
puzzleDlcViewNow: Paketi (DLC) görüntüle puzzleDlcViewNow: Paketi (DLC) görüntüle
mods: mods:
title: Active Mods title: Aktif Modlar
warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please warningPuzzleDLC: Modlarla Yapboz DLC'sini oynamak mümkün değil. Lütfen
disable all mods to play the DLC. Yapboz DLC'sini oynayabilmek için bütün modları devre dışı bırakınız.
dialogs: dialogs:
buttons: buttons:
ok: OK ok: OK
@ -263,12 +263,12 @@ dialogs:
desc: "'<title>' yapbozunu silmek istediğinize emin misiniz? Bu işlem geri desc: "'<title>' yapbozunu silmek istediğinize emin misiniz? Bu işlem geri
alınamaz!" alınamaz!"
modsDifference: modsDifference:
title: Mod Warning title: Mod Uyarısı
desc: The currently installed mods differ from the mods the savegame was created desc: Halihazırda kullanılan modlar, kayıtlı oyunun yaratıldığı modlardan farklıdır.
with. This might cause the savegame to break or not load at all. Are Bu işlem kayıtlı oyunun bozulmasına veya hiç yüklenmemesine neden olabilir. Devam
you sure you want to continue? etmek istediğinize emin misiniz?
missingMods: Missing Mods missingMods: Eksik Modlar
newMods: Newly installed Mods newMods: Yeni yüklenen Modlar
ingame: ingame:
keybindingsOverlay: keybindingsOverlay:
moveMap: Hareket Et moveMap: Hareket Et
@ -1038,7 +1038,7 @@ settings:
description: Şekil ipuçlarını 'ALT' tuşuna basarak göstermek yerine her zaman description: Şekil ipuçlarını 'ALT' tuşuna basarak göstermek yerine her zaman
gösterir. gösterir.
tickrateHz: <amount> Hz tickrateHz: <amount> Hz
newBadge: New! newBadge: Yeni!
keybindings: keybindings:
title: Tuş Atamaları title: Tuş Atamaları
hint: "İpucu: CTRL, SHIFT ve ALT tuşlarından yararlanın! Farklı yerleştirme hint: "İpucu: CTRL, SHIFT ve ALT tuşlarından yararlanın! Farklı yerleştirme
@ -1052,7 +1052,7 @@ keybindings:
massSelect: Çoklu Seçİm massSelect: Çoklu Seçİm
buildings: Yapı Kısayolları buildings: Yapı Kısayolları
placementModifiers: Yerleştİrme Özellİklerİ placementModifiers: Yerleştİrme Özellİklerİ
mods: Provided by Mods mods: Modlar tarafından sağlandı
mappings: mappings:
confirm: Kabul confirm: Kabul
back: Geri back: Geri
@ -1307,19 +1307,19 @@ backendErrors:
istiyorsanız support@shapez.io ile iletişime geçiniz! istiyorsanız support@shapez.io ile iletişime geçiniz!
no-permission: Bu işlemi yapmak için izniniz yok. no-permission: Bu işlemi yapmak için izniniz yok.
mods: mods:
title: Mods title: Modlar
author: Author author: Sahibi
version: Version version: Sürüm
modWebsite: Website modWebsite: İnternet sitesi
openFolder: Open Mods Folder openFolder: Mod Klasörünü Aç
folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. folderOnlyStandalone: Mod klasörünü açmak sadece tam sürümü çalıştırıyorken mümkün.
browseMods: Browse Mods browseMods: Modlara Gözat
modsInfo: To install and manage mods, copy them to the mods folder within the modsInfo: Modları yüklemek ve yönetmek için, bunları oyun dizini içerisindeki Modlar
game directory. You can also use the 'Open Mods Folder' button on the klasörüne kopyalayın. Ayrıca sağ üstteki 'Modlar Klasörünü Aç' düğmesini de
top right. kullanabilirsiniz.
noModSupport: You need the standalone version on Steam to install mods. noModSupport: Mod yükleyebilmek için tam sürümü çalıştırmalısınız.
togglingComingSoon: togglingComingSoon:
title: Coming Soon title: Yakında Gelecek
description: Enabling or disabling mods is currently only possible by copying description: Modları etkinleştirmek veya devre dışı bırakmak şu anda yalnızca
the mod file from or to the mods/ folder. However, being able to dosyaları Mod klasörüne kopyalayarak mümkündür. Ancak modları burada
toggle them here is planned for a future update! değiştirmek gelecekteki bir güncelleme için planlanmıştır!