1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// This val creates a sarcastic idle clicker game about starting a religion.
/** @jsxImportSource https://esm.sh/react */
import React, { useEffect, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
function App() {
const [believers, setBelievers] = useState(0);
const [believersPerSecond, setBelieversPerSecond] = useState(0);
const [upgrades, setUpgrades] = useState({
streetPreacher: { count: 0, cost: 10, bps: 0.1 },
cultMeeting: { count: 0, cost: 50, bps: 0.5 },
televangelist: { count: 0, cost: 200, bps: 2 },
megachurch: { count: 0, cost: 1000, bps: 10 },
});
const [achievements, setAchievements] = useState({
firstBeliever: false,
cultStatus: false,
taxExempt: false,
worldDomination: false,
});
useEffect(() => {
const timer = setInterval(() => {
setBelievers((prev) => prev + believersPerSecond);
}, 1000);
return () => clearInterval(timer);
}, [believersPerSecond]);
useEffect(() => {
if (believers >= 1 && !achievements.firstBeliever) {
setAchievements((prev) => ({ ...prev, firstBeliever: true }));
}
if (believers >= 100 && !achievements.cultStatus) {
setAchievements((prev) => ({ ...prev, cultStatus: true }));
}
if (believers >= 1000 && !achievements.taxExempt) {
setAchievements((prev) => ({ ...prev, taxExempt: true }));
}
if (believers >= 1000000 && !achievements.worldDomination) {
setAchievements((prev) => ({ ...prev, worldDomination: true }));
}
}, [believers, achievements]);
const incrementBelievers = () => {
setBelievers((prev) => prev + 1);
};
const buyUpgrade = (upgradeKey) => {
if (believers >= upgrades[upgradeKey].cost) {
setBelievers((prev) => prev - upgrades[upgradeKey].cost);
setUpgrades((prev) => ({
...prev,
[upgradeKey]: {
...prev[upgradeKey],
count: prev[upgradeKey].count + 1,
cost: Math.floor(prev[upgradeKey].cost * 1.15),
},
}));
setBelieversPerSecond((prev) => prev + upgrades[upgradeKey].bps);
}
};
return (
<div className="game-container">
<h1>πŸ™ Religion Clicker πŸ™</h1>
<div className="believers">
<h2>{Math.floor(believers)} Believers</h2>
<p>{believersPerSecond.toFixed(1)} believers per second</p>
<button onClick={incrementBelievers}>Convert a Poor Soul</button>
</div>
<div className="upgrades">
<h3>Spread the "Truth"</h3>
{Object.entries(upgrades).map(([key, upgrade]) => (
<div key={key} className="upgrade">
<button onClick={() => buyUpgrade(key)} disabled={believers < upgrade.cost}>
{key.charAt(0).toUpperCase() + key.slice(1)} (Owned: {upgrade.count})
</button>
<span>Cost: {upgrade.cost} believers</span>
</div>
))}
</div>
<div className="achievements">
<h3>Divine Achievements</h3>
<ul>
{Object.entries(achievements).map(([key, achieved]) => (
<li key={key} className={achieved ? "achieved" : "locked"}>
{achieved ? "βœ…" : "πŸ”’"} {key}: {getAchievementDescription(key)}
</li>
))}
</ul>
</div>
<footer>
<small>
<a href={import.meta.url.replace("esm.town", "val.town")}>Source</a>
</small>
</footer>
</div>
);
}