diff --git a/.eslintrc.json b/.eslintrc.json
index e4a913e..1ab1085 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -2,104 +2,13 @@
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
- "plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {"project": "tsconfig.json"},
"plugins": ["@typescript-eslint"],
"rules": {
- "max-len": ["warn", {
- "ignoreStrings": true,
- "ignoreTemplateLiterals": true,
- "ignoreRegExpLiterals": true}],
"@typescript-eslint/triple-slash-reference": "off",
- "@typescript-eslint/no-unused-vars": "off",
- "@typescript-eslint/no-inferrable-types": "warn",
- "@typescript-eslint/array-type": ["warn", {"default": "array-simple"}],
- "@typescript-eslint/consistent-indexed-object-style": ["warn", "index-signature"],
- "@typescript-eslint/consistent-type-assertions": ["warn", {
- "assertionStyle": "angle-bracket",
- "objectLiteralTypeAssertions": "never"}],
- "@typescript-eslint/explicit-function-return-type": "warn",
- "@typescript-eslint/explicit-member-accessibility": ["error", {
- "accessibility": "explicit",
- "overrides": {"constructors": "no-public"}}],
- "@typescript-eslint/member-delimiter-style": ["warn", {
- "multiline": {"delimiter": "semi", "requireLast": true},
- "singleline": {"delimiter": "comma", "requireLast": false}}],
- "@typescript-eslint/member-ordering": "warn",
- "@typescript-eslint/method-signature-style": ["warn", "property"],
- "@typescript-eslint/naming-convention": "warn",
- "@typescript-eslint/no-base-to-string": "error",
- "@typescript-eslint/no-confusing-non-null-assertion": "error",
- "@typescript-eslint/no-confusing-void-expression": "error",
- "@typescript-eslint/no-extraneous-class": "error",
- "@typescript-eslint/no-implicit-any-catch": "error",
- "@typescript-eslint/no-invalid-void-type": "error",
- "@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn",
- "@typescript-eslint/no-unnecessary-condition": "warn",
- "@typescript-eslint/no-unnecessary-qualifier": "warn",
- "@typescript-eslint/no-unnecessary-type-arguments": "warn",
- "@typescript-eslint/no-unnecessary-type-constraint": "warn",
- "@typescript-eslint/no-unsafe-argument": "error",
- "@typescript-eslint/non-nullable-type-assertion-style": "warn",
- "@typescript-eslint/prefer-enum-initializers": "warn",
- "@typescript-eslint/prefer-function-type": "warn",
- "@typescript-eslint/prefer-includes": "warn",
- "@typescript-eslint/prefer-literal-enum-member": "error",
- "@typescript-eslint/prefer-nullish-coalescing": "warn",
- "@typescript-eslint/prefer-optional-chain": "warn",
- "@typescript-eslint/prefer-readonly": "warn",
- "@typescript-eslint/prefer-reduce-type-parameter": "warn",
- "@typescript-eslint/prefer-return-this-type": "warn",
- "@typescript-eslint/prefer-string-starts-ends-with": "warn",
- "@typescript-eslint/prefer-ts-expect-error": "error",
- "@typescript-eslint/promise-function-async": "warn",
- "@typescript-eslint/require-array-sort-compare": "warn",
- "@typescript-eslint/strict-boolean-expressions": ["error", {
- "allowString": false,
- "allowNumber": false,
- "allowNullableObject": false}],
- "@typescript-eslint/switch-exhaustiveness-check": "warn",
- "@typescript-eslint/type-annotation-spacing": "warn",
- "@typescript-eslint/unified-signatures": "warn",
- "@typescript-eslint/brace-style": "warn",
- "@typescript-eslint/comma-dangle": ["warn", "always-multiline"],
- "@typescript-eslint/comma-spacing": "warn",
- "@typescript-eslint/default-param-last": "error",
- "@typescript-eslint/dot-notation": "error",
- "@typescript-eslint/func-call-spacing": ["warn", "never"],
- "@typescript-eslint/indent": ["warn", 2, {
- "SwitchCase": 1,
- "VariableDeclarator": 1,
- "outerIIFEBody": 1,
- "FunctionDeclaration": {"parameters": 1, "body": 1},
- "CallExpression": {"arguments": 1},
- "ArrayExpression": 1,
- "ObjectExpression": 1,
- "MemberExpression": 2,
- "flatTernaryExpressions": false,
- "ignoreComments": false}],
- "@typescript-eslint/keyword-spacing": "error",
- "@typescript-eslint/lines-between-class-members": ["warn", "always", {
- "exceptAfterSingleLine": true}],
- "@typescript-eslint/no-dupe-class-members": "error",
- "@typescript-eslint/no-extra-parens": "warn",
- "@typescript-eslint/no-invalid-this": "error",
- "@typescript-eslint/no-loop-func": "error",
- "@typescript-eslint/no-loss-of-precision": "warn",
- "@typescript-eslint/no-redeclare": "error",
- "@typescript-eslint/no-shadow": "error",
- "@typescript-eslint/no-unused-expressions": "error",
- "@typescript-eslint/no-use-before-define": "error",
- "@typescript-eslint/no-useless-constructor": "warn",
- "@typescript-eslint/object-curly-spacing": ["warn", "always", {
- "arraysInObjects": true,
- "objectsInObjects": false}],
- "@typescript-eslint/quotes": ["warn", "single", {"avoidEscape": true}],
- "@typescript-eslint/semi": ["error", "always"],
- "@typescript-eslint/space-before-function-paren": ["warn", "always"],
- "@typescript-eslint/space-infix-ops": "warn"
+ "@typescript-eslint/no-unused-vars": "off"
}
}
diff --git a/src/main.ts b/src/main.ts
index 235c122..c4129ef 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,6 +1,9 @@
///
///
+const versionMajor = 2;
+const versionMinor = 0;
+
let globalStartTime = 0;
let globalTimeout: number | null = null;
const cycleLength = 250;
@@ -27,7 +30,7 @@ function startGame (state: GameState, renderer: IRenderer): void {
function initialRender (state: GameState): void {
if (state.logger === null) return;
- state.logger.unsafeMsg(`Welcome to irreligio.us!
+ state.logger.unsafeMsg(`Welcome to irreligio.us! alpha v${versionMajor}.${versionMinor}
The game is still in an active state of development and nowhere near its final form. This is a debugging interface that can show all resources even before they're unlocked, and many factors may be sped up significantly to aid in development. There is a chance that playing it now may spoil aspects of the game for you later when it's closer to being finished.
@@ -38,7 +41,7 @@ The game's source code on Github
// run with default config at startup
((): void => {
- const config = new GameConfig();
+ const config = new GameConfig(versionMajor, versionMinor);
// debug values to make the game play faster while testing
config.cfgTitheAmount = 1000;
diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts
index 5c7a93c..c844061 100644
--- a/src/model/GameConfig.ts
+++ b/src/model/GameConfig.ts
@@ -79,6 +79,11 @@ class GameConfig {
public cfgTitheAmount = 10;
public cfgTitheCredibilityHitFactor = 3;
+ constructor (
+ public versionMajor: number,
+ public versionMinor: number,
+ ) {}
+
public generateState (): GameState {
const state = new GameState(this);
diff --git a/src/model/GameState.ts b/src/model/GameState.ts
index 933c1c5..0d37912 100644
--- a/src/model/GameState.ts
+++ b/src/model/GameState.ts
@@ -8,9 +8,6 @@ class GameState {
public now = 0;
- private readonly _versionMaj = 0;
- private readonly _versionMin = 1;
-
private _timeSinceSave = 0;
private readonly _timeBetweenSaves = 10000;
@@ -116,19 +113,25 @@ class GameState {
}
public save (): void {
- const saveObj: SaveData = {};
- saveObj.version = {
- maj: this._versionMaj,
- min: this._versionMin,
+ const saveObj: SaveData = {
+ version: {
+ maj: this.config.versionMajor,
+ min: this.config.versionMinor,
+ },
+ resources: {},
};
for (const key in this._resources) {
const rkey = key;
const resource = this._resources[rkey];
if (resource === undefined) continue;
- saveObj[rkey] = {
+ const resSav: ResourceConfig = {
value: resource.value,
cost: resource.cost,
};
+ if (resource.emitConfig !== undefined) {
+ resSav.config = resource.emitConfig();
+ }
+ saveObj.resources[rkey] = resSav;
}
const saveStr: string = btoa(JSON.stringify(saveObj));
localStorage.setItem('savegame', saveStr);
@@ -139,18 +142,21 @@ class GameState {
if (saveStr !== null) {
try {
const saveObj: SaveData = JSON.parse(atob(saveStr));
- if (this._versionMaj === saveObj.version?.maj) {
+ if (this.config.versionMajor === saveObj.version.maj) {
for (const key in this._resources) {
const rkey = key;
- const saveRes = <{
- value: number;
- cost?: { [key: string]: number };
- } | undefined> saveObj[key];
+ const resource = this._resources[rkey];
+ if (resource === undefined) continue;
+ const saveRes = saveObj.resources[rkey];
if (saveRes !== undefined) {
// @ts-expect-error writing read-only value from save data
- this._resources[rkey].value = saveRes.value;
+ resource.value = saveRes.value;
// @ts-expect-error writing read-only cost from save data
- this._resources[rkey].cost = saveRes.cost;
+ resource.cost = saveRes.cost;
+ if (saveRes.config !== undefined
+ && resource.restoreConfig !== undefined) {
+ resource.restoreConfig(saveRes.config);
+ }
}
}
} else {
@@ -173,11 +179,3 @@ class GameState {
this.log('Reset all game resources.');
}
}
-
-type SaveData = {
- [key: string]: {
- value: number;
- cost?: { [key: string]: number };
- } | { maj: number, min: number } | undefined;
- version?: { maj: number, min: number };
-};
diff --git a/src/model/resource/IResource.ts b/src/model/resource/IResource.ts
index 7e1175d..0f02949 100644
--- a/src/model/resource/IResource.ts
+++ b/src/model/resource/IResource.ts
@@ -18,4 +18,8 @@ interface IResource {
addValue: (amount: number, state: GameState) => void;
isUnlocked: (state: GameState) => boolean;
+
+ emitConfig?: () => { [key: string]: string | number | boolean };
+ restoreConfig?: (
+ config: { [key: string]: string | number | boolean }) => void;
}
diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts
index e0f5864..674ff26 100644
--- a/src/model/resource/Money.ts
+++ b/src/model/resource/Money.ts
@@ -13,7 +13,7 @@ class Money implements IResource {
name: 'Collect Tithes',
description: 'Voluntary contributions from followers.',
isEnabled: (state: GameState): boolean =>
- this.value <= this.max(state)
+ this.value < this.max(state)
&& (state.resource.followers?.value ?? 0) >= 1,
performAction: (state: GameState): void => {
this._collectTithes(state);
diff --git a/src/model/resource/SharedTypes.ts b/src/model/resource/SharedTypes.ts
index 4228493..01e73db 100644
--- a/src/model/resource/SharedTypes.ts
+++ b/src/model/resource/SharedTypes.ts
@@ -39,3 +39,14 @@ type ResourceAction = {
isEnabled: (state: GameState) => boolean;
performAction: (state: GameState) => void;
};
+
+type ResourceConfig = {
+ value: number;
+ cost?: ResourceNumber;
+ config?: { [key: string]: string | number | boolean };
+};
+
+type SaveData = {
+ version: { maj: number, min: number };
+ resources: { [key in ResourceKey]?: ResourceConfig };
+};