Build generalist agents for 3D open worlds using vision-language models with human-like interaction patterns and adaptive reasoning—achieving zero-shot transfer across games without fine-tuning through pixel-level perception and high-frequency action generation.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Build generalist agents for 3D open worlds using vision-language models with human-like interaction patterns and adaptive reasoning—achieving zero-shot transfer across games without fine-tuning through pixel-level perception and high-frequency action generation.
Build Generalist Agents for Open-World 3D Environments
Game-playing agents typically require game-specific training or scripted logic. Lumine demonstrates that pretrained vision-language models can play complex 3D open-world games by mimicking human interaction patterns: processing visual frames at 5 Hz, generating keyboard-mouse actions at 30 Hz, and adaptively invoking reasoning only when necessary. A single agent trained on one game transfers zero-shot to others without fine-tuning.
The approach completes five-hour story sequences on par with human efficiency, establishing a concrete step toward generalist embodied agents for open-ended environments.
Core Concept
Lumine treats game-playing as a straightforward vision-to-action problem: given pixels, generate human-like actions (keyboard/mouse). The key innovations are:
Human-like interaction frequency - Process at 5 Hz (human perception) for perception but generate actions at 30 Hz (motor frequency)
Adaptive reasoning - Invoke chain-of-thought only when needed (complex decisions), not constantly
Zero-shot transfer - Train once on one game; use directly on others with no game-specific tuning
This approach relies on strong vision-language models' inherent understanding of physics, game mechanics, and strategy—learned during general pretraining.
Architecture Overview
Vision Encoder: Processes game frames to understand state and environment
Perception Buffer: Maintains frame history for context (last 4-5 frames at 5 Hz)
Reasoning Module: VLM chain-of-thought for complex decisions (adaptive invocation)
Action Generator: Converts reasoning to keyboard/mouse commands
Action Executor: Sends actions to game at 30 Hz motor frequency
Adaptive Control: Routes between reactive (fast) and deliberative (slow) modes
Implementation Steps
Step 1: Frame Capture and Perception Pipeline
Capture game frames and feed them to vision-language model.
"""
Args:
game_process: Handle to running game process
perception_freq: Perception frequency (Hz), typically 5
frame_size: Resolution to capture at
"""
Decide when to invoke chain-of-thought reasoning vs. reactive response.
classAdaptiveReasoningModule:
"""
Routes between fast reactive actions and slow reasoning-based actions.
"""def__init__(self, vlm, reasoning_threshold: float = 0.3):
"""
Args:
vlm: Vision-language model (e.g., GPT-4o, Claude)
reasoning_threshold: Confidence below which triggers reasoning
"""self.vlm = vlm
self.reasoning_threshold = reasoning_threshold
defanalyze_game_state(self, frame: np.ndarray) -> Dict[str, Any]:
"""
Quick analysis of current game state without full reasoning.
Args:
frame: Current game frame
Returns:
analysis: {situation, confidence, needs_reasoning}
"""# Fast perception-only prompt (no reasoning)
prompt = f"""Analyze this game screenshot briefly:
What is the player's immediate situation?
- Location/context in 1-2 words
- Immediate threat level (none/low/medium/high)
Keep response brief (under 20 tokens)."""
response = self.vlm.generate(
prompt, frame=frame, max_tokens=50,
temperature=0.0# Deterministic for speed
)
# Parse response
threat_level = self._parse_threat_level(response)
confidence = self._estimate_confidence(response)
needs_reasoning = threat_level == 'high'or confidence < self.reasoning_threshold
return {
'situation': response,
'threat_level': threat_level,
'confidence': confidence,
'needs_reasoning': needs_reasoning
}
definvoke_reasoning(self, frame: np.ndarray, frame_history: List[np.ndarray],
situation: str) -> str:
"""
Invoke full chain-of-thought reasoning for complex decisions.
Args:
frame: Current frame
frame_history: Recent frame history for context
situation: Quick situation analysis
Returns:
reasoning: Chain-of-thought explanation
"""
prompt = f"""You are playing a complex 3D action RPG. Current situation:
{situation}
Given the game state in these screenshots, analyze:
1. What is happening in the game world?
2. What are the major threats/opportunities?
3. What is the optimal strategy for the next 5 seconds?
4. What specific controls should be executed?
Provide detailed reasoning."""# Use frame history for temporal context
reasoning = self.vlm.generate(
prompt,
frames=frame_history,
max_tokens=500,
temperature=0.5
)
return reasoning
def_parse_threat_level(self, response: str) -> str:
"""Extract threat level from response."""
lower = response.lower()
if'high'in lower:
return'high'elif'medium'in lower:
return'medium'elif'low'in lower:
return'low'else:
return'none'def_estimate_confidence(self, response: str) -> float:
"""Estimate model confidence from response uncertainty."""# Heuristic: presence of uncertainty words
uncertain_words = ['maybe', 'unclear', 'hard to tell', 'uncertain']
uncertainty_count = sum(1for word in uncertain_words
if word in response.lower())
confidence = max(0.0, 1.0 - 0.2 * uncertainty_count)
return confidence
Step 3: Action Generation and Execution
Convert reasoning to keyboard/mouse commands.
import pydirectinput # For sending inputs to Windows gamesclassActionGenerator:
"""
Converts VLM reasoning to game actions.
"""def__init__(self, action_freq: int = 30):
"""
Args:
action_freq: Action frequency (Hz), typically 30 (motor frequency)
"""self.action_freq = action_freq
self.action_interval = 1.0 / action_freq
self.last_action_time = 0# Key mapping: action names to keyboard keysself.key_map = {
'move_forward': 'w',
'move_back': 's',
'move_left': 'a',
'move_right': 'd',
'jump': 'space',
'crouch': 'ctrl',
'interact': 'e',
'attack': 'mouse1',
'special': 'q',
'inventory': 'i',
}
defparse_reasoning_to_actions(self, reasoning: str) -> List[str]:
"""
Extract action commands from reasoning text.
Args:
reasoning: Chain-of-thought explanation
Returns:
actions: List of action codes (e.g., ['move_forward', 'attack'])
"""
actions = []
# Simple parsing: look for action mentions in reasoning
reasoning_lower = reasoning.lower()
action_keywords = {
'move forward': 'move_forward',
'move_forward': 'move_forward',
'move back': 'move_back',
'move left': 'move_left',
'move right': 'move_right',
'jump': 'jump',
'crouch': 'crouch',
'interact': 'interact',
'attack': 'attack',
'cast': 'special',
'inventory': 'inventory',
}
for keyword, action in action_keywords.items():
if keyword in reasoning_lower:
if action notin actions:
actions.append(action)
return actions if actions else ['wait']
defexecute_actions(self, actions: List[str], duration: float = 0.1):
"""
Send action commands to game.
Args:
actions: List of actions to execute
duration: How long to hold each action
"""
current_time = time.time()
# Throttle to action frequencyif current_time - self.last_action_time < self.action_interval:
returnfor action in actions:
if action == 'wait':
continue
key = self.key_map.get(action)
if key:
if action.startswith('move_') or action in ['jump', 'crouch']:
# Hold movement keys
pydirectinput.press(key)
time.sleep(duration)
pydirectinput.release(key)
else:
# Toggle actions
pydirectinput.press(key)
time.sleep(0.05)
pydirectinput.release(key)
self.last_action_time = current_time
Step 4: Game Agent Main Loop
Integrate perception, reasoning, and action generation into agent loop.
classLumineGameAgent:
"""
Generalist game-playing agent for open-world 3D games.
"""def__init__(self, game_process, vlm):
"""
Args:
game_process: Handle to running game
vlm: Vision-language model (GPT-4o, Claude, etc.)
"""self.game = game_process
self.vlm = vlm
self.perception = PerceptionPipeline(game_process, perception_freq=5)
self.reasoning = AdaptiveReasoningModule(vlm)
self.actions = ActionGenerator(action_freq=30)
self.episode_steps = 0self.reasoning_invocations = 0defrun_episode(self, max_steps: int = 10000):
"""
Run game episode with agent control.
Args:
max_steps: Maximum steps before episode ends
"""print("Starting game episode...")
start_time = time.time()
for step inrange(max_steps):
# Step 1: Perception (5 Hz)
perception_obs = self.perception.get_perception_observation()
if perception_obs isNone:
continue# Not enough time passed
frame = perception_obs['current_frame']
frame_history = perception_obs['frame_history']
# Step 2: Analyze game state (fast)
state_analysis = self.reasoning.analyze_game_state(frame)
# Step 3: Decide on action (adaptive)if state_analysis['needs_reasoning']:
self.reasoning_invocations += 1
reasoning_output = self.reasoning.invoke_reasoning(
frame, frame_history, state_analysis['situation']
)
else:
# Use fast heuristic response
reasoning_output = state_analysis['situation']
# Step 4: Generate actions
action_list = self.actions.parse_reasoning_to_actions(reasoning_output)
# Step 5: Execute actions (30 Hz)self.actions.execute_actions(action_list, duration=0.05)
self.episode_steps += 1# Optional: check for episode terminationifself._check_episode_complete():
print(f"Episode complete in {self.episode_steps} steps")
break# Progress reportif (step + 1) % 100 == 0:
elapsed = time.time() - start_time
print(f"Step {step + 1}: {elapsed:.1f}s elapsed, "f"{self.reasoning_invocations} reasonings")
def_check_episode_complete(self) -> bool:
"""Check if current objective is complete."""# Game-specific check: look for completion UI# For now, return False (continue playing)returnFalse
Practical Guidance
When to Use Lumine Approach:
Complex 3D game environments (VLMs understand physics and strategy)
Scenarios allowing long-horizon episodes (minutes to hours)
Games where zero-shot transfer is valuable (no fine-tuning per game)
When NOT to Use:
Fast-paced arcade games (latency from VLM inference problematic)
Games requiring frame-perfect timing (5 Hz perception insufficient)
Fully open-ended exploration (no clear objectives)
Hyperparameters and Configuration:
Perception frequency: 5 Hz for most games; increase to 10 Hz for fast-paced games
Action frequency: 30 Hz (standard game input frequency); match game engine updates
Reasoning threshold: 0.3-0.5 (trigger reasoning when uncertain)
Reasoning invocation frequency: ~10% of steps (too frequent = latency, too rare = poor decisions)
Pitfalls to Avoid:
Latency sensitivity - VLM inference takes 2-5 seconds; plan ahead rather than react immediately
Input buffering - Queue actions during reasoning latency; don't let agent freeze
Frame processing overhead - Compress/resize frames; avoid loading full resolution
Game-specific skills - Some games have unique mechanics; agent needs examples or adaptation