diff --git a/drafts/site-c/index.html b/drafts/site-c/index.html new file mode 100644 index 00000000..88275164 --- /dev/null +++ b/drafts/site-c/index.html @@ -0,0 +1,352 @@ + + + + + + + Magic Civilization — Mod the Mind + + + + + + + + +
+
+
+

Mod the Mind

+

A 4X engine built for modders. Ship your own AI. Play against decision-makers you designed.

+ + + +
+

Age of Dwarves — Episode 1 • Coming Soon

+

Available on Steam App Store Google Play

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
+

The AI Plugin Interface

+

Three trait methods. One decision loop. Your imagination.

+ +
+
pub trait DecisionMaker {
+    fn decide_turn(
+        &mut self,
+        state: &GameState,
+        slot: PlayerId,
+        seed: u64,
+    ) -> Vec<Action>;
+
+    fn resolve_combat(
+        &mut self,
+        units: &[Unit],
+    ) -> CombatOrder;
+
+    fn inspect(&self) -> AiMetadata;
+}
+
+ +
+
+
📊
+

Access Complete State

+

Map, units, cities, tech, economics, diplomacy—everything the game knows, your AI sees.

+
+
+
🎲
+

Deterministic by Design

+

Same seed, same game. Replay, debug, validate your decisions. No RNG surprises.

+
+
+
+

Composition Over Config

+

Implement once, plug in everywhere. Trading, diplomacy, magic, combat—one interface.

+
+
+ +
+

Shipping AI Variants

+
+
+ Neural + Learned (PPO) +

Trained via self-play. Open-sourced as worked example. 128K games, 5 strategies emergent.

+
+
+ Scripted + Six Personalities +

MCTS + heuristics. Dwarven Traditionalist, Trader, Conqueror, Scholar, Mystic, Xenophobe.

+
+
+
+
+
+ + +
+
+

WASM by Default

+

Safe. Deterministic. Cross-platform. The mod lingua franca.

+ +
+
+
🔒
+

Sandboxed

+

No filesystem, no network, no OS calls. Your mod can't crash the game or steal saves.

+
+
+
+

Deterministic

+

Floating-point ops, RNG, time—all pinned. Replays never diverge, even years later.

+
+
+
📦
+

One Binary

+

Compile once. Ships unmodified on Windows, macOS, Linux, mobile. No per-platform rebuilds.

+
+
+
🚀
+

Near-Native Speed

+

Wasmer JIT + engine optimizations. Typical AI turn decision: <100ms on mid-range hardware.

+
+
+ +
+

Loading Pipeline

+ + + + Mod.wasm + + + + + Validate + + + + + Instantiate + + + + + Game + + + Signed + Checksum + Sandboxed + Deterministic + +
+
+
+ + +
+
+

Native Escape Hatch

+

Need raw GPU? Deep reinforcement learning? Go native—with your signature.

+ +
+
+

For AI projects that demand native performance (CUDA, large model inference, specialized math), sign your plugin with a developer certificate. The game loads and isolates it—you own the security risk, you own the support burden.

+ +

The bar is signature, not gatekeeping. We're not reviewing code. We're not limiting what you can do. Sign it, ship it, users decide.

+ +
+

Post-launch roadmap: Steam Workshop will surface both WASM and signed native mods side-by-side. Filtering, ratings, versioning built in.

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WASMNative (Signed)
Sandbox✓ EnforcedFull access
Platform coverage✓ Windows, macOS, Linux, iOS, AndroidPer-platform builds
Determinism guarantee✓ By defaultYour responsibility
Review gate✓ Zero—publish immediately✓ Signature only, no code review
Typical use caseMCTS, heuristics, small NNLLM inference, CUDA training, bespoke math
+
+
+
+
+ + +
+
+

Ship Open Source

+

The shipped learned AI is your working example.

+ +
+
+

Reference Implementation

+

The Neural variant—PPO trainer, 128K game history, strategy evaluation suite—lives on GitHub as public Rust + WASM. Read it. Fork it. Retrain it. Own the stack.

+ + + github.com/magic-civilization/ai-reference + +
+ +
+
+ 128K + Training games +
+
+ 5 + Emergent strategies +
+
+ Apache 2.0 + License +
+
+
+
+
+ + +
+
+

Roadmap

+

From launch through post-launch.

+ +
+
+
+

Episode 1: Age of Dwarves

+

Pre-launch (now). Wishlist opens. AI mod docs go live. Reference AI training begins.

+
+ +
+
+

