Skip to main content
Glama
tile.repo.ts6.21 kB
import Database from 'better-sqlite3'; import { Tile, TileSchema } from '../../schema/tile.js'; export class TileRepository { constructor(private db: Database.Database) { } create(tile: Tile): void { const validTile = TileSchema.parse(tile); const stmt = this.db.prepare(` INSERT INTO tiles (id, world_id, x, y, biome, elevation, moisture, temperature) VALUES (@id, @worldId, @x, @y, @biome, @elevation, @moisture, @temperature) `); stmt.run({ id: validTile.id, worldId: validTile.worldId, x: validTile.x, y: validTile.y, biome: validTile.biome, elevation: validTile.elevation, moisture: validTile.moisture, temperature: validTile.temperature, }); } /** * Create multiple tiles in a single transaction. * Uses prepared statement batching for optimal performance during worldgen. * * @param tiles - Array of tiles to create * @returns Number of tiles created * * @example * // Create 10,000 tiles from worldgen data * const tiles = []; * for (let y = 0; y < 100; y++) { * for (let x = 0; x < 100; x++) { * tiles.push({ * id: `tile-${x}-${y}`, * worldId: 'world-1', * x, y, * biome: biomes[y][x], * elevation: elevation[y * 100 + x], * moisture: moisture[y * 100 + x] / 100, * temperature: temperature[y * 100 + x] * }); * } * } * tileRepo.createBatch(tiles); // ~50x faster than individual inserts */ createBatch(tiles: Tile[]): number { if (tiles.length === 0) return 0; const stmt = this.db.prepare(` INSERT INTO tiles (id, world_id, x, y, biome, elevation, moisture, temperature) VALUES (@id, @worldId, @x, @y, @biome, @elevation, @moisture, @temperature) `); const insertMany = this.db.transaction((tilesToInsert: Tile[]) => { let count = 0; for (const tile of tilesToInsert) { const validTile = TileSchema.parse(tile); stmt.run({ id: validTile.id, worldId: validTile.worldId, x: validTile.x, y: validTile.y, biome: validTile.biome, elevation: validTile.elevation, moisture: validTile.moisture, temperature: validTile.temperature, }); count++; } return count; }); return insertMany(tiles); } /** * Create tiles from worldgen data arrays efficiently. * Directly maps array indices to tile coordinates. * * @param worldId - World ID * @param width - World width * @param height - World height * @param biomes - 2D biome array [y][x] * @param elevation - Flat elevation array (y * width + x) * @param moisture - Flat moisture array (y * width + x), values 0-100 * @param temperature - Flat temperature array (y * width + x) * @param idPrefix - Optional ID prefix (default: 'tile') * @returns Number of tiles created */ createFromWorldgen( worldId: string, width: number, height: number, biomes: string[][], elevation: Uint8Array | number[], moisture: Uint8Array | number[], temperature: Int8Array | number[], idPrefix: string = 'tile' ): number { const stmt = this.db.prepare(` INSERT INTO tiles (id, world_id, x, y, biome, elevation, moisture, temperature) VALUES (@id, @worldId, @x, @y, @biome, @elevation, @moisture, @temperature) `); const insertAll = this.db.transaction(() => { let count = 0; for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const idx = y * width + x; stmt.run({ id: `${idPrefix}-${worldId}-${x}-${y}`, worldId, x, y, biome: biomes[y][x], elevation: elevation[idx], moisture: moisture[idx] / 100, // Convert 0-100 to 0-1 temperature: temperature[idx], }); count++; } } return count; }); return insertAll(); } /** * Delete all tiles for a world (useful before regenerating) */ deleteByWorldId(worldId: string): number { const stmt = this.db.prepare('DELETE FROM tiles WHERE world_id = ?'); const result = stmt.run(worldId); return result.changes; } findByCoordinates(worldId: string, x: number, y: number): Tile | null { const stmt = this.db.prepare('SELECT * FROM tiles WHERE world_id = ? AND x = ? AND y = ?'); const row = stmt.get(worldId, x, y) as TileRow | undefined; if (!row) return null; return TileSchema.parse({ id: row.id, worldId: row.world_id, x: row.x, y: row.y, biome: row.biome, elevation: row.elevation, moisture: row.moisture, temperature: row.temperature, }); } findByWorldId(worldId: string): Tile[] { const stmt = this.db.prepare('SELECT * FROM tiles WHERE world_id = ?'); const rows = stmt.all(worldId) as TileRow[]; return rows.map((row) => TileSchema.parse({ id: row.id, worldId: row.world_id, x: row.x, y: row.y, biome: row.biome, elevation: row.elevation, moisture: row.moisture, temperature: row.temperature, }) ); } } interface TileRow { id: string; world_id: string; x: number; y: number; biome: string; elevation: number; moisture: number; temperature: number; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server