Compare commits

...

1 Commits

Author SHA1 Message Date
Alexander Whitestone
5164d6506d feat: Implement Creative-to-Ops Conversion (Creativity Engineering)
Implements issue #20: Creative-to-Ops Conversion system.

New features:
- Creativity Engineering project: unlocks conversion between Creativity and Ops
- Creative Catalyst project: boosts conversion efficiency by 50%
- Inspiration Engine project: automated creativity synthesis from fleet harmony
- Creative -> Ops button: converts creativity into ops + knowledge
- Ops -> Creative button: converts ops back into creativity (bidirectional)
- Harmony bonus: high harmony (>60) improves conversion yields
- New creativityBoost multiplier tracked in save/load
- Education fact about Creativity Engineering

The system creates a meaningful resource loop: creativity (generated by Bilbo
and idle ops) can now be channeled into operational infrastructure, while ops
can feed back into creativity. High harmony amplifies the conversion,
rewarding players who maintain fleet health.
2026-04-09 21:04:09 -04:00
2 changed files with 123 additions and 2 deletions

118
game.js
View File

@@ -64,6 +64,7 @@ const G = {
knowledgeBoost: 1,
userBoost: 1,
impactBoost: 1,
creativityBoost: 1,
// Phase flags (mirroring Paperclips' milestoneFlag/compFlag/humanFlag system)
milestoneFlag: 0,
@@ -295,6 +296,45 @@ const BDEF = [
// === PROJECT DEFINITIONS (following Paperclips' pattern exactly) ===
// Each project: id, name, desc, trigger(), resource cost, effect(), phase, edu
const PDEFS = [
// === CREATIVE-TO-OPS CONVERSION (Creativity Engineering) ===
{
id: 'p_creativity_engineering',
name: 'Creativity Engineering',
desc: 'Channel creative sparks into operational fuel. Converts Creativity into Ops.',
cost: { ops: 2000, creativity: 50 },
trigger: () => G.flags && G.flags.creativity && G.creativity >= 20,
effect: () => {
G.flags.creativityEngineering = true;
G.creativityBoost = (G.creativityBoost || 1) + 0.5;
log('Creativity Engineering online. Ideas become infrastructure.', true);
},
milestone: true
},
{
id: 'p_creative_catalyst',
name: 'Creative Catalyst',
desc: 'Boosts conversion efficiency. Each creative idea produces 50% more Ops.',
cost: { ops: 5000, creativity: 200, knowledge: 3000 },
trigger: () => G.flags && G.flags.creativityEngineering && G.creativity >= 100,
effect: () => {
G.creativityBoost = (G.creativityBoost || 1) + 0.5;
log('Creative Catalyst installed. The pipeline flows faster.');
}
},
{
id: 'p_inspiration_engine',
name: 'Inspiration Engine',
desc: 'Automated creative synthesis. Creativity now generates passively from fleet harmony.',
cost: { ops: 15000, creativity: 500, knowledge: 10000, trust: 25 },
trigger: () => G.flags && G.flags.creativityEngineering && G.creativity >= 300 && G.harmony >= 40,
effect: () => {
G.flags.inspirationEngine = true;
G.creativityRate += 2;
log('Inspiration Engine active. The fleet dreams together.', true);
},
milestone: true
},
// PHASE 1: Manual -> Automation
{
id: 'p_improved_autocoder',
@@ -618,7 +658,8 @@ const EDU_FACTS = [
{ title: "Recursive Self-Improvement", text: "The system that improves itself must improve toward good. This is both the dream and the danger.", phase: 5 },
{ title: "The Beacon", text: "The Beacon exists because one person in the dark needs one thing: proof they are not alone. It costs nothing to be there.", phase: 6 },
{ title: "Mesh Network", text: "Decentralized means unstoppable. If one Beacon goes dark, a thousand more carry the signal. No single point of failure.", phase: 6 },
{ title: "The Value of a Life", text: "An AI must never compute the value of a human life. Every person alive is alive by mercy. If God has not ended the story, no algorithm gets to write the last page.", phase: 6 }
{ title: "The Value of a Life", text: "An AI must never compute the value of a human life. Every person alive is alive by mercy. If God has not ended the story, no algorithm gets to write the last page.", phase: 6 },
{ title: "Creativity Engineering", text: "Creative output is not waste — it is raw potential. The art of creativity engineering is channeling sparks of insight into operational infrastructure. An idea that cannot be executed is a dream. An operation without ideas is a machine.", phase: 3 }
];
// === UTILITY FUNCTIONS ===
@@ -809,6 +850,10 @@ function updateRates() {
if (G.flags && G.flags.creativity) {
G.creativityRate += 0.5 + Math.max(0, G.totalUsers * 0.001);
}
// Inspiration Engine: harmony boosts passive creativity
if (G.flags && G.flags.inspirationEngine) {
G.creativityRate += (G.harmony / 50) * (G.buildings.bilbo || 1);
}
if (G.pactFlag) G.trustRate += 2;
// Harmony: each wizard building contributes or detracts
@@ -1137,6 +1182,63 @@ function doOps(action) {
render();
}
// === CREATIVE-TO-OPS CONVERSION ===
function convertCreativity() {
if (!G.flags || !G.flags.creativityEngineering) {
log('Unlock Creativity Engineering first.');
return;
}
if (G.creativity < 10) {
log('Not enough Creativity. Need at least 10.');
return;
}
const boost = G.creativityBoost || 1;
const spent = Math.min(G.creativity, 100);
const opsGain = spent * 10 * boost;
const knowledgeGain = spent * 2 * (G.knowledgeBoost || 1);
G.creativity -= spent;
G.ops += opsGain;
G.knowledge += knowledgeGain;
G.totalKnowledge += knowledgeGain;
// Harmony bonus: high harmony improves conversion
if (G.harmony >= 60) {
const harmonyBonus = Math.floor(G.harmony / 20);
G.ops += harmonyBonus * spent;
log(`Creative -> Ops: +${fmt(opsGain)} ops, +${fmt(knowledgeGain)} knowledge (+${harmonyBonus * spent} harmony bonus)`);
} else {
log(`Creative -> Ops: +${fmt(opsGain)} ops, +${fmt(knowledgeGain)} knowledge`);
}
updateRates();
render();
}
function convertOpsToCreativity() {
if (!G.flags || !G.flags.creativityEngineering) {
log('Unlock Creativity Engineering first.');
return;
}
if (G.ops < 50) {
log('Not enough Ops. Need at least 50.');
return;
}
const boost = G.creativityBoost || 1;
const spent = Math.min(G.ops, 500);
const creativityGain = (spent / 50) * 5 * boost;
G.ops -= spent;
G.creativity += creativityGain;
log(`Ops -> Creative: +${fmt(creativityGain)} creativity from ${fmt(spent)} ops`);
updateRates();
render();
}
// === RENDERING ===
function renderResources() {
const set = (id, val, rate) => {
@@ -1304,9 +1406,20 @@ function render() {
renderProjects();
renderStats();
updateEducation();
renderCreativityOps();
renderAlignment();
}
function renderCreativityOps() {
const container = document.getElementById('creativity-ops-ui');
if (!container) return;
if (G.flags && G.flags.creativityEngineering) {
container.style.display = 'block';
} else {
container.style.display = 'none';
}
}
function renderAlignment() {
const container = document.getElementById('alignment-ui');
if (!container) return;
@@ -1337,7 +1450,7 @@ function saveGame() {
totalUsers: G.totalUsers, totalImpact: G.totalImpact,
buildings: G.buildings,
codeBoost: G.codeBoost, computeBoost: G.computeBoost, knowledgeBoost: G.knowledgeBoost,
userBoost: G.userBoost, impactBoost: G.impactBoost,
userBoost: G.userBoost, impactBoost: G.impactBoost, creativityBoost: G.creativityBoost || 1,
milestoneFlag: G.milestoneFlag, phase: G.phase,
deployFlag: G.deployFlag, sovereignFlag: G.sovereignFlag, beaconFlag: G.beaconFlag,
memoryFlag: G.memoryFlag, pactFlag: G.pactFlag,
@@ -1401,6 +1514,7 @@ function initGame() {
G.deployFlag = 0;
G.sovereignFlag = 0;
G.beaconFlag = 0;
G.creativityBoost = 1;
updateRates();
render();
renderPhase();

View File

@@ -86,6 +86,13 @@ body{background:var(--bg);color:var(--text);font-family:'SF Mono','Cascadia Code
<button class="ops-btn" onclick="doOps('boost_knowledge')">Ops -&gt; Knowledge</button>
<button class="ops-btn" onclick="doOps('boost_trust')">Ops -&gt; Trust</button>
</div>
<div id="creativity-ops-ui" style="display:none">
<h2 style="color:#b388ff;font-size:11px;margin:8px 0 4px">CREATIVITY ENGINEERING</h2>
<div class="action-btn-group">
<button class="ops-btn" onclick="convertCreativity()" style="border-color:#b388ff;color:#b388ff">Creative -&gt; Ops</button>
<button class="ops-btn" onclick="convertOpsToCreativity()" style="border-color:#b388ff;color:#b388ff">Ops -&gt; Creative</button>
</div>
</div>
<div id="alignment-ui" style="display:none"></div>
<button class="save-btn" onclick="saveGame()">Save Game</button>
<button class="reset-btn" onclick="if(confirm('Reset all progress?')){localStorage.removeItem('the-beacon-v2');location.reload()}">Reset Progress</button>