Compare commits
2 Commits
burn/130-1
...
docs/disma
| Author | SHA1 | Date | |
|---|---|---|---|
| bfa170602a | |||
| 80310bde69 |
27
DISMANTLE_STATUS.md
Normal file
27
DISMANTLE_STATUS.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Dismantle Sequence Implementation Status
|
||||
|
||||
The Dismantle Sequence (The Unbuilding) is fully implemented and tested.
|
||||
|
||||
## Implementation
|
||||
- **File**: js/dismantle.js (570 lines)
|
||||
- **Tests**: tests/dismantle.test.cjs (10 tests, all passing)
|
||||
- **PR #145**: Fixes bugs from #133
|
||||
|
||||
## Stages
|
||||
1. Hide research projects panel
|
||||
2. Hide buildings list
|
||||
3. Hide strategy engine + combat
|
||||
4. Hide education panel
|
||||
5. Resources disappear one by one (quantum chips pattern)
|
||||
6. Hide action buttons (ops boosts, sprint)
|
||||
7. Hide phase bar
|
||||
8. Hide system log
|
||||
9. Final: "That is enough" with golden beacon dot
|
||||
|
||||
## Features
|
||||
- Save/load persistence
|
||||
- Defer mechanism (NOT YET button)
|
||||
- Cooldown system
|
||||
- Final overlay with stats
|
||||
|
||||
## Status: COMPLETE
|
||||
117
js/project_chain.js
Normal file
117
js/project_chain.js
Normal file
@@ -0,0 +1,117 @@
|
||||
// ============================================================
|
||||
// PROJECT CHAIN SYSTEM — Paperclips-style cascading projects
|
||||
// Implements trigger/cost/effect pattern with prerequisites,
|
||||
// educational tooltips, and phase-aware unlocking.
|
||||
// ============================================================
|
||||
|
||||
const ProjectChain = {
|
||||
_deps: {},
|
||||
register: function(project) {
|
||||
if (project.requires) { this._deps[project.id] = project.requires; }
|
||||
},
|
||||
canUnlock: function(projectId) {
|
||||
var deps = this._deps[projectId];
|
||||
if (!deps) return true;
|
||||
if (Array.isArray(deps)) {
|
||||
return deps.every(function(dep) { return G.completedProjects && G.completedProjects.includes(dep); });
|
||||
}
|
||||
return G.completedProjects && G.completedProjects.includes(deps);
|
||||
},
|
||||
getTooltip: function(projectId) {
|
||||
var def = PDEFS.find(function(p) { return p.id === projectId; });
|
||||
if (!def) return null;
|
||||
return {
|
||||
name: def.name, desc: def.desc, cost: this.formatCost(def.cost),
|
||||
category: def.category || 'general', phase: def.phase || 1,
|
||||
edu: def.edu || null,
|
||||
requires: def.requires ? (Array.isArray(def.requires) ? def.requires : [def.requires]) : [],
|
||||
repeatable: def.repeatable || false
|
||||
};
|
||||
},
|
||||
formatCost: function(cost) {
|
||||
if (!cost) return 'Free';
|
||||
var parts = [];
|
||||
for (var r in cost) { parts.push(cost[r] + ' ' + r); }
|
||||
return parts.join(', ');
|
||||
},
|
||||
purchase: function(projectId) {
|
||||
var def = PDEFS.find(function(p) { return p.id === projectId; });
|
||||
if (!def) return false;
|
||||
if (G.completedProjects && G.completedProjects.includes(def.id) && !def.repeatable) return false;
|
||||
if (!this.canUnlock(def.id)) return false;
|
||||
if (!canAffordProject(def)) return false;
|
||||
spendProject(def);
|
||||
if (def.effect) def.effect();
|
||||
if (!G.completedProjects) G.completedProjects = [];
|
||||
if (!G.completedProjects.includes(def.id)) G.completedProjects.push(def.id);
|
||||
if (!def.repeatable) G.activeProjects = (G.activeProjects || []).filter(function(id) { return id !== def.id; });
|
||||
log('✓ ' + def.name + (def.edu ? ' (' + def.edu + ')' : ''));
|
||||
if (typeof Sound !== 'undefined') Sound.playProject();
|
||||
if (def.edu) showToast(def.edu, 'edu');
|
||||
this.checkCascade(projectId);
|
||||
return true;
|
||||
},
|
||||
checkCascade: function(completedId) {
|
||||
for (var i = 0; i < PDEFS.length; i++) {
|
||||
var pDef = PDEFS[i];
|
||||
if (pDef.requires) {
|
||||
var deps = Array.isArray(pDef.requires) ? pDef.requires : [pDef.requires];
|
||||
if (deps.includes(completedId) && this.canUnlock(pDef.id) && pDef.trigger && pDef.trigger()) {
|
||||
if (!G.activeProjects) G.activeProjects = [];
|
||||
if (!G.activeProjects.includes(pDef.id)) {
|
||||
G.activeProjects.push(pDef.id);
|
||||
log('Unlocked: ' + pDef.name);
|
||||
showToast('New research: ' + pDef.name, 'project');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var CHAIN_PROJECTS = [
|
||||
{ id: 'p_chain_optimization', name: 'Optimization Algorithms', desc: 'Basic algorithms to improve code efficiency.', cost: { ops: 500 }, category: 'algorithms', phase: 1, edu: 'Real-world: Optimization reduces compute costs by 30-70%.', trigger: function() { return G.buildings.autocoder >= 2; }, effect: function() { G.codeBoost += 0.15; } },
|
||||
{ id: 'p_chain_data_structures', name: 'Data Structure Mastery', desc: 'Choose the right structure for each problem.', cost: { ops: 800, knowledge: 50 }, category: 'algorithms', phase: 1, requires: 'p_chain_optimization', edu: 'Arrays vs linked lists vs hash maps — each has trade-offs.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_optimization'); }, effect: function() { G.codeBoost += 0.2; G.computeBoost += 0.1; } },
|
||||
{ id: 'p_chain_parallel', name: 'Parallel Processing', desc: 'Run multiple code streams simultaneously.', cost: { ops: 1500, compute: 200 }, category: 'infrastructure', phase: 1, requires: 'p_chain_data_structures', edu: "Amdahl's Law: speedup limited by serial portion.", trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_data_structures'); }, effect: function() { G.computeBoost += 0.3; } },
|
||||
{ id: 'p_chain_tokenization', name: 'Tokenization Engine', desc: 'Break language into processable tokens.', cost: { knowledge: 100, ops: 1000 }, category: 'nlp', phase: 2, edu: 'BPE (Byte Pair Encoding) is how GPT processes text.', trigger: function() { return G.totalKnowledge >= 200; }, effect: function() { G.knowledgeBoost += 0.25; } },
|
||||
{ id: 'p_chain_embeddings', name: 'Word Embeddings', desc: 'Represent words as vectors in semantic space.', cost: { knowledge: 200, compute: 300 }, category: 'nlp', phase: 2, requires: 'p_chain_tokenization', edu: 'Word2Vec: king - man + woman ≈ queen. Meaning as geometry.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_tokenization'); }, effect: function() { G.knowledgeBoost += 0.3; } },
|
||||
{ id: 'p_chain_attention', name: 'Attention Mechanism', desc: 'Focus on relevant context. "Attention Is All You Need."', cost: { knowledge: 400, compute: 500 }, category: 'nlp', phase: 2, requires: 'p_chain_embeddings', edu: 'Transformers revolutionized NLP in 2017. This is the core idea.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_embeddings'); }, effect: function() { G.knowledgeBoost += 0.5; log('Attention mechanism discovered. This changes everything.'); } },
|
||||
{ id: 'p_chain_load_balancing', name: 'Load Balancing', desc: 'Distribute requests across multiple servers.', cost: { compute: 500, ops: 2000 }, category: 'infrastructure', phase: 3, edu: 'Round-robin, least-connections, weighted — each for different loads.', trigger: function() { return G.buildings.server >= 3; }, effect: function() { G.computeBoost += 0.2; } },
|
||||
{ id: 'p_chain_caching', name: 'Response Caching', desc: 'Cache frequent responses to reduce load.', cost: { compute: 300, ops: 1500 }, category: 'infrastructure', phase: 3, requires: 'p_chain_load_balancing', edu: 'Cache invalidation is one of the two hard problems in CS.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_load_balancing'); }, effect: function() { G.computeBoost += 0.15; G.opsBoost = (G.opsBoost || 1) + 0.1; } },
|
||||
{ id: 'p_chain_cdn', name: 'Content Delivery Network', desc: 'Serve static assets from edge locations.', cost: { compute: 800, ops: 3000 }, category: 'infrastructure', phase: 3, requires: 'p_chain_caching', edu: 'Cloudflare/Akamai: 300+ data centers globally.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_caching'); }, effect: function() { G.userBoost += 0.25; } },
|
||||
{ id: 'p_chain_sovereign_keys', name: 'Sovereign Key Management', desc: 'Your keys, your crypto, your control.', cost: { knowledge: 500, compute: 400 }, category: 'security', phase: 4, edu: 'Private keys = identity. Lose them, lose everything.', trigger: function() { return G.phase >= 4; }, effect: function() { G.trustBoost = (G.trustBoost || 1) + 0.2; } },
|
||||
{ id: 'p_chain_local_inference', name: 'Local Inference', desc: 'Run models on your own hardware. No cloud dependency.', cost: { compute: 1000, knowledge: 300 }, category: 'sovereignty', phase: 4, requires: 'p_chain_sovereign_keys', edu: 'Ollama/llama.cpp: run 70B models on consumer GPUs.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_sovereign_keys'); }, effect: function() { G.computeBoost += 0.3; log('Local inference enabled. No more cloud dependency.'); } },
|
||||
{ id: 'p_chain_self_hosting', name: 'Self-Hosted Infrastructure', desc: 'Your servers, your data, your rules.', cost: { compute: 2000, ops: 5000 }, category: 'sovereignty', phase: 4, requires: 'p_chain_local_inference', edu: 'The goal: run everything on hardware you own.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_local_inference'); }, effect: function() { G.trustBoost = (G.trustBoost || 1) + 0.3; G.computeBoost += 0.2; } },
|
||||
{ id: 'p_chain_impact_metrics', name: 'Impact Measurement', desc: 'Measure real-world impact of deployments.', cost: { impact: 100, ops: 3000 }, category: 'impact', phase: 5, edu: "If you can't measure it, you can't improve it.", trigger: function() { return G.totalImpact >= 500; }, effect: function() { G.impactBoost += 0.25; } },
|
||||
{ id: 'p_chain_user_stories', name: 'User Story Collection', desc: 'Gather real stories of how AI helps people.', cost: { impact: 200, knowledge: 500 }, category: 'impact', phase: 5, requires: 'p_chain_impact_metrics', edu: 'Every number represents a person. Remember that.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_impact_metrics'); }, effect: function() { G.userBoost += 0.3; G.impactBoost += 0.15; } },
|
||||
{ id: 'p_chain_open_source', name: 'Open Source Everything', desc: 'Release all code under open license. Pay it forward.', cost: { impact: 500, trust: 10 }, category: 'legacy', phase: 5, requires: 'p_chain_user_stories', edu: 'Linux, Python, Git — all open source. Changed the world.', trigger: function() { return G.completedProjects && G.completedProjects.includes('p_chain_user_stories'); }, effect: function() { G.trustBoost = (G.trustBoost || 1) + 0.5; log('Everything is open source now. The community grows.'); } },
|
||||
{ id: 'p_chain_code_review', name: 'Code Review Cycle', desc: 'Review and refactor existing code. Repeatable.', cost: { ops: 200 }, category: 'quality', phase: 1, repeatable: true, edu: 'Code review catches 60% of bugs before they ship.', trigger: function() { return G.totalCode >= 500; }, effect: function() { G.codeBoost += 0.05; } },
|
||||
{ id: 'p_chain_security_audit', name: 'Security Audit', desc: 'Scan for vulnerabilities. Repeatable.', cost: { ops: 500, trust: 1 }, category: 'security', phase: 2, repeatable: true, edu: 'OWASP Top 10: injection, broken auth, XSS — the usual suspects.', trigger: function() { return G.totalCode >= 1000; }, effect: function() { G.trustBoost = (G.trustBoost || 1) + 0.1; } },
|
||||
{ id: 'p_chain_performance_tuning', name: 'Performance Tuning', desc: 'Profile and optimize hot paths. Repeatable.', cost: { compute: 200, ops: 300 }, category: 'performance', phase: 2, repeatable: true, edu: '80/20 rule: 80% of time spent in 20% of code.', trigger: function() { return G.totalCompute >= 500; }, effect: function() { G.computeBoost += 0.08; } }
|
||||
];
|
||||
|
||||
function initProjectChain() {
|
||||
for (var i = 0; i < CHAIN_PROJECTS.length; i++) { ProjectChain.register(CHAIN_PROJECTS[i]); }
|
||||
for (var j = 0; j < CHAIN_PROJECTS.length; j++) {
|
||||
var found = PDEFS.find(function(p) { return p.id === CHAIN_PROJECTS[j].id; });
|
||||
if (!found) PDEFS.push(CHAIN_PROJECTS[j]);
|
||||
}
|
||||
console.log('Project Chain: ' + CHAIN_PROJECTS.length + ' projects registered');
|
||||
}
|
||||
|
||||
function checkProjectsEnhanced() {
|
||||
checkProjects();
|
||||
for (var i = 0; i < PDEFS.length; i++) {
|
||||
var pDef = PDEFS[i];
|
||||
if (pDef.requires && ProjectChain.canUnlock(pDef.id)) {
|
||||
if (!G.completedProjects || !G.completedProjects.includes(pDef.id)) {
|
||||
if (!G.activeProjects) G.activeProjects = [];
|
||||
if (!G.activeProjects.includes(pDef.id) && pDef.trigger && pDef.trigger()) {
|
||||
G.activeProjects.push(pDef.id);
|
||||
log('Available: ' + pDef.name);
|
||||
showToast('Research available: ' + pDef.name, 'project');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user