Download backend/lisp-rs/forge_engine.rs from Snapkitty/snapkitty-clojure-lisp-bridge: direct link, hf CLI and curl.
- Browser
- Download file 17.9 kB
-
https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/backend/lisp-rs/forge_engine.rs
- Command line
-
hf download hf://Snapkitty/snapkitty-clojure-lisp-bridge/backend/lisp-rs/forge_engine.rs
-
curl -L -o forge_engine.rs https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/backend/lisp-rs/forge_engine.rs
17.9 kB
| //! FORGE Generation Engine β Autonomous Environmental Evolution | |
| //! | |
| //! FORGE does not generate terrain. FORGE generates: | |
| //! infrastructure logic, settlement patterns, ecosystem balance, | |
| //! social topology, conflict vectors, economic pressure, architectural identity. | |
| //! | |
| //! When a player says "build a trading post that charges 2% tax" β | |
| //! FORGE constructs the shard, authors the object DNA, writes the behavior rules, | |
| //! patches the economy, and seals the entire act to the WORM chain. | |
| //! No developer wrote this map. FORGE built it. It is now permanent history. | |
| use serde::{Deserialize, Serialize}; | |
| use sha2::{Sha256, Digest}; | |
| use super::object_dna::{ObjectDna, ObjectKind, BehaviorRule}; | |
| use super::world_shard::{WorldShard, ShardKind}; | |
| /// A FORGE generation request β what the world needs built | |
| pub struct ForgeRequest { | |
| pub id: String, | |
| pub intent: String, // raw player/agent intent | |
| pub parsed_kind: GenerationKind, | |
| pub district: String, | |
| pub constraints: Vec<String>, // economic, physical, social constraints | |
| pub requester: String, // player ID or agent name | |
| pub seal: String, | |
| pub ts: u64, | |
| } | |
| pub enum GenerationKind { | |
| Structure, // buildings, walls, roads | |
| Economy, // markets, vaults, banks, tax systems | |
| Ecosystem, // forests, rivers, fauna populations | |
| Social, // community spaces, governance halls | |
| Infrastructure, // roads, bridges, portals between shards | |
| Conflict, // arenas, faction territories, contested zones | |
| Event, // temporary world events β festivals, disasters | |
| } | |
| /// A FORGE generation result β what was built | |
| pub struct ForgeOutput { | |
| pub request_id: String, | |
| pub shard: WorldShard, | |
| pub objects: Vec<ObjectDna>, | |
| pub behavior_script: String, // Lua script for runtime behavior | |
| pub economic_rules: Vec<EconomicRule>, | |
| pub seal: String, | |
| pub worm_id: String, | |
| pub build_ms: u64, | |
| pub ts: u64, | |
| } | |
| /// An economic rule authored by FORGE for a shard | |
| pub struct EconomicRule { | |
| pub id: String, | |
| pub kind: EconomicRuleKind, | |
| pub rate: f64, // tax rate, interest rate, exchange rate | |
| pub condition: String, // when this rule applies | |
| pub beneficiary: String, // who receives the value | |
| pub seal: String, | |
| } | |
| pub enum EconomicRuleKind { | |
| Tax, | |
| Tariff, | |
| Subsidy, | |
| InterestRate, | |
| ExchangeRate, | |
| ResourceCap, | |
| } | |
| /// Settlement emergence pattern β how FORGE decides what to build next | |
| pub struct SettlementPressure { | |
| pub population_density: f64, // drives housing and social infra | |
| pub trade_volume: f64, // drives markets and roads | |
| pub conflict_index: f64, // drives arenas and fortifications | |
| pub resource_scarcity: f64, // drives resource extraction structures | |
| pub cultural_momentum: f64, // drives galleries, schools, temples | |
| } | |
| impl SettlementPressure { | |
| /// Determine what FORGE should build next based on systemic pressure | |
| pub fn highest_priority(&self) -> GenerationKind { | |
| let pressures = [ | |
| (self.population_density, GenerationKind::Social), | |
| (self.trade_volume, GenerationKind::Economy), | |
| (self.conflict_index, GenerationKind::Conflict), | |
| (self.resource_scarcity, GenerationKind::Infrastructure), | |
| (self.cultural_momentum, GenerationKind::Structure), | |
| ]; | |
| pressures.iter() | |
| .max_by(|a, b| a.0.partial_cmp(&b.0).unwrap()) | |
| .map(|(_, k)| k.clone()) | |
| .unwrap_or(GenerationKind::Structure) | |
| } | |
| } | |
| impl ForgeRequest { | |
| pub fn new( | |
| intent: impl Into<String>, | |
| parsed_kind: GenerationKind, | |
| district: impl Into<String>, | |
| requester: impl Into<String>, | |
| ) -> Self { | |
| let ts = Self::now(); | |
| let intent = intent.into(); | |
| let district = district.into(); | |
| let requester = requester.into(); | |
| let mut h = Sha256::new(); | |
| h.update(format!("FORGE-REQ:{:?}:{}:{}:{}", parsed_kind, district, requester, ts).as_bytes()); | |
| let seal = hex::encode(h.finalize()); | |
| let id = format!("FREQ-{}", &seal[..12].to_uppercase()); | |
| Self { id, intent, parsed_kind, district, constraints: vec![], requester, seal, ts } | |
| } | |
| fn now() -> u64 { | |
| std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap_or_default() | |
| .as_millis() as u64 | |
| } | |
| } | |
| /// The FORGE engine β parses intent, constructs shards and objects | |
| pub struct ForgeEngine { | |
| pub generations: Vec<ForgeOutput>, | |
| } | |
| impl ForgeEngine { | |
| pub fn new() -> Self { Self { generations: vec![] } } | |
| /// Parse raw player/agent intent into a structured request | |
| pub fn parse_intent( | |
| &self, | |
| raw_intent: &str, | |
| district: &str, | |
| requester: &str, | |
| ) -> ForgeRequest { | |
| let kind = Self::classify_intent(raw_intent); | |
| ForgeRequest::new(raw_intent, kind, district, requester) | |
| } | |
| /// Execute a FORGE request β build the shard, objects, and rules | |
| pub fn execute(&mut self, req: ForgeRequest) -> ForgeOutput { | |
| let t0 = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap_or_default() | |
| .as_millis() as u64; | |
| let (shard, objects, econ_rules, script) = match req.parsed_kind { | |
| GenerationKind::Economy => self.build_economy(&req), | |
| GenerationKind::Structure => self.build_structure(&req), | |
| GenerationKind::Social => self.build_social(&req), | |
| GenerationKind::Conflict => self.build_conflict(&req), | |
| GenerationKind::Ecosystem => self.build_ecosystem(&req), | |
| GenerationKind::Infrastructure => self.build_infrastructure(&req), | |
| GenerationKind::Event => self.build_event(&req), | |
| }; | |
| let ts = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap_or_default() | |
| .as_millis() as u64; | |
| let build_ms = ts - t0; | |
| let mut h = Sha256::new(); | |
| h.update(format!("FORGE-OUT:{}:{}:{}", req.id, shard.id, ts).as_bytes()); | |
| let seal = hex::encode(h.finalize()); | |
| let worm_id = format!("WORM-FORGE-{}", &seal[..16].to_uppercase()); | |
| let output = ForgeOutput { | |
| request_id: req.id, shard, objects, behavior_script: script, | |
| economic_rules: econ_rules, seal, worm_id, build_ms, ts, | |
| }; | |
| self.generations.push(output.clone()); | |
| output | |
| } | |
| // ββ Generation Routines ββββββββββββββββββββββββββββββββββββββββββββββ | |
| fn build_economy(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| // Parse tax rate from intent if present | |
| let tax_rate = Self::extract_rate(&req.intent, "tax").unwrap_or(0.02); | |
| let mut shard = WorldShard::spawn( | |
| ShardKind::TradingPost, | |
| Self::name_from_intent(&req.intent, "Exchange"), | |
| &req.district, 200, | |
| format!("FORGE built by: {}", req.requester), | |
| ); | |
| // Object: market structure | |
| let mut market = ObjectDna::new(ObjectKind::Economic, "Market Hall"); | |
| market.attributes.insert("trade_volume".into(), 0.0); | |
| market.attributes.insert("tax_rate".into(), tax_rate); | |
| market.forge_rewrite( | |
| "on_trade", | |
| &format!("price > 0"), | |
| &format!("apply_tax({tax_rate}); seal_ledger(); emit_to_vault()"), | |
| ); | |
| // Object: vault | |
| let mut vault = ObjectDna::new(ObjectKind::Economic, "Tax Vault"); | |
| vault.attributes.insert("balance".into(), 0.0); | |
| // Economic rule | |
| let mut h = Sha256::new(); | |
| h.update(format!("TAX:{}:{}", tax_rate, req.ts).as_bytes()); | |
| let rule_seal = hex::encode(h.finalize()); | |
| let econ_rule = EconomicRule { | |
| id: format!("ERULE-{}", &rule_seal[..10].to_uppercase()), | |
| kind: EconomicRuleKind::Tax, | |
| rate: tax_rate, | |
| condition: "every_trade".into(), | |
| beneficiary: req.requester.clone(), | |
| seal: rule_seal, | |
| }; | |
| shard.forge_patch(format!( | |
| "-- FORGE generated economy script\nTAX_RATE = {tax_rate}\n\ | |
| function on_trade(item, price)\n tax = price * TAX_RATE\n\ | |
| ledger:seal(item, price, tax)\n vault:deposit(tax)\nend" | |
| )); | |
| let script = format!( | |
| "-- Sovereign trading post: {}\n-- Tax: {}%\n-- WORM-sealed every trade", | |
| req.intent, tax_rate * 100.0 | |
| ); | |
| (shard, vec![market, vault], vec![econ_rule], script) | |
| } | |
| fn build_structure(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn( | |
| ShardKind::BuildZone, | |
| Self::name_from_intent(&req.intent, "Structure"), | |
| &req.district, 50, | |
| format!("FORGE built by: {}", req.requester), | |
| ); | |
| let building = ObjectDna::new(ObjectKind::Structure, &req.intent); | |
| let script = format!("-- Structure: {}\n-- All state sealed to WORM", req.intent); | |
| shard.forge_patch(&script); | |
| (shard, vec![building], vec![], script) | |
| } | |
| fn build_social(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn(ShardKind::SocialHub, | |
| Self::name_from_intent(&req.intent, "Hub"), &req.district, 150, | |
| format!("FORGE: {}", req.intent)); | |
| let hall = ObjectDna::new(ObjectKind::Structure, "Community Hall"); | |
| let script = "-- Social hub: NPC memory events sealed here\n-- Governance voting enabled".into(); | |
| shard.forge_patch(script); | |
| (shard, vec![hall], vec![], "-- community hub script".into()) | |
| } | |
| fn build_conflict(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn(ShardKind::CombatArena, | |
| Self::name_from_intent(&req.intent, "Arena"), &req.district, 40, | |
| format!("FORGE: {}", req.intent)); | |
| let arena = ObjectDna::new(ObjectKind::Structure, "Combat Arena"); | |
| let script = "-- Combat arena: every kill sealed to weapon DNA + player ledger".into(); | |
| shard.forge_patch(script); | |
| (shard, vec![arena], vec![], "-- combat script".into()) | |
| } | |
| fn build_ecosystem(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn(ShardKind::Wilderness, | |
| Self::name_from_intent(&req.intent, "Wilderness"), &req.district, 500, | |
| format!("FORGE: {}", req.intent)); | |
| let terrain = ObjectDna::new(ObjectKind::NaturalFeature, "Procedural Terrain"); | |
| let script = "-- Ecosystem: resource nodes, fauna population, weather sealed per tick".into(); | |
| shard.forge_patch(script); | |
| (shard, vec![terrain], vec![], "-- ecosystem script".into()) | |
| } | |
| fn build_infrastructure(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn(ShardKind::Portal, | |
| Self::name_from_intent(&req.intent, "Portal"), &req.district, 1000, | |
| format!("FORGE: {}", req.intent)); | |
| let portal = ObjectDna::new(ObjectKind::Portal, "Shard Gate"); | |
| let script = "-- Portal: cross-shard travel point, toll optional, usage sealed to ledger".into(); | |
| shard.forge_patch(script); | |
| (shard, vec![portal], vec![], "-- infrastructure script".into()) | |
| } | |
| fn build_event(&self, req: &ForgeRequest) -> (WorldShard, Vec<ObjectDna>, Vec<EconomicRule>, String) { | |
| let mut shard = WorldShard::spawn(ShardKind::EventSpace, | |
| Self::name_from_intent(&req.intent, "Event"), &req.district, 300, | |
| format!("FORGE event: {}", req.intent)); | |
| let stage = ObjectDna::new(ObjectKind::Structure, "Event Stage"); | |
| let script = "-- Temporary event shard: auto-tears down when players leave".into(); | |
| shard.forge_patch(script); | |
| (shard, vec![stage], vec![], "-- event script".into()) | |
| } | |
| // ββ Helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| fn classify_intent(intent: &str) -> GenerationKind { | |
| let i = intent.to_lowercase(); | |
| if i.contains("tax") || i.contains("market") || i.contains("trade") || i.contains("economy") || i.contains("bank") { | |
| GenerationKind::Economy | |
| } else if i.contains("arena") || i.contains("combat") || i.contains("fight") || i.contains("war") { | |
| GenerationKind::Conflict | |
| } else if i.contains("forest") || i.contains("river") || i.contains("nature") || i.contains("farm") { | |
| GenerationKind::Ecosystem | |
| } else if i.contains("road") || i.contains("bridge") || i.contains("portal") || i.contains("gate") { | |
| GenerationKind::Infrastructure | |
| } else if i.contains("festival") || i.contains("event") || i.contains("celebration") { | |
| GenerationKind::Event | |
| } else if i.contains("hall") || i.contains("community") || i.contains("gather") || i.contains("social") { | |
| GenerationKind::Social | |
| } else { | |
| GenerationKind::Structure | |
| } | |
| } | |
| fn extract_rate(intent: &str, keyword: &str) -> Option<f64> { | |
| let pattern = format!("{}%", keyword); | |
| if let Some(pos) = intent.to_lowercase().find(&pattern) { | |
| let before = &intent[..pos]; | |
| let num_start = before.rfind(|c: char| !c.is_ascii_digit() && c != '.').map(|i| i + 1).unwrap_or(0); | |
| if let Ok(rate) = before[num_start..].parse::<f64>() { | |
| return Some(rate / 100.0); | |
| } | |
| } | |
| // Also check "N% tax" pattern | |
| if intent.to_lowercase().contains(keyword) { | |
| // scan for any number near the keyword | |
| for token in intent.split_whitespace() { | |
| let t = token.trim_end_matches('%'); | |
| if let Ok(v) = t.parse::<f64>() { | |
| if v > 0.0 && v <= 100.0 { | |
| return Some(v / 100.0); | |
| } | |
| } | |
| } | |
| } | |
| None | |
| } | |
| fn name_from_intent(intent: &str, fallback: &str) -> String { | |
| // Use first 3-4 significant words of intent as the name | |
| let words: Vec<&str> = intent.split_whitespace() | |
| .filter(|w| w.len() > 3) | |
| .take(3) | |
| .collect(); | |
| if words.is_empty() { fallback.to_string() } else { words.join(" ") } | |
| } | |
| } | |
| impl Default for ForgeEngine { | |
| fn default() -> Self { Self::new() } | |
| } | |
| mod tests { | |
| use super::*; | |
| fn test_parse_economy_intent() { | |
| let engine = ForgeEngine::new(); | |
| let req = engine.parse_intent( | |
| "Build a trading post that charges 2% tax", | |
| "Downtown", "PLAYER-001", | |
| ); | |
| assert_eq!(req.parsed_kind, GenerationKind::Economy); | |
| } | |
| fn test_forge_builds_economy_shard() { | |
| let mut engine = ForgeEngine::new(); | |
| let req = engine.parse_intent("Build a trading post that charges 2% tax", "Downtown", "PLAYER"); | |
| let output = engine.execute(req); | |
| assert!(!output.shard.id.is_empty()); | |
| assert!(!output.objects.is_empty()); | |
| assert!(!output.economic_rules.is_empty()); | |
| assert_eq!(output.economic_rules[0].kind, EconomicRuleKind::Tax); | |
| assert!((output.economic_rules[0].rate - 0.02).abs() < 0.001); | |
| assert!(!output.worm_id.is_empty()); | |
| assert!(output.worm_id.starts_with("WORM-FORGE-")); | |
| } | |
| fn test_forge_conflict_arena() { | |
| let mut engine = ForgeEngine::new(); | |
| let req = engine.parse_intent("create a combat arena for player tournaments", "Underground", "NEXUS"); | |
| let output = engine.execute(req); | |
| assert_eq!(output.shard.kind, ShardKind::CombatArena); | |
| } | |
| fn test_settlement_pressure_priorities() { | |
| let high_trade = SettlementPressure { | |
| population_density: 0.3, | |
| trade_volume: 0.9, | |
| conflict_index: 0.2, | |
| resource_scarcity: 0.1, | |
| cultural_momentum: 0.4, | |
| }; | |
| assert_eq!(high_trade.highest_priority(), GenerationKind::Economy); | |
| let high_conflict = SettlementPressure { | |
| population_density: 0.2, trade_volume: 0.3, | |
| conflict_index: 0.95, resource_scarcity: 0.1, cultural_momentum: 0.2, | |
| }; | |
| assert_eq!(high_conflict.highest_priority(), GenerationKind::Conflict); | |
| } | |
| } | |