bonktools 2.0.1 โ†’ 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,551 +1,262 @@
1
- # ๐ŸŽฎ BonkTools v2.0
1
+ # BonkBot.js
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/bonktools.svg)](https://www.npmjs.com/package/bonktools)
4
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ BonkBot is a JavaScript library for creating bots for the web game [Bonk.io](https://bonk.io). It provides an easy way to create custom bots that can automate various actions within the game. With BonkBot, you can interact with the game's websocket protocol easily, chat with other players, and perform actions such as joining and leaving rooms.
6
4
 
7
- > Advanced Bonk.io bot library with physics simulation and game state management
5
+ ### V4 Alpha, report any issues/bugs in the issues tab
8
6
 
9
- BonkTools is a powerful TypeScript library for creating automated bots for Bonk.io. Unlike other libraries, BonkTools includes a **Box2D physics simulator** that allows you to detect game events like player deaths, round endings, and collisions in real-time.
7
+ ### Newer NodeJS versions may encounter issues, node 18 and 16 are confirmed working
10
8
 
11
- ## โœจ Features
9
+ ## Installation
12
10
 
13
- - ๐Ÿ”Œ **WebSocket Connection Management** - Stable connection with automatic reconnection
14
- - โšก **Box2D Physics Simulation** - Replicate game physics locally to detect events
15
- - ๐ŸŽฏ **Game State Tracking** - Full awareness of game state (rounds, scores, players)
16
- - ๐ŸŽญ **Event-Driven Architecture** - React to any game event with TypeScript events
17
- - ๐Ÿ› ๏ธ **Room Management** - Create, join, and manage rooms programmatically
18
- - ๐Ÿ‘ฅ **Player Management** - Track all players, their states, and positions
19
- - ๐ŸŽช **Host Controls** - Start/stop games, kick players, change settings
20
- - ๐Ÿ“ **TypeScript Native** - Full type safety and IntelliSense support
21
- - ๐Ÿงช **Tested & Reliable** - Built on proven Bonkbot foundation
22
-
23
- ## ๐Ÿ“ฆ Installation
11
+ To install BonkBot, you will need [Node.js](https://nodejs.org/en/download/) installed on your system. Then, run the following command in your terminal:
24
12
 
25
13
  ```bash
26
- npm install bonktools
14
+ npm install bonkbot
27
15
  ```
28
16
 
29
- ## ๐Ÿš€ Quick Start
30
-
31
- ### Simple Bot Example
32
-
33
- ```typescript
34
- import { createBot } from 'bonktools';
35
-
36
- // Create bot
37
- const bot = createBot({
38
- account: {
39
- username: 'MyBot',
40
- guest: true
41
- },
42
- logLevel: 'info'
43
- });
17
+ ## Features
44
18
 
45
- // Initialize and connect
46
- await bot.init();
47
- await bot.connect();
19
+ - Connect to existing rooms or create new ones
20
+ - Automatically determine the optimal server using the game's API
21
+ - Send and receive chat messages
22
+ - Track players joining and leaving
23
+ - Manage teams and game settings
24
+ - Handle game events
25
+ - Comprehensive error handling
26
+ - Detailed logging
48
27
 
49
- // Join a room
50
- await bot.joinRoomByUrl('https://bonk.io/123456');
28
+ # Support
51
29
 
52
- // Send a message
53
- await bot.chat('Hello from BonkTools! ๐ŸŽฎ');
54
-
55
- // Listen for events
56
- bot.on('chatMessage', (player, message) => {
57
- console.log(`${player.username}: ${message}`);
58
- });
59
- ```
30
+ [Discord Server](https://discord.gg/USJQjwD7AY)
60
31
 
61
- ### Host Bot Example
32
+ ## Basic Usage
62
33
 
63
- ```typescript
64
- import { createBot } from 'bonktools';
34
+ ```javascript
35
+ const { createBot, LOG_LEVELS } = require('bonkbot');
65
36
 
37
+ // Create a bot instance
66
38
  const bot = createBot({
67
- account: {
68
- username: 'HostBot',
69
- guest: true
70
- }
71
- });
72
-
73
- await bot.init();
74
- await bot.connect();
75
-
76
- // Create a room
77
- const room = await bot.createRoom({
78
- roomName: 'My Tournament Room',
79
- maxPlayers: 4,
80
- mode: 'classic'
81
- });
82
-
83
- console.log('Room created:', room.shareLink);
84
-
85
- // Detect when round ends (using physics simulation!)
86
- bot.on('roundEnd', ({ winner, scores }) => {
87
- console.log(`Winner: ${winner.username}`);
88
- console.log('Scores:', scores);
89
-
90
- // Auto-restart in 3 seconds
91
- setTimeout(() => bot.startGame(), 3000);
92
- });
93
-
94
- // Detect player deaths
95
- bot.on('playerDeath', (player, position) => {
96
- console.log(`${player.username} died at (${position.x}, ${position.y})`);
97
- });
98
-
99
- // Start when all ready
100
- bot.on('allPlayersReady', () => {
101
- bot.startGame();
102
- });
103
- ```
104
-
105
- ## ๐Ÿ“š API Reference
106
-
107
- ### Core Methods
108
-
109
- #### `init(): Promise<BonkTools>`
110
- Initialize the bot (get auth token, server info)
111
-
112
- #### `connect(): Promise<BonkTools>`
113
- Connect to Bonk.io server
114
-
115
- #### `disconnect(): void`
116
- Disconnect from server
117
-
118
- ### Room Management
119
-
120
- #### `createRoom(options: RoomOptions): Promise<RoomInfo>`
121
- Create a new room
122
-
123
- ```typescript
124
- const room = await bot.createRoom({
125
- roomName: 'My Room',
126
- maxPlayers: 4,
127
- password: 'secret',
128
- mode: 'classic',
129
- hidden: false
130
- });
131
- ```
132
-
133
- #### `joinRoom(address: string, password?: string): Promise<void>`
134
- Join room by address code
135
-
136
- ```typescript
137
- await bot.joinRoom('123456', 'password');
138
- ```
139
-
140
- #### `joinRoomByUrl(url: string): Promise<void>`
141
- Join room by full URL
142
-
143
- ```typescript
144
- await bot.joinRoomByUrl('https://bonk.io/123456');
145
- ```
146
-
147
- #### `leaveRoom(): Promise<void>`
148
- Leave current room
149
-
150
- ### Game Control
151
-
152
- #### `startGame(): Promise<void>`
153
- Start the game (host only)
154
-
155
- #### `stopGame(): Promise<void>`
156
- Stop/abort current game (host only)
157
-
158
- #### `setRounds(rounds: number): Promise<void>`
159
- Set number of rounds to win (1-999)
160
-
161
- ```typescript
162
- await bot.setRounds(5);
163
- ```
164
-
165
- #### `setReady(ready: boolean): Promise<void>`
166
- Set bot ready status
167
-
168
- ```typescript
169
- await bot.setReady(true);
170
- ```
171
-
172
- ### Player Management
173
-
174
- #### `getPlayer(id: number): PlayerData | null`
175
- Get player by ID
176
-
177
- #### `getPlayerByUsername(username: string, guest?: boolean): PlayerData | null`
178
- Get player by username
179
-
180
- #### `getAllPlayers(): PlayerData[]`
181
- Get all players in room
182
-
183
- #### `getHost(): PlayerData | null`
184
- Get current host player
185
-
186
- #### `isHost(): boolean`
187
- Check if bot is host
188
-
189
- #### `kickPlayer(playerId: number): Promise<void>`
190
- Kick a player (host only)
191
-
192
- #### `giveHost(playerId: number): Promise<void>`
193
- Transfer host to another player (host only)
194
-
195
- #### `joinTeam(team: number): Promise<void>`
196
- Join a team (0=spectate, 1=FFA, 2-6=teams)
197
-
198
- #### `lockTeams(locked: boolean): Promise<void>`
199
- Lock/unlock teams (host only)
200
-
201
- ### Chat
202
-
203
- #### `chat(message: string): Promise<void>`
204
- Send a chat message (max 200 chars)
205
-
206
- ```typescript
207
- await bot.chat('Hello everyone! ๐Ÿ‘‹');
208
- ```
209
-
210
- ### Utility
211
-
212
- #### `getShareLink(): string | null`
213
- Get room share link
214
-
215
- #### `getRoomInfo(): RoomInfo`
216
- Get current room information
217
-
218
- #### `getMyId(): number`
219
- Get bot's player ID
220
-
221
- #### `isReady(): boolean`
222
- Check if bot is initialized
223
-
224
- #### `isConnected(): boolean`
225
- Check if bot is connected
226
-
227
- #### `getGameState(): any`
228
- Get current game state (if physics is running)
229
-
230
- ## ๐ŸŽญ Events
231
-
232
- BonkTools uses TypeScript's EventEmitter for type-safe events:
233
-
234
- ### Connection Events
235
-
236
- ```typescript
237
- bot.on('ready', () => {
238
- console.log('Bot initialized');
39
+ account: {
40
+ username: 'BotName',
41
+ guest: true, // Use guest account
42
+ },
43
+ logLevel: LOG_LEVELS.WARN, // Set log level (DEBUG, INFO, WARN, ERROR, NONE)
239
44
  });
240
45
 
241
- bot.on('connect', () => {
242
- console.log('Connected to server');
46
+ // Initialize and handle events
47
+ bot.events.on('ready', async () => {
48
+ await bot.connect();
243
49
  });
244
50
 
245
- bot.on('disconnect', (reason) => {
246
- console.log('Disconnected:', reason);
247
- });
51
+ // Handle chat messages
52
+ bot.events.on('CHAT_MESSAGE', (message) => {
53
+ console.log(`${message.player.username}: ${message.message}`);
248
54
 
249
- bot.on('error', (error) => {
250
- console.error('Error:', error);
55
+ // Respond to !ping command
56
+ if (message.message === '!ping') {
57
+ bot.chat('Pong!');
58
+ }
251
59
  });
252
- ```
253
60
 
254
- ### Room Events
255
-
256
- ```typescript
257
- bot.on('roomCreated', (room) => {
258
- console.log('Room created:', room.shareLink);
61
+ bot.events.on('PACKET', (packet) => {
62
+ bot.autoHandlePacket(packet);
259
63
  });
260
64
 
261
- bot.on('roomJoined', ({ game, room, players }) => {
262
- console.log('Joined room:', room.name);
263
- });
65
+ bot.init();
264
66
  ```
265
67
 
266
- ### Player Events
68
+ ## Authentication Examples
267
69
 
268
- ```typescript
269
- bot.on('playerJoin', (player) => {
270
- console.log(`${player.username} joined`);
271
- });
70
+ ### Automatic Server Detection
272
71
 
273
- bot.on('playerLeave', (player) => {
274
- console.log(`${player.username} left`);
275
- });
72
+ By default, BonkBot will automatically determine the optimal server to connect to by querying the game's API. This ensures your bot connects to the most appropriate server based on the current game infrastructure.
276
73
 
277
- bot.on('playerReady', (player, ready) => {
278
- console.log(`${player.username} is ${ready ? 'ready' : 'not ready'}`);
279
- });
280
-
281
- bot.on('allPlayersReady', () => {
282
- console.log('All players ready!');
283
- });
284
-
285
- bot.on('playerTeamChange', (player, team) => {
286
- console.log(`${player.username} joined team ${team}`);
287
- });
74
+ If you want to override this behavior and connect to a specific server, you can provide the `server` option when creating the bot:
288
75
 
289
- bot.on('playerKick', (player) => {
290
- console.log(`${player.username} was kicked`);
76
+ ```javascript
77
+ const bot = createBot({
78
+ // ... other options
79
+ server: 'b2ny1', // Force connection to a specific server
291
80
  });
292
81
  ```
293
82
 
294
- ### Game Events
295
-
296
- ```typescript
297
- bot.on('gameStart', () => {
298
- console.log('Game started!');
299
- });
83
+ ### Guest Account
300
84
 
301
- bot.on('gameEnd', (result) => {
302
- console.log('Game ended!');
303
- console.log('Champion:', result.champion?.username);
304
- });
305
-
306
- bot.on('roundStart', (roundNumber) => {
307
- console.log(`Round ${roundNumber} started`);
308
- });
309
-
310
- bot.on('roundEnd', (result) => {
311
- console.log('Round ended!');
312
- console.log('Winner:', result.winner?.username);
313
- console.log('Scores:', result.scores);
314
- console.log('Duration:', result.duration);
315
- });
316
-
317
- bot.on('countdown', (seconds) => {
318
- console.log(`Starting in ${seconds}...`);
85
+ ```javascript
86
+ const bot = createBot({
87
+ account: {
88
+ username: 'BotName',
89
+ guest: true,
90
+ },
91
+ logLevel: LOG_LEVELS.WARN,
319
92
  });
320
93
  ```
321
94
 
322
- ### Physics Events (โšก New!)
95
+ ### User Account
323
96
 
324
- These events are powered by the Box2D physics simulator:
325
-
326
- ```typescript
327
- bot.on('playerDeath', (player, position) => {
328
- console.log(`${player.username} died at (${position.x}, ${position.y})`);
329
- });
330
-
331
- bot.on('collision', (event) => {
332
- console.log('Collision detected:', event.type);
333
- console.log('Player:', event.playerId);
334
- console.log('Position:', event.position);
335
- });
336
-
337
- bot.on('playerOutOfBounds', (player) => {
338
- console.log(`${player.username} went out of bounds`);
97
+ ```javascript
98
+ const bot = createBot({
99
+ account: {
100
+ username: 'YourUsername',
101
+ password: 'YourPassword',
102
+ guest: false,
103
+ },
104
+ logLevel: LOG_LEVELS.WARN,
339
105
  });
340
106
  ```
341
107
 
342
- ### Chat Events
108
+ ## Connection Flow and Examples
343
109
 
344
- ```typescript
345
- bot.on('chatMessage', (player, message) => {
346
- console.log(`${player.username}: ${message}`);
347
-
348
- // Respond to commands
349
- if (message === '!help') {
350
- bot.chat('Available commands: !help, !placar');
351
- }
352
- });
353
- ```
110
+ The connection flow typically follows this sequence:
354
111
 
355
- ### Host Events
112
+ 1. Bot initialization (`bot.init()`)
113
+ 2. Ready event fires when login completes
114
+ 3. Connect to game server (`bot.connect()`)
115
+ 4. Find or create room
116
+ 5. Join room or create room
117
+ 6. Handle game events
356
118
 
357
- ```typescript
358
- bot.on('hostTransfer', (oldHost, newHost) => {
359
- console.log(`Host transferred from ${oldHost.username} to ${newHost.username}`);
360
- });
119
+ ### Joining a Room by Name
361
120
 
362
- bot.on('teamLockToggle', (locked) => {
363
- console.log(`Teams ${locked ? 'locked' : 'unlocked'}`);
364
- });
121
+ ```javascript
122
+ bot.events.on('ready', async () => {
123
+ try {
124
+ // Find room by name
125
+ const roomInfo = await bot.getAddressFromRoomName('roomName');
126
+ console.log(`Found room: ${roomInfo.roomname}`);
365
127
 
366
- bot.on('roundsChange', (rounds) => {
367
- console.log(`Rounds changed to ${rounds}`);
368
- });
128
+ // Set address and connect
129
+ bot.setAddress(roomInfo);
130
+ await bot.connect();
369
131
 
370
- bot.on('gamemodeChange', (mode, engine) => {
371
- console.log(`Mode changed to ${mode} (${engine})`);
132
+ // Join with optional password
133
+ await bot.joinRoom({
134
+ password: 'optional-password',
135
+ });
136
+ } catch (error) {
137
+ console.error('Failed to join room:', error);
138
+ }
372
139
  });
373
140
  ```
374
141
 
375
- ### Map Events
142
+ ### Joining a Room by Link
376
143
 
377
- ```typescript
378
- bot.on('mapSwitch', (map) => {
379
- console.log('Map changed:', map.m.n); // map name
380
- });
144
+ ```javascript
145
+ bot.events.on('ready', async () => {
146
+ try {
147
+ // Get room info from share link
148
+ const roomInfo = await bot.getAddressFromUrl('https://bonk.io/123abc');
149
+ console.log(`Found room: ${roomInfo.roomname}`);
381
150
 
382
- bot.on('mapSuggest', ({ title, author, player }) => {
383
- console.log(`${player.username} suggested map: ${title} by ${author}`);
151
+ // Connect to room
152
+ bot.setAddress(roomInfo);
153
+ await bot.connect();
154
+ await bot.joinRoom();
155
+ } catch (error) {
156
+ console.error('Failed to join room:', error);
157
+ }
384
158
  });
385
159
  ```
386
160
 
387
- ## ๐ŸŽฏ Advanced Usage
161
+ ### Creating a Room
388
162
 
389
- ### Tournament Bot
163
+ ```javascript
164
+ bot.events.on('ready', async () => {
165
+ try {
166
+ // Connect to server first
167
+ await bot.connect();
390
168
 
391
- ```typescript
392
- import { createBot } from 'bonktools';
393
-
394
- const bot = createBot({ /* ... */ });
395
- await bot.init();
396
- await bot.connect();
397
-
398
- const room = await bot.createRoom({
399
- roomName: '๐Ÿ† Tournament - Round 1',
400
- maxPlayers: 8,
401
- mode: 'arrows'
169
+ // Then create room
170
+ bot.createRoom({
171
+ roomname: 'BonkBot Room',
172
+ maxplayers: 10,
173
+ roompassword: '',
174
+ hidden: true,
175
+ });
176
+ } catch (error) {
177
+ console.error('Failed to create room:', error);
178
+ }
402
179
  });
403
180
 
404
- const scores = new Map<string, number>();
405
- let matchCount = 0;
406
- const maxMatches = 10;
407
-
408
- bot.on('roundEnd', ({ winner }) => {
409
- if (winner) {
410
- scores.set(winner.username, (scores.get(winner.username) || 0) + 1);
411
- }
412
-
413
- matchCount++;
414
-
415
- if (matchCount >= maxMatches) {
416
- // Tournament ended
417
- const champion = Array.from(scores.entries())
418
- .sort((a, b) => b[1] - a[1])[0];
419
-
420
- bot.chat(`๐Ÿ† Tournament Champion: ${champion[0]}!`);
421
-
422
- // Show leaderboard
423
- const leaderboard = Array.from(scores.entries())
424
- .sort((a, b) => b[1] - a[1])
425
- .map(([name, score], i) => `${i+1}. ${name}: ${score}`)
426
- .join(' | ');
427
-
428
- bot.chat(`๐Ÿ“Š Final: ${leaderboard}`);
429
- } else {
430
- // Next match
431
- setTimeout(() => bot.startGame(), 5000);
432
- }
181
+ // Get share link when room is created
182
+ bot.events.on('ROOM_SHARE_LINK', (data) => {
183
+ console.log(`Room created! URL: ${data.url}`);
433
184
  });
434
185
  ```
435
186
 
436
- ### Custom Command System
437
-
438
- ```typescript
439
- const commands = {
440
- '!help': () => bot.chat('Commands: !help, !score, !stats'),
441
-
442
- '!score': () => {
443
- const players = bot.getAllPlayers();
444
- const scoreText = players
445
- .map(p => `${p.username}: ${p.balance}`)
446
- .join(' | ');
447
- bot.chat(`๐Ÿ“Š ${scoreText}`);
448
- },
449
-
450
- '!stats': () => {
451
- const players = bot.getAllPlayers();
452
- bot.chat(`๐Ÿ‘ฅ Players: ${players.length}`);
453
- bot.chat(`๐ŸŽฎ Round: ${currentRound}/${maxRounds}`);
454
- }
455
- };
456
-
457
- bot.on('chatMessage', (player, message) => {
458
- const command = commands[message.toLowerCase()];
459
- if (command) {
460
- command();
461
- }
462
- });
187
+ ## Available Events
188
+
189
+ | Event | Description | Returns |
190
+ | ------------------ | --------------------------- | ------------------------- |
191
+ | `ready` | Bot is ready to connect | - |
192
+ | `connect` | Connected to server | - |
193
+ | `PACKET` | Any packet received | `{type, ...data}` |
194
+ | `JOIN` | Joined a room | `{game, room, players}` |
195
+ | `PLAYER_JOIN` | Player joined room | `{player, id}` |
196
+ | `PLAYER_LEAVE` | Player left room | `{player, id}` |
197
+ | `CHAT_MESSAGE` | Chat message received | `{player, message}` |
198
+ | `TEAM_CHANGE` | Player changed team | `{player, team}` |
199
+ | `HOST_TRANSFER` | Host was transferred | `{oldHost, newHost}` |
200
+ | `READY_CHANGE` | Player ready status changed | `{player, ready}` |
201
+ | `GAME_START` | Game started | - |
202
+ | `GAME_END` | Game ended | - |
203
+ | `COUNTDOWN` | Game countdown | `{countdown}` |
204
+ | `MAP_SWITCH` | Map was switched | `{map}` |
205
+ | `MAP_SUGGEST` | Map was suggested | `{title, author, player}` |
206
+ | `CHANGE_ROUNDS` | Round count changed | `{rounds}` |
207
+ | `GAMEMODE_CHANGE` | Game mode changed | `{mode, engine}` |
208
+ | `ROOM_SHARE_LINK` | Room link created | `{url}` |
209
+ | `PLAYER_KICK` | Player was kicked | `player` |
210
+ | `PLAYER_TABBED` | Player tabbed in/out | `{player, tabbed}` |
211
+ | `PLAYER_INPUT` | Player input received | `{player, movement}` |
212
+ | `TEAMLOCK_TOGGLE` | Teams locked/unlocked | `{teamsLocked}` |
213
+ | `ROOM_NAME_UPDATE` | Room name changed | `{name}` |
214
+ | `ROOM_ADDRESS` | Room address updated | `{address}` |
215
+ | `BALANCE_SET` | Player balance changed | `{player, balance}` |
216
+ | `disconnect` | Disconnected from server | - |
217
+
218
+ ## Common Methods
219
+
220
+ ```javascript
221
+ // Chat message
222
+ bot.chat('Hello world');
223
+
224
+ // Get all players
225
+ const players = bot.getAllPlayers();
226
+
227
+ // Get host
228
+ const host = bot.getHost();
229
+
230
+ // Get room share link
231
+ const shareLink = bot.getShareLink();
232
+
233
+ // Set player ready status
234
+ bot.ready(true);
235
+
236
+ // Join a team (0-5)
237
+ bot.joinTeam(2); // 0=spectator, 1=FFA, 2=red, 3=blue...
238
+
239
+ // Give host to player
240
+ bot.giveHost(playerId);
241
+
242
+ // Kick a player
243
+ bot.kickPlayer(playerId);
244
+
245
+ // Leave the room
246
+ bot.leaveGame();
463
247
  ```
464
248
 
465
- ## ๐Ÿ”ง Configuration
466
-
467
- ### BonkToolsOptions
468
-
469
- ```typescript
470
- interface BonkToolsOptions {
471
- account: {
472
- username: string;
473
- password?: string; // For non-guest accounts
474
- guest?: boolean; // Default: true
475
- };
476
- server?: string; // Default: auto-detect best server
477
- avatar?: Avatar; // Custom avatar
478
- logLevel?: LogLevel; // 'debug' | 'info' | 'warn' | 'error' | 'none'
479
- protocolVersion?: number; // Default: 49
480
- peerID?: string; // Custom peer ID (auto-generated if not provided)
481
- }
482
- ```
483
-
484
- ### RoomOptions
485
-
486
- ```typescript
487
- interface RoomOptions {
488
- roomName?: string;
489
- maxPlayers?: number; // 1-8
490
- password?: string;
491
- hidden?: boolean;
492
- quick?: boolean;
493
- mode?: 'classic' | 'arrows' | 'grapple' | 'death arrows' | 'simple' | 'vtol';
494
- minLevel?: number; // 0-999
495
- maxLevel?: number; // 0-999
496
- }
497
- ```
498
-
499
- ## ๐Ÿ—๏ธ Architecture
500
-
501
- BonkTools is built on a modular architecture:
502
-
503
- ```
504
- BonkTools (Main API)
505
- โ”œโ”€โ”€ BonkConnection (WebSocket layer)
506
- โ”‚ โ”œโ”€โ”€ PacketParser
507
- โ”‚ โ””โ”€โ”€ PacketBuilder
508
- โ”œโ”€โ”€ PhysicsWorld (Box2D simulation)
509
- โ”‚ โ”œโ”€โ”€ GameState
510
- โ”‚ โ”œโ”€โ”€ CollisionDetector
511
- โ”‚ โ””โ”€โ”€ InputProcessor
512
- โ”œโ”€โ”€ GameLoop (60 FPS game loop)
513
- โ”œโ”€โ”€ RoomManager
514
- โ””โ”€โ”€ PlayerManager
515
- ```
516
-
517
- The key innovation is the **PhysicsWorld** module, which:
518
- 1. Receives player inputs from the server
519
- 2. Simulates the game physics using Box2D
520
- 3. Detects collisions, deaths, and round endings
521
- 4. Emits events for your bot to react to
522
-
523
- This allows BonkTools to have awareness of the game state that's impossible with just WebSocket packets alone.
524
-
525
- ## ๐Ÿค Contributing
526
-
527
- Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) first.
528
-
529
- ## ๐Ÿ“ License
530
-
531
- MIT ยฉ OBL
532
-
533
- ## ๐Ÿ™ Acknowledgments
534
-
535
- - Built on [Bonkbot](https://github.com/PixelMelt/BonkBot) by PixelMelt
536
- - Physics powered by [Box2D](https://box2d.org/)
537
- - Inspired by the Brazilian Bonk.io community
249
+ ## Examples
538
250
 
539
- ## ๐Ÿ“ž Support
251
+ Check out the `examples` directory for more examples:
540
252
 
541
- - GitHub Issues: [github.com/brenoluizdev/bonktools/issues](https://github.com/brenoluizdev/bonktools/issues)
542
- - Discord: [Join our Discord](https://discord.gg/dBVmaySqEk)
253
+ - `simple-bot.js`: A basic bot that connects to a room and responds to chat commands
254
+ - `host-bot.js`: A bot that creates and hosts a room
543
255
 
544
- ---
256
+ ## Contributing
545
257
 
546
- Made with โค๏ธ for the Bonk.io community
258
+ Contributions are always welcome! If you find a bug or have a feature request, please open an issue on the project's GitHub page.
547
259
 
260
+ ## License
548
261
 
549
- [![npm version](https://img.shields.io/npm/v/bonktools.svg?color=blue)](https://www.npmjs.com/package/bonktools)
550
- [![license](https://img.shields.io/github/license/brenoluizdev/bonktools.svg)](https://github.com/brenoluizdev/bonktools/blob/main/LICENSE)
551
- [![GitHub Repo stars](https://img.shields.io/github/stars/brenoluizdev/bonktools?style=social)](https://github.com/brenoluizdev/bonktools)
262
+ BonkBot is open-source software licensed under the [GPL-3.0 License](https://www.gnu.org/licenses/gpl-3.0.en.html).