diff --git a/.gitignore b/.gitignore
index fd39b89..e5a6635 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
public/js/irreligious.js
node_modules/*
+.env
diff --git a/README.md b/README.md
index c4e9fff..24a413e 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,15 @@ An incremental game in which you start a cult and must grow it into the dominant
## Current State
-It can be run and played through a not-very-pretty debugging interface. To make testing easier, default configuration is massively sped up from what the final game will use, and the relationships between resources have not been play-tested or balanced in any meaningful way.
+Playable, but lightyears from complete and not very pretty or fun yet.
-## Build and Run
+## Play Online
+
+[https://irreligio.us/](https://irreligio.us)
+
+The online version may be behind what's in the repository.
+
+## Build and Run Locally
```
npm install
diff --git a/package.json b/package.json
index 831f42e..aad4b7a 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,8 @@
{
"scripts": {
- "build": "eslint src/ && tsc",
- "lint": "eslint src/"
+ "lint": "eslint src/",
+ "build": "npm run lint && tsc",
+ "deploy": "aws s3 sync --delete public/ \"$(grep AWS_S3_BUCKET .env | cut -d '=' -f2)\" && aws cloudfront create-invalidation --distribution-id \"$(grep AWS_CLOUDFRONT_ID .env | cut -d '=' -f2)\" --paths=/*"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.30.0",
diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts
index b35b6b8..5c7a93c 100644
--- a/src/model/GameConfig.ts
+++ b/src/model/GameConfig.ts
@@ -77,6 +77,7 @@ class GameConfig {
public cfgPastorTitheCollectionFollowerMax = 100;
public cfgTimeBetweenTithes = 30000;
public cfgTitheAmount = 10;
+ public cfgTitheCredibilityHitFactor = 3;
public generateState (): GameState {
const state = new GameState(this);
diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts
index f97552c..e0f5864 100644
--- a/src/model/resource/Money.ts
+++ b/src/model/resource/Money.ts
@@ -1,22 +1,36 @@
///
-class Money extends Purchasable {
+class Money implements IResource {
public readonly resourceType = ResourceType.consumable;
+ public readonly label = 'Money';
+ public readonly singularName = '${}';
+ public readonly pluralName = '${}';
+ public readonly description = 'Used to purchase goods and services.';
+ public readonly valueInWholeNumbers = false;
+
+ public userActions: ResourceAction[] = [
+ {
+ name: 'Collect Tithes',
+ description: 'Voluntary contributions from followers.',
+ isEnabled: (state: GameState): boolean =>
+ this.value <= this.max(state)
+ && (state.resource.followers?.value ?? 0) >= 1,
+ performAction: (state: GameState): void => {
+ this._collectTithes(state);
+ },
+ },
+ ];
private _lastCollectionTime = 0;
constructor (
public value: number
- ) {
- super(
- 'Money',
- '${}',
- '${}',
- 'Used to purchase goods and services.',
- 'Collect Tithes',
- 'Voluntary contributions from followers.');
- this.valueInWholeNumbers = false;
- this._isUnlocked = true;
+ ) {}
+
+ public isUnlocked = (_state: GameState): boolean => true;
+
+ public addValue (amount: number, _state: GameState): void {
+ this.value += amount;
}
public max: (state: GameState) => number = (state: GameState) => {
@@ -40,20 +54,27 @@ class Money extends Purchasable {
return inc;
};
- protected _purchaseAmount (state: GameState): number {
- const plorg = state.resource.followers;
- if (plorg === undefined || plorg.value === 0) {
- state.log('You have no followers to collect from!');
- return 0;
- }
+ protected _collectTithes (state: GameState): void {
+ if (this.value >= this.max(state)) return;
+
+ const followers = state.resource.followers?.value ?? 0;
+ if (followers <= 0) return;
+
+ // collecting too frequently hurts credibility
const diff = state.now - this._lastCollectionTime;
if (diff < state.config.cfgTimeBetweenTithes) {
- const lost = state.config.cfgTimeBetweenTithes / diff / 3;
+ const lost = state.config.cfgTimeBetweenTithes
+ / diff / state.config.cfgTitheCredibilityHitFactor;
state.resource.credibility?.addValue(lost * -1, state);
}
- const tithings = plorg.value * state.config.cfgTitheAmount;
+
+ const tithings = followers * state.config.cfgTitheAmount;
this._lastCollectionTime = state.now;
- return tithings;
+
+ if (tithings > 0) {
+ this.addValue(tithings, state);
+ this._purchaseLog(tithings, state);
+ }
}
protected _purchaseLog (amount: number, state: GameState): string {
diff --git a/src/model/resource/Purchasable.ts b/src/model/resource/Purchasable.ts
index 831757e..58b1de2 100644
--- a/src/model/resource/Purchasable.ts
+++ b/src/model/resource/Purchasable.ts
@@ -49,10 +49,6 @@ abstract class Purchasable implements IResource {
return;
}
- protected _purchaseAmount (_state: GameState): number {
- return 1;
- }
-
protected _purchaseLog (amount: number, _state: GameState): string {
return `You purchased ${amount} ${amount > 1 ? this.pluralName : this.singularName}.`;
}
@@ -60,15 +56,12 @@ abstract class Purchasable implements IResource {
private _purchase (state: GameState): void {
if (this.max !== undefined && this.value >= this.max(state)) return;
if (state.deductCost(this.cost)) {
- const amount = this._purchaseAmount(state);
- if (amount > 0) {
- this.value += amount;
- state.log(this._purchaseLog(amount, state));
- for (const key in this._costMultiplier) {
- const rkey = key;
- this.cost[rkey] =
- (this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
- }
+ this.value += 1;
+ state.log(this._purchaseLog(1, state));
+ for (const key in this._costMultiplier) {
+ const rkey = key;
+ this.cost[rkey] =
+ (this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
}
}
}