RPG Level Generator
RPG Level Generator: AI-Powered Game Design
Section titled “RPG Level Generator: AI-Powered Game Design”Build a dynamic RPG level generator using LLMs and Jac’s by llm syntax.
Time: 30 minutes Level: Advanced
What You’ll Build
Section titled “What You’ll Build”An AI-powered system that:
- Generates balanced, progressively challenging game levels
- Creates detailed maps with walls, enemies, and obstacles
- Scales difficulty automatically as players progress
- Produces playable ASCII map visualizations
Why This Example?
Section titled “Why This Example?”This example showcases:
| Concept | How It’s Used |
|---|---|
| byLLM | AI generates level configurations and maps |
| Structured Types | Objects guide AI understanding |
| Progressive Systems | Difficulty curves and variety |
| Practical Output | AI data becomes usable game content |
Prerequisites
Section titled “Prerequisites”pip install byllmexport OPENAI_API_KEY="your-key"Key concepts used:
| Concept | Where to Learn |
|---|---|
by llm() | byLLM Quickstart |
obj structured types | Structured Outputs, Part 2 |
enum types | Part 2: Add AI |
Data Structures
Section titled “Data Structures”The key to AI-powered generation is well-defined types. The LLM understands these structures and generates appropriate values.
Position and Walls
Section titled “Position and Walls”obj Position { has x: int; has y: int;}
obj Wall { has start_pos: Position; has end_pos: Position;}Level Configuration
Section titled “Level Configuration”obj Level { has name: str; has difficulty: int; has width: int; has height: int; has num_wall: int; has num_enemies: int; has time_countdown: int; has n_retries_allowed: int;}Map Layout
Section titled “Map Layout”obj Map { has level: Level; has walls: list[Wall]; has small_obstacles: list[Position]; has enemies: list[Position]; has player_pos: Position;}AI-Powered Generation
Section titled “AI-Powered Generation”The magic happens with by llm():
import from byllm.lib { Model }
glob llm = Model(model_name="gpt-4o", verbose=True);
obj LevelManager { has current_level: int = 0; has current_difficulty: int = 1; has prev_levels: list[Level] = []; has prev_level_maps: list[Map] = [];
"""Generate a new level configuration based on difficulty and history.""" def create_next_level( last_levels: list[Level], difficulty: int, level_width: int, level_height: int ) -> Level by llm();
"""Generate a detailed map for a given level.""" def create_next_map(level: Level) -> Map by llm();}Key insight: The AI automatically understands:
- Previous levels (to ensure variety)
- Difficulty scaling
- Spatial constraints (width, height)
- Object relationships (Map contains Level)
Level Flow Management
Section titled “Level Flow Management”def get_next_level() -> tuple[Level, Map] { self.current_level += 1;
# Keep only last 3 levels for context if len(self.prev_levels) > 3 { self.prev_levels.pop(0); self.prev_level_maps.pop(0); }
# AI generates the level new_level = self.create_next_level( self.prev_levels, self.current_difficulty, 20, 20 # 20x20 grid ); self.prev_levels.append(new_level);
# AI generates the map new_level_map = self.create_next_map(new_level); self.prev_level_maps.append(new_level_map);
# Increase difficulty every 2 levels if self.current_level % 2 == 0 { self.current_difficulty += 1; }
return (new_level, new_level_map);}Map Visualization
Section titled “Map Visualization”Convert AI-generated maps to ASCII:
def get_map(map: Map) -> list[str] { # Initialize empty grid tiles = [['.' for _ in range(map.level.width)] for _ in range(map.level.height)];
# Place walls for wall in map.walls { for x in range(wall.start_pos.x, wall.end_pos.x + 1) { for y in range(wall.start_pos.y, wall.end_pos.y + 1) { tiles[y-1][x-1] = 'B'; } } }
# Place obstacles for obs in map.small_obstacles { tiles[obs.y-1][obs.x-1] = 'B'; }
# Place enemies for enemy in map.enemies { tiles[enemy.y-1][enemy.x-1] = 'E'; }
# Place player tiles[map.player_pos.y-1][map.player_pos.x-1] = 'P';
# Add borders tiles = [['B'] + row + ['B'] for row in tiles]; border = ['B' for _ in range(map.level.width + 2)]; tiles = [border] + tiles + [border];
return [''.join(row) for row in tiles];}Symbols:
.= Empty spaceB= Block/WallE= EnemyP= Player start
Testing the Generator
Section titled “Testing the Generator”# test_generator.jacimport from level_manager { LevelManager }
with entry { manager = LevelManager();
print("Generating 3 AI-powered levels...\n");
for i in range(3) { (level, map_obj) = manager.get_next_level(); visual_map = manager.get_map(map_obj);
print(f"=== LEVEL {i+1} ==="); print(f"Difficulty: {level.difficulty}"); print(f"Enemies: {level.num_enemies}"); print(f"Walls: {level.num_wall}"); print("Map:"); for row in visual_map { print(row); } print("\n"); }}Run it:
jac test_generator.jacSample Output
Section titled “Sample Output”=== LEVEL 1 ===Difficulty: 1Enemies: 2Walls: 3Map:BBBBBBBBBBBBBBBBBBBBBBB....................BB.....B..............BB....................BB........E...........BB....................BB..........P.........BB....................BB.E..................BB....................BBBBBBBBBBBBBBBBBBBBBBBEach run produces different layouts as the AI creates unique levels.
How It Works
Section titled “How It Works”- Structured Types -
LevelandMapobjects define what the AI generates - Historical Context - Previous levels prevent repetition
- Difficulty Scaling - Increases every 2 levels
- Spatial Constraints - Width/height guide placement
- AI Creativity - LLM handles the actual creative work
Extension Ideas
Section titled “Extension Ideas”- More object types - Treasure, power-ups, keys, doors
- Different terrain - Water, lava, grass tiles
- Boss levels - Special every 5th level
- Player stats - Health, damage, speed progression
- Theme variations - Dungeon, forest, castle themes
Full Source Code
Section titled “Full Source Code”- RPG Game Source
- Fantasy Trading Game - Similar patterns
Key Takeaways
Section titled “Key Takeaways”- Types guide AI - Well-defined objects lead to better generation
by llmis declarative - Describe what you want, not how- Context matters - Pass history and constraints for variety
- Practical output - Convert AI data to usable formats
Next Examples
Section titled “Next Examples”- EmailBuddy - AI-powered email assistant
- LittleX - Social media platform