{"id":27607908,"url":"https://github.com/benallfree/vibescale","last_synced_at":"2025-04-22T22:17:32.002Z","repository":{"id":287610794,"uuid":"965266534","full_name":"benallfree/vibescale","owner":"benallfree","description":"Serverless MMO for your next vibegame","archived":false,"fork":false,"pushed_at":"2025-04-15T21:21:44.000Z","size":2381,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-22T22:17:25.130Z","etag":null,"topics":["game-development","game-server","gamedev","mmo","realtime","serverless","websocket"],"latest_commit_sha":null,"homepage":"https://vibescale.benallfree.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benallfree.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-12T19:23:37.000Z","updated_at":"2025-04-19T03:28:15.000Z","dependencies_parsed_at":"2025-04-12T20:38:53.133Z","dependency_job_id":null,"html_url":"https://github.com/benallfree/vibescale","commit_stats":null,"previous_names":["benallfree/vibescale"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benallfree%2Fvibescale","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benallfree%2Fvibescale/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benallfree%2Fvibescale/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benallfree%2Fvibescale/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benallfree","download_url":"https://codeload.github.com/benallfree/vibescale/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250331819,"owners_count":21413103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-development","game-server","gamedev","mmo","realtime","serverless","websocket"],"created_at":"2025-04-22T22:17:30.505Z","updated_at":"2025-04-22T22:17:31.658Z","avatar_url":"https://github.com/benallfree.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌊 Vibescale\n\nA lightweight TypeScript client for building multiplayer games with Vibescale. vibescale.benallfree.com provides real-time multiplayer state synchronization with automatic reconnection handling and built-in debugging tools.\n\n## Features\n\n- 🚀 **Instant Setup**: No server installation required\n- 🌐 **Serverless Architecture**: Built on Cloudflare Workers\n- 🔄 **Real-time Sync**: Low-latency state synchronization with automatic reconnection\n- 🎮 **Game-Ready**: Optimized for multiplayer games with built-in state change detection\n- 🔒 **Secure**: Built-in security and data validation\n- 🎯 **Type-Safe**: Full TypeScript support with generics\n- ⚡ **High Performance**: Efficient state updates using Immer and intelligent change detection\n- 🛠️ **Debug Tools**: Built-in debug panel for development\n\n## Installation\n\n```bash\n# Using npm\nnpm install vibescale\n\n# Using yarn\nyarn add vibescale\n\n# Using bun\nbun add vibescale\n```\n\n## Quick Start\n\n```typescript\nimport { createRoom, RoomEventType } from 'vibescale'\n\n// Create and connect to a room\nconst room = createRoom('my-game', {\n  endpoint: 'https://your-server.com', // Optional, defaults to https://vibescale.benallfree.com/\n})\n\n// Connect to the room\nroom.connect()\n\n// Handle connection events\nroom.on(RoomEventType.Connected, () =\u003e {\n  console.log('Connected to room')\n})\n\n// Update player state\nroom.mutatePlayer((player) =\u003e {\n  player.position = { x: 10, y: 5, z: 0 }\n  player.rotation = { x: 0, y: Math.PI / 2, z: 0 }\n})\n```\n\n## Core Concepts\n\n### Player State\n\nEvery player has base fields and optional custom state:\n\n```typescript\n// Base fields included automatically\ntype BasePlayerFields = {\n  id: PlayerId // Unique player identifier\n  position: Vector3 // 3D position in world space\n  rotation: Vector3 // 3D rotation in radians\n  color: string // Server-assigned color\n  username: string // Player username\n  isLocal: boolean // Whether this is the local player\n  isConnected: boolean // Connection status\n}\n\n// Add custom state by extending PlayerBase\nimport type { PlayerBase } from 'vibescale'\n\ntype Player = PlayerBase\u003c{\n  health: number\n  speed: number\n  powerups: string[]\n}\u003e\n\nconst room = createRoom\u003cPlayer\u003e('my-game')\n\nroom.mutatePlayer((player) =\u003e {\n  // Base fields accessed directly\n  player.position = { x: 10, y: 5, z: 0 }\n  player.rotation = { x: 0, y: Math.PI / 2, z: 0 }\n\n  // Custom fields accessed through state\n  player.state.health = 100\n  player.state.speed = 5\n  player.state.powerups = ['shield', 'boost']\n})\n```\n\n### Event System\n\n```typescript\n// Connection events\nroom.on(RoomEventType.Connected, () =\u003e {\n  console.log('Connected to room')\n})\n\nroom.on(RoomEventType.Disconnected, () =\u003e {\n  console.log('Disconnected from room')\n})\n\n// Player events\nroom.on(RoomEventType.PlayerJoined, (player) =\u003e {\n  console.log('Player joined:', player.id)\n  console.log('Server color:', player.server.color)\n})\n\nroom.on(RoomEventType.PlayerLeft, (player) =\u003e {\n  console.log('Player left:', player.id)\n})\n\nroom.on(RoomEventType.PlayerUpdated, (player) =\u003e {\n  console.log('Player updated:', player.id)\n  console.log('State:', player.state)\n})\n```\n\n### State Change Detection\n\n```typescript\nimport { createRoom, hasSignificantStateChange, type StateChangeDetectorFn } from 'vibescale'\n\n// Custom state change detector\nconst myDetector: StateChangeDetectorFn\u003cPlayer\u003e = (current, next) =\u003e {\n  return (\n    hasSignificantStateChange(current, next) || // Check position/rotation\n    Math.abs(current.state.health - next.state.health) \u003e 5 // Check custom state\n  )\n}\n\nconst room = createRoom\u003cPlayer\u003e('my-game', {\n  stateChangeDetectorFn: myDetector,\n})\n```\n\n### Debug Panel\n\n```typescript\nimport { DebugPanel } from 'vibescale/debug'\n\n// Add to your UI\ndocument.body.appendChild(DebugPanel())\n```\n\nFeatures:\n\n- Real-time player position visualization (radar view)\n- Player list with state inspection\n- WebSocket message logging\n- Connection status monitoring\n- Manual player state manipulation\n- Automatic wandering simulation for testing\n\n## Advanced Topics\n\n### Design Philosophy\n\nVibescale acts as the authoritative source of truth for all player states in your multiplayer game. This means that all player state updates are managed and synchronized through Vibescale, ensuring consistency across all connected clients.\n\n### Connection Handling\n\nRoom connections are completely ephemeral. Disconnecting and reconnecting will produce a new player ID, and none of the old data should be trusted. Each connection is treated as a fresh start - there is no session persistence between connections.\n\nThis design enables:\n\n- Clean state management without stale data\n- Automatic cleanup of disconnected players\n- Simplified reconnection logic\n- No need for complex session management\n\n## API Reference\n\n### Room Creation\n\n```typescript\nfunction createRoom\u003cTPlayer extends PlayerBase\u003e(roomName: string, options?: RoomOptions\u003cTPlayer\u003e): Room\u003cTPlayer\u003e\n\ntype RoomOptions\u003cTPlayer extends PlayerBase\u003e = {\n  endpoint?: string // Custom server URL (default: https://vibescale.benallfree.com/)\n  stateChangeDetectorFn?: StateChangeDetectorFn\u003cTPlayer\u003e // Custom state change detection\n}\n```\n\n### Room Interface\n\n```typescript\ntype Room\u003cTPlayer extends PlayerBase\u003e = {\n  // Event handling\n  on(event: RoomEventType, handler: Function): void\n  off(event: RoomEventType, handler: Function): void\n\n  // Player management\n  getPlayer(id: PlayerId): TPlayer | null\n  getLocalPlayer(): TPlayer | null\n  mutatePlayer(mutator: (player: TPlayer) =\u003e void): void\n\n  // Room information\n  getRoomId(): string\n  isConnected(): boolean\n  getEndpointUrl(): string\n\n  // Connection management\n  connect(): void\n  disconnect(): void\n}\n```\n\n### Events\n\n```typescript\nenum RoomEventType {\n  // Core events\n  Connected = 'connected',\n  Disconnected = 'disconnected',\n  Error = 'error',\n\n  // Player events\n  PlayerJoined = 'player:joined',\n  PlayerLeft = 'player:left',\n  PlayerUpdated = 'player:updated',\n  PlayerError = 'player:error',\n\n  // WebSocket events\n  WebSocketInfo = 'websocket:info',\n  Rx = 'rx',\n  Tx = 'tx',\n  Any = '*',\n}\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenallfree%2Fvibescale","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenallfree%2Fvibescale","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenallfree%2Fvibescale/lists"}