来源信息
- 仓库
- SimHacker/moollm
- 最近来源活动
- 2026年2月9日 21:17
- 检测到的 SKILL.md 语言
- 英语
- 星标
- 60
- Forks
- 5
安装方式
默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。
检查来源文件
决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。
文件资源管理器
5 个文件正在显示 SKILL.md
SKILL.md
来源说明 · 只读预览- name
- runtime
- description
- Dual Python/JavaScript adventure runtimes — always in sync
- allowed-tools
- ["read_file","write_file"]
- tier
- 1
- protocol
- DUAL-RUNTIME
- tags
- ["moollm","runtime","python","javascript","compilation","sync"]
- related
- ["context","adventure","object","expression"]
- adversary
- single-target
# Runtime
> *"Test in Python, deploy to browser. Same semantics, both targets."*
> — Vanessa Freudenberg (memorial voice)
---
## What Is It?
The **Runtime** skill defines the dual Python/JavaScript adventure engines. Both runtimes:
- Execute compiled expressions
- Manage world state
- Process simulation ticks
- Handle events
**CRITICAL:** We ALWAYS generate BOTH `_js` AND `_py` code. Never one without the other.
---
## Why Dual Runtimes?
| Runtime | Purpose |
|---------|---------|
| **Python** | Server-side, testing, LLM tethering, CLI |
| **JavaScript** | Browser, standalone play, offline |
```yaml
# Dual Runtime Architecture
dual_runtime:
source: "YAML"
compiler: "LLM"
outputs:
guard_js: "(world) => ..."
guard_py: "lambda world: ..."
runtimes:
python:
file: "adventure.py"
targets: ["CLI", "Server"]
javascript:
file: "engine.js"
targets: ["Browser", "SPA"]
```
---
## The World Object
Both runtimes implement identical `World` classes:
### Python
```python
class World:
"""Adventure runtime context for Python."""
def __init__(self, adventure_data: dict):
# Standard keys
self.turn = 0
self.timestamp = None
self.adventure = adventure_data
self.player = adventure_data.get('player', {})
self.room = None
self.party = adventure_data.get('party', {})
# Extended keys (set contextually)
self.object = None # During object simulation
self.target = None # During targeted action
self.npc = None # During NPC simulation
# Skill state namespaces
self.skills = DotDict() # world.skills.economy.gold
# INVENTORY
def has(self, item_id: str) -> bool:
return item_id in self.player.get('inventory', [])
def has_tag(self, tag: str) -> bool:
"""Check if player has any item with the given tag."""
for item_id in self.player.get('inventory', []):
item = self.get_object(item_id)
if item and tag in item.get('tags', []):
return True
return False
def find_by_tag(self, tag: str, in_room: bool = True) -> list:
"""Find all objects with the given tag."""
results = []
# Check inventory
for item_id in self.player.get('inventory', []):
item = self.get_object(item_id)
if item and tag in item.get('tags', []):
results.append(item)
# Check current room
if in_room and self.room:
for obj in self.room.get('objects', []):
if tag in obj.get('tags', []):
results.append(obj)
return results
def give(self, item_id: str):
inv = self.player.setdefault('inventory', [])
inv.append(item_id)
def take(self, item_id: str):
inv = self.player.get('inventory', [])
if item_id in inv:
inv.remove(item_id)
# FLAGS
def flag(self, name: str) -> bool:
return self.adventure.get('flags', {}).get(name, False)
def set_flag(self, name: str, value: bool):
flags = self.adventure.setdefault('flags', {})
flags[name] = value
# NARRATIVE
def emit(self, message: str):
self._output_queue.append(message)
def narrate(self, message: str, style: str = "normal"):
self._output_queue.append({'text': message, 'style': style})
# EVENTS
def trigger_event(self, name: str, data: dict = None):
self._event_queue.append({'name': name, 'data': data or {}})
# NAVIGATION
def go(self, destination: str):
self._pending_navigation = destination
def can_go(self, direction: str) -> bool:
exits = self.room.get('exits', {})
return direction in exits
# BUFFS
def has_buff(self, buff_id: str) -> bool:
buffs = self.player.get('buffs', [])
return any(b.get('id') == buff_id for b in buffs)
def add_buff(self, buff: dict):
buffs = self.player.setdefault('buffs', [])
buffs.append(buff)
def remove_buff(self, buff_id: str):
buffs = self.player.get('buffs', [])
self.player['buffs'] = [b for b in buffs if b.get('id') != buff_id]
# EFFECTIVE VALUES (Buff Modification Protocol)
#
# Base value = persistent truth
# Effective value = recalculated each tick
#
# "The base value is truth. The effective value is reality."
#
def reset_effective(self, obj: dict = None):
"""
Reset all effective values to their base values.
Called at the start of each tick.
"""
obj = obj or self.object
if not obj or 'state' not in obj:
return
state = obj['state']
for key in list(state.keys()):
if not key.endswith('_effective'):
effective_key = f"{key}_effective"
state[effective_key] = state[key]
def get_effective(self, obj: dict, prop: str):
"""Get effective value, falling back to base if not set."""
state = obj.get('state', {})
effective_key = f"{prop}_effective"
if effective_key in state:
return state[effective_key]
return state.get(prop)
def modify_effective(self, obj: dict, prop: str, delta):
"""Add delta to effective value."""
state = obj.get('state', {})
effective_key = f"{prop}_effective"
state[effective_key] = state.get(effective_key, state.get(prop, 0)) + delta
def multiply_effective(self, obj: dict, prop: str, factor: float):
"""Multiply effective value by factor."""
state = obj.get('state', {})
effective_key = f"{prop}_effective"
state[effective_key] = state.get(effective_key, state.get(prop, 0)) * factor
# RESILIENCE (SimCity Zone Pattern)
#
# WILL WRIGHT: "If one tile burns but the center survives,
# the zone will eventually rebuild."
#
def ensure_defaults(self, obj: dict = None) -> dict:
"""
Ensure object has its default state values.
Self-initializing: creates state if missing.
Self-healing: clamps invalid values.
"""
obj = obj or self.object
if not obj:
return {}
# Create state if missing
if 'state' not in obj:
obj['state'] = {}
# Merge defaults
defaults = obj.get('defaults', {})
for key, default_val in defaults.items():
if key not in obj['state']:
obj['state'][key] = default_val
return obj['state']
def heal_state(self, obj: dict = None):
"""
Fix inconsistent state values.
- Clamp negative numbers to 0
- Fix logical inconsistencies
"""
state = self.ensure_defaults(obj)
# Clamp numeric values to non-negative
for key, val in list(state.items()):
if isinstance(val, (int, float)) and val < 0:
state[key] = 0
return state
# STATE ACCESS
def get(self, path: str):
"""Get value by dot path: world.get('object.state.fuel')"""
parts = path.split('.')
obj = self
for part in parts:
if isinstance(obj, dict):
obj = obj.get(part)
else:
obj = getattr(obj, part, None)
if obj is None:
return None
return obj
def set(self, path: str, value):
"""Set value by dot path: world.set('object.state.lit', True)"""
parts = path.split('.')
obj = self
for part in parts[:-1]:
if isinstance(obj, dict):
obj = obj.setdefault(part, {})
else:
obj = getattr(obj, part)
if isinstance(obj, dict):
obj[parts[-1]] = value
else:
setattr(obj, parts[-1], value)
```
### JavaScript
```javascript
class World {
/** Adventure runtime context for JavaScript. */
constructor(adventureData) {
// Standard keys
this.turn = 0;
this.timestamp = null;
this.adventure = adventureData;
this.player = adventureData.player || {};
this.room = null;
this.party = adventureData.party || {};
// Extended keys (set contextually)
this.object = null; // During object simulation
this.target = null; // During targeted action
this.npc = null; // During NPC simulation
// Skill state namespaces
this.skills = {}; // world.skills.economy.gold
// Internal queues
this._outputQueue = [];
this._eventQueue = [];
this._pendingNavigation = null;
}
// === INVENTORY ===
has(itemId) {
return (this.player.inventory || []).includes(itemId);
}
hasTag(tag) {
/** Check if player has any item with the given tag. */
for (const itemId of this.player.inventory || []) {
const item = this.getObject(itemId);
if (item && (item.tags || []).includes(tag)) {
return true;
}
}
return false;
}
findByTag(tag, inRoom = true) {
/** Find all objects with the given tag. */
const results = [];
// Check inventory
for (const itemId of this.player.inventory || []) {
const item = this.getObject(itemId);
if (item && (item.tags || []).includes(tag)) {
results.push(item);
}
}
// Check current room
if (inRoom && this.room) {
for (const obj of this.room.objects || []) {
if ((obj.tags || []).includes(tag)) {
results.push(obj);
}
}
}
return results;
}
give(itemId) {
this.player.inventory = this.player.inventory || [];
this.player.inventory.push(itemId);
}
take(itemId) {
const inv = this.player.inventory || [];
const idx = inv.indexOf(itemId);
if (idx > -1) inv.splice(idx, 1);
}
// === FLAGS ===
flag(name) {
return (this.adventure.flags || {})[name] || false;
}
setFlag(name, value) {
this.adventure.flags = this.adventure.flags || {};
this.adventure.flags[name] = value;
}
// === NARRATIVE ===
emit(message) {
this._outputQueue.push(message);
}
narrate(message, style = "normal") {
this._outputQueue.push({ text: message, style });
}
// === EVENTS ===
triggerEvent(name, data = {}) {
this._eventQueue.push({ name, data });
}
// === NAVIGATION ===
go(destination) {
this._pendingNavigation = destination;
}
canGo(direction) {
const exits = this.room?.exits || {};
return direction in exits;
}
// === BUFFS ===
hasBuff(buffId) {
const buffs = this.player.buffs || [];
return buffs.some(b => b.id === buffId);
}
addBuff(buff) {
this.player.buffs = this.player.buffs || [];
this.player.buffs.push(buff);
}
removeBuff(buffId) {
const buffs = this.player.buffs || [];
this.player.buffs = buffs.filter(b => b.id !== buffId);
}
在 GitHub 查看这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看