1.0 Launch

+

Steam, App Store, Google Play. Shipped with 1 neural + 6 scripted AIs. Direct mod loading from ~/Documents/MagicCivilization/mods/.

+
+ +
+
+

1.x: Steam Workshop

+

Post-launch update. Unified mod discovery, versioning, ratings. One-click install for WASM and signed native mods.

+
+ +
+
+

Episode 2: Age of Kzzkyt

+

2027. Second playable race. New decision-making constraints. Modders craft new AIs for new rules.

+
+
+
+
+ + +
+
+

Ready to Mod?

+

Wishlist on Steam and stay in the loop.

+ +
+
+ + + + + + + diff --git a/drafts/site-c/script.js b/drafts/site-c/script.js new file mode 100644 index 00000000..43a59e3b --- /dev/null +++ b/drafts/site-c/script.js @@ -0,0 +1,49 @@ +// Smooth scroll already handled by CSS scroll-behavior +// Minimal interactivity for polish + +document.addEventListener('DOMContentLoaded', () => { + // CTA buttons - prevent default href + document.querySelectorAll('a[href="#"]').forEach(link => { + link.addEventListener('click', (e) => { + e.preventDefault(); + console.log('CTA clicked:', link.textContent.trim()); + // In a real implementation, these would route to Steam wishlist, docs, etc. + }); + }); + + // Add slight animation on scroll for visible elements + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.animation = 'fadeInUp 0.6s ease-out forwards'; + observer.unobserve(entry.target); + } + }); + }, observerOptions); + + // Observe sections and cards + document.querySelectorAll('section, .feature, .wasm-item, .variant, .stat, .phase').forEach(el => { + observer.observe(el); + }); +}); + +// Add fade-in-up animation +const style = document.createElement('style'); +style.textContent = ` + @keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } + } +`; +document.head.appendChild(style); diff --git a/drafts/site-c/styles.css b/drafts/site-c/styles.css new file mode 100644 index 00000000..d45ed36c --- /dev/null +++ b/drafts/site-c/styles.css @@ -0,0 +1,902 @@ +/* Reset and Variables */ +:root { + --accent: #a78bfa; + --accent-dark: #7c3aed; + --accent-light: #ddd6fe; + --bg: #0f172a; + --bg-secondary: #1e293b; + --bg-tertiary: #334155; + --text: #f1f5f9; + --text-secondary: #cbd5e1; + --text-tertiary: #94a3b8; + --border: #475569; + --success: #34d399; + --warning: #fbbf24; + + --font-mono: 'JetBrains Mono', monospace; + --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + + --spacing-xs: 0.5rem; + --spacing-sm: 1rem; + --spacing-md: 1.5rem; + --spacing-lg: 2rem; + --spacing-xl: 3rem; + --spacing-2xl: 4rem; + + --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: var(--font-sans); + background: linear-gradient(135deg, var(--bg) 0%, var(--bg-secondary) 50%, var(--bg) 100%); + color: var(--text); + line-height: 1.6; + min-height: 100vh; +} + +/* Container */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 var(--spacing-lg); +} + +/* Typography */ +h1, h2, h3, h4, h5, h6 { + font-weight: 700; + letter-spacing: -0.5px; +} + +h1 { + font-size: 3.5rem; + line-height: 1.1; + margin-bottom: var(--spacing-lg); +} + +h2 { + font-size: 2.5rem; + margin-bottom: var(--spacing-lg); + background: linear-gradient(135deg, var(--accent) 0%, var(--accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +h3 { + font-size: 1.5rem; + margin-bottom: var(--spacing-md); + color: var(--text); +} + +p { + color: var(--text-secondary); + margin-bottom: var(--spacing-md); +} + +a { + color: var(--accent); + text-decoration: none; + transition: var(--transition); +} + +a:hover { + color: var(--accent-light); +} + +code { + font-family: var(--font-mono); + font-size: 0.9rem; + background: var(--bg-tertiary); + padding: 0.2rem 0.6rem; + border-radius: 4px; + color: var(--accent-light); +} + +/* Navigation */ +.navbar { + background: rgba(15, 23, 42, 0.8); + backdrop-filter: blur(8px); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 100; +} + +.navbar .container { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--spacing-md) var(--spacing-lg); +} + +.nav-brand { + font-weight: 700; + font-size: 1.3rem; + letter-spacing: -1px; +} + +.logo-text { + margin-right: 0.5rem; + font-size: 1.5rem; +} + +.nav-links { + display: flex; + gap: var(--spacing-lg); + list-style: none; +} + +.nav-links a { + color: var(--text-secondary); + font-size: 0.95rem; + font-weight: 500; + transition: var(--transition); +} + +.nav-links a:hover { + color: var(--accent); +} + +/* Hero Section */ +.hero { + padding: var(--spacing-2xl) var(--spacing-lg); + min-height: 100vh; + display: flex; + align-items: center; + position: relative; + overflow: hidden; +} + +.hero .container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-2xl); + align-items: center; +} + +.hero-content h1 { + background: linear-gradient(135deg, var(--text) 0%, var(--accent) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.hero-tagline { + font-size: 1.3rem; + color: var(--text-secondary); + line-height: 1.5; + max-width: 600px; + margin-bottom: var(--spacing-xl); +} + +.hero-ctas { + display: flex; + gap: var(--spacing-md); + margin-bottom: var(--spacing-xl); +} + +.cta { + padding: var(--spacing-md) var(--spacing-lg); + border-radius: 6px; + font-weight: 600; + font-size: 1rem; + border: 2px solid transparent; + cursor: pointer; + transition: var(--transition); + display: inline-block; + text-align: center; +} + +.cta.primary { + background: var(--accent); + color: var(--bg); + border-color: var(--accent); +} + +.cta.primary:hover { + background: var(--accent-light); + border-color: var(--accent-light); + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(167, 139, 250, 0.3); +} + +.cta.secondary { + background: transparent; + color: var(--accent); + border-color: var(--accent); +} + +.cta.secondary:hover { + background: rgba(167, 139, 250, 0.1); + border-color: var(--accent-light); + color: var(--accent-light); +} + +.hero-meta { + margin-top: var(--spacing-lg); +} + +.hero-meta p { + margin: 0.5rem 0; + color: var(--text-tertiary); + font-size: 0.95rem; +} + +.hero-meta p strong { + color: var(--text-secondary); +} + +.platforms { + display: flex; + gap: var(--spacing-md); + flex-wrap: wrap; +} + +.chip { + display: inline-block; + background: var(--bg-tertiary); + border: 1px solid var(--border); + padding: 0.4rem 0.8rem; + border-radius: 4px; + font-size: 0.85rem; + font-weight: 500; + color: var(--text-secondary); +} + +.hero-visual { + display: flex; + justify-content: center; + align-items: center; +} + +.ai-diagram { + width: 100%; + max-width: 250px; + height: auto; + animation: float 6s ease-in-out infinite; +} + +@keyframes float { + 0%, 100% { transform: translateY(0px); } + 50% { transform: translateY(-20px); } +} + +.svg-text { + font-family: var(--font-mono); + font-size: 11px; + fill: var(--text); + font-weight: 500; +} + +.svg-label { + font-family: var(--font-sans); + font-size: 10px; + fill: var(--text-tertiary); + font-weight: 400; +} + +/* Sections */ +section { + padding: var(--spacing-2xl) var(--spacing-lg); + border-top: 1px solid var(--border); +} + +.section-intro { + font-size: 1.2rem; + color: var(--text-secondary); + max-width: 700px; + margin-bottom: var(--spacing-xl); +} + +/* AI Interface Section */ +.ai-interface { + background: var(--bg-secondary); +} + +.code-block { + background: var(--bg-tertiary); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-lg); + overflow-x: auto; + margin: var(--spacing-xl) 0; +} + +.code-block pre { + margin: 0; + font-family: var(--font-mono); + font-size: 0.9rem; + line-height: 1.6; +} + +.code-block code { + background: none; + padding: 0; + color: var(--text); +} + +.kw { + color: var(--accent); + font-weight: 600; +} + +.typ { + color: var(--accent-light); +} + +.fn { + color: var(--success); +} + +.var { + color: var(--text-secondary); +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: var(--spacing-xl); + margin: var(--spacing-2xl) 0; +} + +.feature { + background: var(--bg); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-lg); + transition: var(--transition); +} + +.feature:hover { + border-color: var(--accent); + box-shadow: 0 8px 24px rgba(167, 139, 250, 0.1); + transform: translateY(-4px); +} + +.feature-icon { + font-size: 2rem; + margin-bottom: var(--spacing-md); +} + +.feature h3 { + color: var(--text); + margin-bottom: var(--spacing-sm); +} + +.feature p { + color: var(--text-tertiary); + font-size: 0.95rem; +} + +/* AI Variants */ +.ai-variants { + margin-top: var(--spacing-2xl); + padding-top: var(--spacing-2xl); + border-top: 1px solid var(--border); +} + +.ai-variants h3 { + margin-bottom: var(--spacing-lg); +} + +.variant-list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: var(--spacing-lg); +} + +.variant { + background: var(--bg); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-lg); +} + +.variant-tag { + display: inline-block; + padding: 0.3rem 0.8rem; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + margin-bottom: var(--spacing-md); + letter-spacing: 0.5px; +} + +.variant-tag.neural { + background: rgba(52, 211, 153, 0.2); + color: var(--success); +} + +.variant-tag.scripted { + background: rgba(251, 191, 36, 0.2); + color: var(--warning); +} + +.variant strong { + display: block; + margin-bottom: var(--spacing-sm); + color: var(--text); + font-size: 1.1rem; +} + +.variant p { + font-size: 0.95rem; + color: var(--text-tertiary); +} + +/* WASM Section */ +.wasm { + background: var(--bg); +} + +.wasm-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: var(--spacing-lg); + margin: var(--spacing-2xl) 0; +} + +.wasm-item { + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-lg); + text-align: center; + transition: var(--transition); +} + +.wasm-item:hover { + border-color: var(--accent); + background: rgba(167, 139, 250, 0.05); +} + +.wasm-icon { + font-size: 2.5rem; + margin-bottom: var(--spacing-md); +} + +.wasm-item h3 { + color: var(--text); + margin-bottom: var(--spacing-sm); +} + +.wasm-item p { + color: var(--text-tertiary); + font-size: 0.95rem; +} + +.wasm-diagram { + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-xl); + margin: var(--spacing-2xl) 0; +} + +.wasm-diagram h3 { + margin-bottom: var(--spacing-lg); +} + +.pipeline-svg { + width: 100%; + max-width: 600px; +} + +/* Native Section */ +.native { + background: var(--bg-secondary); +} + +.native-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-2xl); + margin: var(--spacing-2xl) 0; +} + +.native-text p { + margin-bottom: var(--spacing-md); + color: var(--text-secondary); + line-height: 1.8; +} + +.native-callout { + background: rgba(167, 139, 250, 0.1); + border: 1px solid var(--accent); + border-radius: 8px; + padding: var(--spacing-lg); + margin-top: var(--spacing-lg); +} + +.native-callout p { + margin: 0; + color: var(--text-secondary); +} + +.comparison-table { + width: 100%; + border-collapse: collapse; + background: var(--bg); + border-radius: 8px; + overflow: hidden; + border: 1px solid var(--border); +} + +.comparison-table thead { + background: var(--bg-tertiary); +} + +.comparison-table th { + padding: var(--spacing-md); + text-align: left; + font-weight: 600; + color: var(--text); + border-bottom: 1px solid var(--border); + font-size: 0.95rem; +} + +.comparison-table td { + padding: var(--spacing-md); + border-bottom: 1px solid var(--border); + font-size: 0.95rem; + color: var(--text-secondary); +} + +.comparison-table tbody tr:last-child td { + border-bottom: none; +} + +.comparison-table .check { + color: var(--success); + font-weight: 500; +} + +.comparison-table .x { + color: var(--text-tertiary); +} + +/* Open Source Section */ +.opensource { + background: var(--bg); +} + +.opensource-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-2xl); + margin: var(--spacing-2xl) 0; + align-items: center; +} + +.opensource-box { + background: var(--bg-secondary); + border: 2px solid var(--accent); + border-radius: 8px; + padding: var(--spacing-lg); +} + +.opensource-box h3 { + color: var(--text); + margin-bottom: var(--spacing-md); +} + +.opensource-box p { + color: var(--text-secondary); + margin-bottom: var(--spacing-lg); + line-height: 1.8; +} + +.code-link { + display: block; + background: var(--bg-tertiary); + border: 1px solid var(--border); + padding: var(--spacing-md); + border-radius: 6px; + font-family: var(--font-mono); + font-size: 0.9rem; + color: var(--accent); + transition: var(--transition); + text-align: center; +} + +.code-link:hover { + background: rgba(167, 139, 250, 0.1); + border-color: var(--accent); +} + +.opensource-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--spacing-lg); +} + +.stat { + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-lg); + text-align: center; + transition: var(--transition); +} + +.stat:hover { + border-color: var(--accent); +} + +.stat-value { + display: block; + font-size: 2rem; + font-weight: 700; + color: var(--accent); + margin-bottom: var(--spacing-sm); +} + +.stat-label { + display: block; + font-size: 0.9rem; + color: var(--text-tertiary); + font-weight: 500; +} + +/* Roadmap Section */ +.roadmap { + background: var(--bg-secondary); +} + +.roadmap-timeline { + margin: var(--spacing-2xl) 0; + position: relative; + padding-left: var(--spacing-lg); +} + +.roadmap-timeline::before { + content: ''; + position: absolute; + left: 15px; + top: 0; + bottom: 0; + width: 2px; + background: linear-gradient(180deg, var(--accent) 0%, transparent 100%); +} + +.phase { + position: relative; + margin-bottom: var(--spacing-2xl); + padding-left: var(--spacing-lg); +} + +.phase-marker { + position: absolute; + left: -34px; + top: 0; + width: 32px; + height: 32px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + font-size: 1.2rem; + background: var(--bg); + border: 2px solid var(--border); +} + +.phase-marker.done { + background: var(--success); + border-color: var(--success); + color: var(--bg); +} + +.phase-marker.soon { + background: var(--accent); + border-color: var(--accent); + color: var(--bg); +} + +.phase-marker.future { + background: transparent; + border-color: var(--border); + color: var(--text-tertiary); +} + +.phase h3 { + margin-bottom: var(--spacing-sm); +} + +.phase p { + color: var(--text-tertiary); + font-size: 0.95rem; +} + +/* CTA Section */ +.cta-final { + padding: var(--spacing-2xl) var(--spacing-lg); + text-align: center; + background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-tertiary) 100%); + border-top: 1px solid var(--border); +} + +.cta-final h2 { + margin-bottom: var(--spacing-md); +} + +.cta-final > .container > p { + margin-bottom: var(--spacing-xl); +} + +.final-ctas { + display: flex; + gap: var(--spacing-md); + justify-content: center; + flex-wrap: wrap; +} + +/* Footer */ +.footer { + background: var(--bg); + border-top: 1px solid var(--border); + padding: var(--spacing-2xl) var(--spacing-lg); +} + +.footer .container { + display: grid; + grid-template-columns: 1fr auto; + gap: var(--spacing-2xl); + align-items: start; +} + +.footer-content p { + margin-bottom: var(--spacing-sm); + font-size: 0.95rem; +} + +.footer-content p:first-child { + font-weight: 600; + color: var(--text); +} + +.footer-meta { + color: var(--text-tertiary); + font-size: 0.85rem; +} + +.footer-links { + display: flex; + gap: var(--spacing-lg); +} + +.footer-links a { + color: var(--text-secondary); + font-size: 0.95rem; + transition: var(--transition); +} + +.footer-links a:hover { + color: var(--accent); +} + +/* Responsive */ +@media (max-width: 768px) { + :root { + --spacing-xl: 2rem; + --spacing-2xl: 3rem; + } + + h1 { + font-size: 2.5rem; + } + + h2 { + font-size: 2rem; + } + + h3 { + font-size: 1.3rem; + } + + .navbar .container { + flex-direction: column; + gap: var(--spacing-md); + text-align: center; + } + + .nav-links { + gap: var(--spacing-md); + } + + .hero { + min-height: auto; + padding: var(--spacing-xl) var(--spacing-lg); + } + + .hero .container { + grid-template-columns: 1fr; + gap: var(--spacing-xl); + } + + .hero-ctas { + flex-direction: column; + } + + .cta { + width: 100%; + } + + .native-content { + grid-template-columns: 1fr; + } + + .opensource-content { + grid-template-columns: 1fr; + } + + .opensource-stats { + grid-template-columns: 1fr; + } + + .footer .container { + grid-template-columns: 1fr; + gap: var(--spacing-lg); + } + + .footer-links { + justify-content: center; + } + + .code-block { + overflow-x: auto; + font-size: 0.8rem; + } +} + +@media (max-width: 480px) { + :root { + --spacing-lg: 1.5rem; + } + + h1 { + font-size: 2rem; + } + + h2 { + font-size: 1.5rem; + } + + .container { + padding: 0 var(--spacing-md); + } + + .hero-tagline { + font-size: 1.1rem; + } + + .nav-links { + gap: var(--spacing-sm); + font-size: 0.9rem; + } + + .features-grid, + .wasm-grid, + .variant-list { + grid-template-columns: 1fr; + } + + .cta-final { + padding: var(--spacing-xl) var(--spacing-md); + } + + .final-ctas { + flex-direction: column; + } +}