diff --git a/src/model/logging/ConsoleLogger.ts b/src/logging/ConsoleLogger.ts similarity index 59% rename from src/model/logging/ConsoleLogger.ts rename to src/logging/ConsoleLogger.ts index 0c63c61..a4da7c3 100644 --- a/src/model/logging/ConsoleLogger.ts +++ b/src/logging/ConsoleLogger.ts @@ -2,4 +2,8 @@ class ConsoleLogger implements ILogger { public msg (text: string): void { console.log(text); } + + public unsafeMsg (text: string): void { + console.error(text); + } } diff --git a/src/model/logging/DebugLogger.ts b/src/logging/DebugLogger.ts similarity index 51% rename from src/model/logging/DebugLogger.ts rename to src/logging/DebugLogger.ts index b0b68db..126136e 100644 --- a/src/model/logging/DebugLogger.ts +++ b/src/logging/DebugLogger.ts @@ -6,9 +6,21 @@ class DebugLogger implements ILogger { } public msg (text: string): void { - const p = document.createElement('p'); - p.innerText = text; - this._container.appendChild(p); + this._doMsg(text, true); + } + + public unsafeMsg (text: string): void { + this._doMsg(text, false); + } + + private _doMsg (text: string, safe: boolean): void { + const el = document.createElement('p'); + if (safe) { + el.innerText = text; + } else { + el.innerHTML = text; + } + this._container.appendChild(el); if (this._container.parentElement !== null) { this._container.parentElement.scrollTop = this._container.parentElement.scrollHeight; diff --git a/src/model/logging/ILogger.ts b/src/logging/ILogger.ts similarity index 58% rename from src/model/logging/ILogger.ts rename to src/logging/ILogger.ts index 2dc7c31..e5770e5 100644 --- a/src/model/logging/ILogger.ts +++ b/src/logging/ILogger.ts @@ -1,3 +1,4 @@ interface ILogger { msg: (text: string) => void; + unsafeMsg: (text: string) => void; } diff --git a/src/main.ts b/src/main.ts index 9aedb3b..9a0c5f6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,6 +25,17 @@ function startGame (state: GameState, renderer: IRenderer): void { gameLoop(state, renderer); // start the main loop } +function initialRender (state: GameState): void { + if (state.logger === null) return; + state.logger.unsafeMsg(`Welcome to irreligio.us! +

+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. +

+Additionally, the game has not been as is not in any kind of state to be playtested or balanced in any way, and even though it auto-saves and resumes, it's changing so much that save data may become corrupt and force you to clear cookies and localstorage and lose all progress before the game loads again. If you want to actually play a fun incremental game, this isn't really ready yet. +

+The game's source code on Github is likely further along than this. Have fun!

`); +} + // run with default config at startup ((): void => { const config = new GameConfig(); @@ -37,6 +48,7 @@ function startGame (state: GameState, renderer: IRenderer): void { config.cfgPastorRecruitRate = 0.5; const renderer = new DebugRenderer(); + renderer.onInitialRender = initialRender; const state = config.generateState(); // re-run main loop immediately on user clicks diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts index 9659bde..b35b6b8 100644 --- a/src/model/GameConfig.ts +++ b/src/model/GameConfig.ts @@ -86,35 +86,35 @@ class GameConfig { // create world religions state.addResource(ResourceKey.christianity, new Religion( - 'christian', 'christians', 'God, Jesus, Bible, churches.', + 'Christianity', 'christian', 'christians', 'God, Jesus, Bible, churches.', (this.cfgReligion.christianity ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.islam, new Religion( - 'muslim', 'muslims', 'God, Muhammad, Quran, mosques.', + 'Islam', 'muslim', 'muslims', 'God, Muhammad, Quran, mosques.', (this.cfgReligion.islam ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.hinduism, new Religion( - 'hindu', 'hindus', 'Dogma-free spiritualism.', + 'Hinduism', 'hindu', 'hindus', 'Dogma-free spiritualism.', (this.cfgReligion.hinduism ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.buddhism, new Religion( - 'buddhist', 'buddhists', 'The minimization of suffering.', + 'Buddhism', 'buddhist', 'buddhists', 'The minimization of suffering.', (this.cfgReligion.buddhism ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.sikhism, new Religion( - 'sikh', 'sikhs', 'Meditation and ten Gurus', + 'Sikhism', 'sikh', 'sikhs', 'Meditation and ten Gurus', (this.cfgReligion.sikhism ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.judaism, new Religion( - 'jew', 'jews', 'God, Abraham, Torah, synagogues.', + 'Judaism', 'jew', 'jews', 'God, Abraham, Torah, synagogues.', (this.cfgReligion.judaism ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.other, new Religion( - 'other', 'others', 'A variety of belief systems.', + 'Other', 'person from other faiths', 'people from other faiths', 'A variety of belief systems.', (this.cfgReligion.other ?? 0) * this.worldPopulation)); state.addResource(ResourceKey.atheism, new Religion( - 'atheist', 'atheists', 'Atheists and agnostics.', + 'Non-Religious', 'atheist', 'atheists', 'Atheists and agnostics.', (this.cfgReligion.atheism ?? 0) * this.worldPopulation)); // add jobs diff --git a/src/model/resource/BuildingPermit.ts b/src/model/resource/BuildingPermit.ts index 37fa910..f7e268d 100644 --- a/src/model/resource/BuildingPermit.ts +++ b/src/model/resource/BuildingPermit.ts @@ -3,6 +3,7 @@ class BuildingPermit extends Research { constructor (config: GameConfig) { super( + 'Building Permit', 'building permit', 'building permits', 'Unlocks several new buildings you can build outside of your compounds.'); diff --git a/src/model/resource/Church.ts b/src/model/resource/Church.ts index 40fbb2b..948cd06 100644 --- a/src/model/resource/Church.ts +++ b/src/model/resource/Church.ts @@ -3,6 +3,7 @@ class Church extends Infrastructure { constructor (config: GameConfig) { super( + 'Churches', 'church', 'churches', `Preaching grounds for ${formatNumber(config.cfgCapacity.churches?.pastors ?? 0)} pastors.`); diff --git a/src/model/resource/Compound.ts b/src/model/resource/Compound.ts index 7e9e16f..89bc73a 100644 --- a/src/model/resource/Compound.ts +++ b/src/model/resource/Compound.ts @@ -3,6 +3,7 @@ class Compound extends Infrastructure { constructor (config: GameConfig) { super( + 'Compounds', 'compound', 'compounds', 'Provides space for tents, houses, and churches and a place to hide more money.'); diff --git a/src/model/resource/Credibility.ts b/src/model/resource/Credibility.ts index 6315a54..3212528 100644 --- a/src/model/resource/Credibility.ts +++ b/src/model/resource/Credibility.ts @@ -3,6 +3,7 @@ class Credibility extends Passive { constructor (config: GameConfig) { super( + 'Credibility', 'credibility', 'credibilities', 'Affects your ability to recruit and retain followers.'); diff --git a/src/model/resource/CryptoCurrency.ts b/src/model/resource/CryptoCurrency.ts index 716b2a7..f50d5c6 100644 --- a/src/model/resource/CryptoCurrency.ts +++ b/src/model/resource/CryptoCurrency.ts @@ -4,7 +4,8 @@ class CryptoCurrency extends Purchasable { constructor (config: GameConfig) { super( 'FaithCoin', - 'FaithCoins', + 'faithcoin', + 'faithcoins', "A crypto coin that can't be spent directly, but provides a steady stream of passive income."); this.cost.money = config.cfgInitialCost.cryptoCurrency; this._costMultiplier.money = config.cfgCostMultiplier.cryptoCurrency; diff --git a/src/model/resource/Follower.ts b/src/model/resource/Follower.ts index 56212f1..f774eca 100644 --- a/src/model/resource/Follower.ts +++ b/src/model/resource/Follower.ts @@ -2,6 +2,7 @@ class Follower implements IResource { public readonly resourceType = ResourceType.religion; + public readonly label = 'Your Followers'; public readonly singularName = 'follower'; public readonly pluralName = 'followers'; public readonly description = 'In you they trust.'; diff --git a/src/model/resource/House.ts b/src/model/resource/House.ts index e6efee2..5561b59 100644 --- a/src/model/resource/House.ts +++ b/src/model/resource/House.ts @@ -3,6 +3,7 @@ class House extends Infrastructure { constructor (config: GameConfig) { super( + 'Houses', 'house', 'houses', `Provides room to house ${formatNumber(config.cfgCapacity.houses?.followers ?? 0)} followers.`); diff --git a/src/model/resource/IResource.ts b/src/model/resource/IResource.ts index 681001b..7e1175d 100644 --- a/src/model/resource/IResource.ts +++ b/src/model/resource/IResource.ts @@ -2,6 +2,7 @@ interface IResource { readonly resourceType: ResourceType; + readonly label?: string; readonly singularName: string; readonly pluralName: string; readonly description: string; diff --git a/src/model/resource/Job.ts b/src/model/resource/Job.ts index 7e50f62..250ce80 100644 --- a/src/model/resource/Job.ts +++ b/src/model/resource/Job.ts @@ -15,7 +15,7 @@ abstract class Job implements IResource { description: 'Promote one of your followers.', isEnabled: (state: GameState): boolean => (this.max === undefined || this.value < this.max(state)) - && this.value < this._availableJobs(state), + && this._availableJobs(state) > 0, performAction: (state: GameState): void => { this._promoteFollower(state); }, @@ -34,6 +34,7 @@ abstract class Job implements IResource { protected _isUnlocked = false; constructor ( + public readonly label: string, public readonly singularName: string, public readonly pluralName: string, public readonly description: string diff --git a/src/model/resource/Megachurch.ts b/src/model/resource/Megachurch.ts index 4ac019b..34ffdb4 100644 --- a/src/model/resource/Megachurch.ts +++ b/src/model/resource/Megachurch.ts @@ -3,6 +3,7 @@ class Megachurch extends Infrastructure { constructor (config: GameConfig) { super( + 'Megachurches', 'megachurch', 'megachurches', `Room for ${formatNumber(config.cfgCapacity.megaChurches?.pastors ?? 0)} pastors`); diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts index 3b51e79..f97552c 100644 --- a/src/model/resource/Money.ts +++ b/src/model/resource/Money.ts @@ -9,8 +9,9 @@ class Money extends Purchasable { public value: number ) { super( - 'money', - 'moneys', + 'Money', + '${}', + '${}', 'Used to purchase goods and services.', 'Collect Tithes', 'Voluntary contributions from followers.'); diff --git a/src/model/resource/Passive.ts b/src/model/resource/Passive.ts index 841b8c0..5d4d1c9 100644 --- a/src/model/resource/Passive.ts +++ b/src/model/resource/Passive.ts @@ -8,6 +8,7 @@ abstract class Passive implements IResource { public advanceAction?: (time: number, state: GameState) => void = undefined; constructor ( + public readonly label: string, public readonly singularName: string, public readonly pluralName: string, public readonly description: string diff --git a/src/model/resource/Pastor.ts b/src/model/resource/Pastor.ts index debeddc..6178c66 100644 --- a/src/model/resource/Pastor.ts +++ b/src/model/resource/Pastor.ts @@ -5,6 +5,7 @@ class Pastor extends Job { constructor () { super( + 'Pastors', 'pastor', 'pastors', 'Collect tithings for you and recruit new members from other faiths automatically.'); diff --git a/src/model/resource/Purchasable.ts b/src/model/resource/Purchasable.ts index 392675a..831757e 100644 --- a/src/model/resource/Purchasable.ts +++ b/src/model/resource/Purchasable.ts @@ -26,6 +26,7 @@ abstract class Purchasable implements IResource { protected _isUnlocked = false; constructor ( + public readonly label: string, public readonly singularName: string, public readonly pluralName: string, public readonly description: string, diff --git a/src/model/resource/Religion.ts b/src/model/resource/Religion.ts index eb95c0c..b7e6dee 100644 --- a/src/model/resource/Religion.ts +++ b/src/model/resource/Religion.ts @@ -5,6 +5,7 @@ class Religion implements IResource { public readonly valueInWholeNumbers = true; constructor ( + public readonly label: string, public readonly singularName: string, public readonly pluralName: string, public readonly description: string, diff --git a/src/model/resource/Research.ts b/src/model/resource/Research.ts index d303522..f68c4f1 100644 --- a/src/model/resource/Research.ts +++ b/src/model/resource/Research.ts @@ -5,11 +5,13 @@ abstract class Research extends Purchasable { public inc = undefined; constructor ( + public readonly label: string, public readonly singularName: string, public readonly pluralName: string, public readonly description: string ) { super( + label, singularName, pluralName, description, diff --git a/src/model/resource/Tent.ts b/src/model/resource/Tent.ts index 468a1ca..cd29579 100644 --- a/src/model/resource/Tent.ts +++ b/src/model/resource/Tent.ts @@ -3,6 +3,7 @@ class Tent extends Infrastructure { constructor (config: GameConfig) { super( + 'Tents', 'tent', 'tents', `Provides room to house ${formatNumber(config.cfgCapacity.tents?.followers ?? 0)} followers.`); diff --git a/src/render/DebugRenderer.ts b/src/render/DebugRenderer.ts index 2616bc3..9e52e1e 100644 --- a/src/render/DebugRenderer.ts +++ b/src/render/DebugRenderer.ts @@ -1,6 +1,8 @@ -/// +/// class DebugRenderer implements IRenderer { + public onInitialRender?: (state: GameState) => void; + private _initialized = false; private _handleClick = true; @@ -12,7 +14,6 @@ class DebugRenderer implements IRenderer { console.error('could not find game container'); return; } - this._initialized = true; state.onResourceClick.push((): void => { this._handleClick = true; }); @@ -43,7 +44,7 @@ class DebugRenderer implements IRenderer { // create containers for each resource for (const rkey of rkeys) { const resource = state.resource[rkey]; - if (resource === undefined) continue; + if (resource === undefined || resource.label === undefined) continue; const resContainer = document.getElementById( `resource-container-${resource.resourceType}`); if (resContainer === null) continue; @@ -53,7 +54,7 @@ class DebugRenderer implements IRenderer { let content = ` - ${this._escape(resource.pluralName)}
+ ${this._escape(resource.label)}
@@ -142,6 +143,11 @@ class DebugRenderer implements IRenderer { } } this._handleClick = false; + + if (!this._initialized && this.onInitialRender !== undefined) { + this.onInitialRender(state); + } + this._initialized = true; } private _escape (text: string): string { diff --git a/src/render/IRenderer.ts b/src/render/IRenderer.ts index 6dddd04..62baf7a 100644 --- a/src/render/IRenderer.ts +++ b/src/render/IRenderer.ts @@ -1,3 +1,4 @@ interface IRenderer { render: (state: GameState) => void; + onInitialRender?: (state: GameState) => void; }