{"_id":"@alfianrafli/growtopia.wasm","_rev":"6-d84e46a5dbf6ae8ec8874fbd4135e325","name":"@alfianrafli/growtopia.wasm","dist-tags":{"latest":"0.3.1"},"versions":{"0.2.0":{"name":"@alfianrafli/growtopia.wasm","version":"0.2.0","keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"author":{"url":"https://stile.jad.li","name":"StileDevs","email":"hendra@jad.li"},"license":"MIT","_id":"@alfianrafli/growtopia.wasm@0.2.0","maintainers":[{"name":"alfianrafli","email":"alfianraflizakarya@gmail.com"}],"homepage":"https://github.com/StileDevs/growtopia.wasm#readme","bugs":{"url":"https://github.com/StileDevs/growtopia.wasm/issues"},"ava":{"files":["__test__/**/*"],"serial":true,"timeout":"3m","extensions":["cjs","mjs"]},"dist":{"shasum":"ff509d0e413d94764f497d61423ffe2da975d13f","tarball":"https://registry.npmjs.org/@alfianrafli/growtopia.wasm/-/growtopia.wasm-0.2.0.tgz","fileCount":22,"integrity":"sha512-tpomkUbydpARUrWceQ870l9Ng97eTxhdABGWzKpiqhLgA8b4+HrZxmyh4TI/nuIfrdhGzcU/1C4yWniQ7mT3Mg==","signatures":[{"sig":"MEUCIHjNz3n8JAXuxfczWSqyJ2mlRbkQDDD4oLrZeX96H8kBAiEAqjxv1YwCFfNnJ1HCqC9NPjADsQE3cIULGg5uw4FPnLs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1113039},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">= 10"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./node":{"types":"./dist/node-transport.d.ts","import":"./dist/node-transport.mjs","require":"./dist/node-transport.js"},"./browser":{"types":"./dist/browser-transport.d.ts","import":"./dist/browser-transport.mjs","require":"./dist/browser-transport.js"},"./package.json":"./package.json"},"gitHead":"aa48f001c109fcab819965f4836a63010203f79e","scripts":{"docs":"rimraf docs && typedoc","lint":"bunx oxlint","test":"ava","build":"bun run build:wasm && bun run build:tsup","format":"bunx oxfmt","lint:fix":"bunx oxlint --fix","build:tsup":"rimraf dist && tsup && tsc --emitDeclarationOnly --outDir dist","build:wasm":"rimraf lib/pkg && wasm-pack build --target web --out-dir lib/pkg","format:check":"bunx oxfmt --check"},"_npmUser":{"name":"alfianrafli","email":"alfianraflizakarya@gmail.com"},"repository":{"url":"git+https://github.com/StileDevs/growtopia.wasm.git","type":"git"},"_npmVersion":"11.19.1","description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","directories":{},"_nodeVersion":"26.4.0","dependencies":{"nanoevents":"^10.0.0"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^8.0.1","tsup":"^8.5.1","oxfmt":"^0.61.0","oxlint":"^1.76.0","rimraf":"^6.1.3","typedoc":"^0.28.20","wasm-pack":"^0.15.0","@types/bun":"^1.3.14","selfsigned":"^5.5.0","typescript":"5.6.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/growtopia.wasm_0.2.0_1788530522351_0.5650821947064868","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@alfianrafli/growtopia.wasm","version":"0.2.1","keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"author":{"url":"https://stile.jad.li","name":"StileDevs","email":"hendra@jad.li"},"license":"MIT","_id":"@alfianrafli/growtopia.wasm@0.2.1","maintainers":[{"name":"alfianrafli","email":"alfianraflizakarya@gmail.com"}],"homepage":"https://github.com/StileDevs/growtopia.wasm#readme","bugs":{"url":"https://github.com/StileDevs/growtopia.wasm/issues"},"ava":{"files":["__test__/**/*"],"serial":true,"timeout":"3m","extensions":["cjs","mjs"]},"dist":{"shasum":"4d3f7ddad6d48c5fafcfb0973ae9bf16ba7e714a","tarball":"https://registry.npmjs.org/@alfianrafli/growtopia.wasm/-/growtopia.wasm-0.2.1.tgz","fileCount":23,"integrity":"sha512-hufGeB7S+fs6NTPE0jxzWJq5J4b9ZD2SfoE2ZxVUtvb2+bqGXpbZUYiQ73wYzuqKTiiJpvjB/PwA9+rzZJmmrA==","signatures":[{"sig":"MEUCIFQ2aF9QAari/i9H0+BpvHRlX/lOA3WYhfwXPCbYLZShAiEAlkO1tecDItTohhUVP2v5shuO/01GlYzdE5R5JPmlrIY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1509769},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">= 10"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./node":{"types":"./dist/node-transport.d.ts","import":"./dist/node-transport.mjs","require":"./dist/node-transport.js"},"./browser":{"types":"./dist/browser-transport.d.ts","import":"./dist/browser-transport.mjs","require":"./dist/browser-transport.js"},"./package.json":"./package.json"},"gitHead":"aa48f001c109fcab819965f4836a63010203f79e","scripts":{"docs":"rimraf docs && typedoc","lint":"bunx oxlint","test":"ava","build":"bun run build:wasm && bun run build:tsup","format":"bunx oxfmt","lint:fix":"bunx oxlint --fix","build:tsup":"rimraf dist && tsup && tsc --emitDeclarationOnly --outDir dist","build:wasm":"rimraf lib/pkg && wasm-pack build --target web --out-dir lib/pkg","format:check":"bunx oxfmt --check"},"_npmUser":{"name":"alfianrafli","email":"alfianraflizakarya@gmail.com"},"repository":{"url":"git+https://github.com/StileDevs/growtopia.wasm.git","type":"git"},"_npmVersion":"11.19.1","description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","directories":{},"_nodeVersion":"26.4.0","dependencies":{"nanoevents":"^10.0.0"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^8.0.1","tsup":"^8.5.1","oxfmt":"^0.61.0","oxlint":"^1.76.0","rimraf":"^6.1.3","typedoc":"^0.28.20","wasm-pack":"^0.15.0","@types/bun":"^1.3.14","selfsigned":"^5.5.0","typescript":"5.6.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/growtopia.wasm_0.2.1_1788532864003_0.9757744494162683","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@alfianrafli/growtopia.wasm","version":"0.2.2","keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"author":{"url":"https://stile.jad.li","name":"StileDevs","email":"hendra@jad.li"},"license":"MIT","_id":"@alfianrafli/growtopia.wasm@0.2.2","maintainers":[{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"}],"homepage":"https://github.com/AlfianRafli/growtopia.wasm-ng#readme","bugs":{"url":"https://github.com/AlfianRafli/growtopia.wasm-ng/issues"},"ava":{"files":["__test__/**/*"],"serial":true,"timeout":"3m","extensions":["cjs","mjs"]},"dist":{"shasum":"ded5e4fa2a2df92d176c54ef58701683973e41eb","tarball":"https://registry.npmjs.org/@alfianrafli/growtopia.wasm/-/growtopia.wasm-0.2.2.tgz","fileCount":31,"integrity":"sha512-OW28mY/AUSU83RFzFm57hKD4/X9UxVVDyCl+JowNdjiUs3f+GSe2Q3LvnwdI6ShvQ7VEotA0TD+WoRVleWeQRA==","signatures":[{"sig":"MEYCIQC62IkpSxFgInMBoIoVRkE/+xczUpOG88foDxo0NvoLPgIhAMoBH6KeYxLbBM68y/rwqhLMKhKUlBcl4Pa6teBYbHJB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":960167},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">= 10"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./node":{"types":"./dist/node-transport.d.ts","import":"./dist/node-transport.mjs","require":"./dist/node-transport.js"},"./browser":{"types":"./dist/browser-transport.d.ts","import":"./dist/browser-transport.mjs","require":"./dist/browser-transport.js"},"./package.json":"./package.json"},"gitHead":"19340950d229c31824dad42206126fd995673a68","scripts":{"docs":"rimraf docs && typedoc","lint":"bunx oxlint","test":"ava","build":"bun run build:wasm && bun run build:tsup","format":"bunx oxfmt","lint:fix":"bunx oxlint --fix","build:tsup":"rimraf dist && tsup && tsc --emitDeclarationOnly --outDir dist","build:wasm":"rimraf lib/pkg && wasm-pack build --target web --out-dir lib/pkg","format:check":"bunx oxfmt --check"},"_npmUser":{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"},"repository":{"url":"git+https://github.com/AlfianRafli/growtopia.wasm-ng.git","type":"git"},"_npmVersion":"11.17.0","description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","directories":{},"_nodeVersion":"24.19.0","dependencies":{"nanoevents":"^10.0.0"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^8.0.1","tsup":"^8.5.1","oxfmt":"^0.61.0","oxlint":"^1.76.0","rimraf":"^6.1.3","typedoc":"^0.28.20","wasm-pack":"^0.15.0","@types/bun":"^1.3.14","selfsigned":"^5.5.0","typescript":"5.6.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/growtopia.wasm_0.2.2_1788544339927_0.17933750244383595","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alfianrafli/growtopia.wasm","version":"0.3.0","keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"author":{"url":"https://stile.jad.li","name":"StileDevs","email":"hendra@jad.li"},"license":"MIT","_id":"@alfianrafli/growtopia.wasm@0.3.0","maintainers":[{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"}],"homepage":"https://github.com/AlfianRafli/growtopia.wasm-ng#readme","bugs":{"url":"https://github.com/AlfianRafli/growtopia.wasm-ng/issues"},"ava":{"files":["__test__/**/*"],"serial":true,"timeout":"3m","extensions":["cjs","mjs"]},"dist":{"shasum":"f3fc340d98dcd471f4131293f2adaa18333c2063","tarball":"https://registry.npmjs.org/@alfianrafli/growtopia.wasm/-/growtopia.wasm-0.3.0.tgz","fileCount":31,"integrity":"sha512-ZlGvhvXP6AktBNH7jyyMXQ6Y8GDYnqKP7abS8xz5zRQ1ASal4pRA6P2lqyXOt06OC/vWKtLaMAO+3A5HHFI13w==","signatures":[{"sig":"MEYCIQDgOUIsA3tor/xu0SSKU0ud4KYQvaoAH7TOvHKhLiggPAIhAJmMmQoqMkTlnC0eN8pKMVsXmqse+/L+G6aWe8oi2Ke5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":960167},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">= 10"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./node":{"types":"./dist/node-transport.d.ts","import":"./dist/node-transport.mjs","require":"./dist/node-transport.js"},"./browser":{"types":"./dist/browser-transport.d.ts","import":"./dist/browser-transport.mjs","require":"./dist/browser-transport.js"},"./package.json":"./package.json"},"gitHead":"1cd77af98d48b902e278e0d051dd0055a920c7db","scripts":{"docs":"rimraf docs && typedoc","lint":"bunx oxlint","test":"ava","build":"bun run build:wasm && bun run build:tsup","format":"bunx oxfmt","lint:fix":"bunx oxlint --fix","build:tsup":"rimraf dist && tsup && tsc --emitDeclarationOnly --outDir dist","build:wasm":"rimraf lib/pkg && wasm-pack build --target web --out-dir lib/pkg","format:check":"bunx oxfmt --check"},"_npmUser":{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"},"repository":{"url":"git+https://github.com/AlfianRafli/growtopia.wasm-ng.git","type":"git"},"_npmVersion":"11.17.0","description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","directories":{},"_nodeVersion":"24.19.0","dependencies":{"nanoevents":"^10.0.0"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^8.0.1","tsup":"^8.5.1","oxfmt":"^0.61.0","oxlint":"^1.76.0","rimraf":"^6.1.3","typedoc":"^0.28.20","wasm-pack":"^0.15.0","@types/bun":"^1.3.14","selfsigned":"^5.5.0","typescript":"5.6.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/growtopia.wasm_0.3.0_1788544745589_0.7169917864489013","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@alfianrafli/growtopia.wasm","version":"0.3.1","description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","import":"./dist/index.mjs"},"./node":{"types":"./dist/node-transport.d.ts","import":"./dist/node-transport.mjs","require":"./dist/node-transport.js"},"./browser":{"types":"./dist/browser-transport.d.ts","import":"./dist/browser-transport.mjs","require":"./dist/browser-transport.js"},"./package.json":"./package.json"},"license":"MIT","ava":{"files":["__test__/**/*"],"extensions":["cjs","mjs"],"timeout":"3m","serial":true},"engines":{"node":">= 10"},"homepage":"https://github.com/AlfianRafli/growtopia.wasm-ng#readme","bugs":{"url":"https://github.com/AlfianRafli/growtopia.wasm-ng/issues"},"repository":{"type":"git","url":"git+https://github.com/AlfianRafli/growtopia.wasm-ng.git"},"keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"author":{"name":"StileDevs","email":"hendra@jad.li","url":"https://stile.jad.li"},"scripts":{"build:wasm":"rimraf lib/pkg && wasm-pack build --target web --out-dir lib/pkg","build:tsup":"rimraf dist && tsup && tsc --emitDeclarationOnly --outDir dist","build":"bun run build:wasm && bun run build:tsup","test":"ava","docs":"rimraf docs && typedoc","format":"bunx oxfmt","format:check":"bunx oxfmt --check","lint":"bunx oxlint","lint:fix":"bunx oxlint --fix"},"devDependencies":{"@types/bun":"^1.3.14","@types/node":"^26.1.2","ava":"^8.0.1","oxfmt":"^0.61.0","oxlint":"^1.76.0","rimraf":"^6.1.3","selfsigned":"^5.5.0","tsup":"^8.5.1","typedoc":"^0.28.20","typescript":"5.6.3","wasm-pack":"^0.15.0"},"dependencies":{"nanoevents":"^10.0.0"},"gitHead":"5414e1f7d6d4b4321699c2bdbbac8ee2ba73b6cd","_id":"@alfianrafli/growtopia.wasm@0.3.1","_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-GVsJbnp1S4DXNFH5c+erAwWSqCET0i3Ii2Cv8nDIJ0R7/8Xve8O66PAvAKYh8TQpyrp4kmKKareSaN02vrWZFQ==","shasum":"17c78efeefcb343be4c5f58ab06f7b117a9a3eb4","tarball":"https://registry.npmjs.org/@alfianrafli/growtopia.wasm/-/growtopia.wasm-0.3.1.tgz","fileCount":31,"unpackedSize":974590,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alfianrafli%2fgrowtopia.wasm@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIG13NCKHwY4loMIT55hn2SIRphhBZBE0qxXRI9w+KGHvAiEA6cKiJ4JxpQdLESGkEaOQOuuWv72amssrqAJubTyGnd0="}]},"_npmUser":{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"},"directories":{},"maintainers":[{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/growtopia.wasm_0.3.1_1788549970953_0.41641597719958034"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-04T14:02:02.153Z","modified":"2026-09-04T19:26:11.517Z","0.2.0":"2026-09-04T14:02:02.549Z","0.2.1":"2026-09-04T14:41:04.187Z","0.2.2":"2026-09-04T17:52:20.137Z","0.3.0":"2026-09-04T17:59:05.724Z","0.3.1":"2026-09-04T19:26:11.129Z"},"bugs":{"url":"https://github.com/AlfianRafli/growtopia.wasm-ng/issues"},"author":{"name":"StileDevs","email":"hendra@jad.li","url":"https://stile.jad.li"},"license":"MIT","homepage":"https://github.com/AlfianRafli/growtopia.wasm-ng#readme","keywords":["growtopia","rust","wasm","webassembly","enet","udp"],"repository":{"type":"git","url":"git+https://github.com/AlfianRafli/growtopia.wasm-ng.git"},"description":"A Universal Growtopia ENet WASM for Node.js, Bun.js (replacement for growtopia.js)","maintainers":[{"name":"alfianrafliz","email":"alfianraflizakarya@gmail.com"}],"readme":"# @alfianrafli/growtopia.wasm\n\n[![NPM Version](https://img.shields.io/npm/v/@alfianrafli/growtopia.wasm?style=flat-square)](https://npmjs.com/package/@alfianrafli/growtopia.wasm)\n[![NPM Downloads](https://img.shields.io/npm/dw/@alfianrafli/growtopia.wasm?style=flat-square&color=blue)](https://npmjs.com/package/@alfianrafli/growtopia.wasm)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/AlfianRafli/growtopia.wasm-ng/CI.yml?branch=main&style=flat-square)](https://github.com/AlfianRafli/growtopia.wasm-ng/actions)\n\nA universal Growtopia ENet library compiled to WebAssembly (WASM) for Node.js and Bun.js. Designed as a cross-platform replacement for [growtopia.js](https://github.com/StileDevs/growtopia.js).\n\n**This project is based on and derived from the original [growtopia.wasm](https://github.com/StileDevs/growtopia.wasm) project by [StileDevs](https://github.com/StileDevs).**\n\n## Why replacement of growtopia.js?\n\n[growtopia.js](https://github.com/StileDevs/growtopia.js) relied on native Rust bindings compiled via [napi-rs](https://napi.rs/), requiring platform-specific binary builds and causing compatibility issues across different platforms. `@alfianrafli/growtopia.wasm` solves this by compiling the Rust core ENet library directly into WebAssembly, guaranteeing seamless execution across Node.js and Bun.js environments without native dependencies.\n\n## Differences between growtopia.js and @alfianrafli/growtopia.wasm\n\n| Feature / Aspect      | `growtopia.js`                                              | `@alfianrafli/growtopia.wasm`                                                  |\n| --------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------- |\n| **Core Engine**       | Native Node.js bindings (`napi-rs` / `.node`)               | Rust compiled to WebAssembly (`wasm-pack`)                        |\n| **Platform Support**  | Requires OS/CPU specific native binaries                    | Single WASM binary (Runs on Windows, Linux, macOS, Android, etc.) |\n| **Installation**      | Heavy; may fail on unsupported OS/arch without C++ compiler | Zero native compilation; instant install                          |\n| **Network Transport** | Native C ENet sockets                                       | TypeScript transport bridge (`dgram` for Node/Bun)                        |\n\n---\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n  - [ENet Server Example](#enet-server-example)\n  - [ENet Client Example](#enet-client-example)\n- [API Reference](#api-reference)\n  - [Initialization](#initialization)\n  - [Node.js API](#nodejs-api)\n  - [Browser API](#browser-api)\n  - [Peer API](#peer-api)\n  - [Packet API](#packet-api)\n  - [Packet Serialization](#packet-serialization)\n  - [Utilities](#utilities)\n- [Lifecycle & Resource Management](#lifecycle--resource-management)\n- [Environment Support](#environment-support)\n- [Links](#links)\n- [License & Credits](#license--credits)\n\n---\n\n## Installation\n\n```bash\nnpm install @alfianrafli/growtopia.wasm\n```\n\nor with Bun:\n\n```bash\nbun add @alfianrafli/growtopia.wasm\n```\n\n---\n\n## Quick Start\n\n### ENet Server Example\n\n```js\nimport { NodeENetServer, init, Packet, PacketKind } from \"@alfianrafli/growtopia.wasm\";\n\nasync function main() {\n  // Initialize WebAssembly core\n  await init();\n\n  // Initialize ENet server host (IP, Port, Max Peers, Channels)\n  const server = new NodeENetServer(\"127.0.0.1\", 17091, 1024, 2);\n  await server.start();\n\n  // Start event polling loop\n  server.startPolling(15);\n\n  server.emitter.on(\"connect\", peer => {\n    console.log(`Client connected: ID ${peer.id} from ${peer.ip}:${peer.port}`);\n\n    // Send Hello packet (Type 1)\n    const helloPayload = new Uint8Array([1, 0, 0, 0, 0]);\n    const helloPacket = new Packet(helloPayload, PacketKind.Reliable);\n    peer.send(helloPacket);\n  });\n\n  server.emitter.on(\"disconnect\", (peer, data) => {\n    console.log(`Client disconnected: ID ${peer.id}, code: ${data}`);\n  });\n\n  server.emitter.on(\"receive\", (peer, packet, channelId) => {\n    const data = packet.data();\n    console.log(`Received ${data.length} bytes on channel ${channelId} from peer ${peer.id}`);\n  });\n}\n\nmain();\n```\n\n### ENet Client Example\n\n```js\nimport { NodeENetClient, init } from \"@alfianrafli/growtopia.wasm\";\n\nasync function main() {\n  await init();\n\n  const client = new NodeENetClient(\"0.0.0.0\", 0, 1, 2);\n  await client.start();\n\n  const peer = client.connect(\"127.0.0.1\", 17091, 2, 0);\n  client.startPolling(15);\n\n  client.emitter.on(\"connect\", p => {\n    console.log(`Connected to server! Peer ID: ${p.id}`);\n  });\n\n  client.emitter.on(\"disconnect\", (p, data) => {\n    console.log(`Disconnected from server. Code: ${data}`);\n  });\n\n  client.emitter.on(\"receive\", (p, packet, channelId) => {\n    const data = packet.data();\n    console.log(`Received packet on channel ${channelId}: ${data.length} bytes`);\n  });\n}\n\nmain();\n```\n\n---\n\n## API Reference\n\n### Initialization\n\n#### `init(input?: any): Promise<void>`\n\nInitializes the WebAssembly core environment for the ENet library. **Must be invoked prior to instantiating any ENet client or server.**\n\nIn Node.js/Bun environments, it automatically locates and reads the compiled WASM binary.\n\n**Parameters:**\n- `input` (optional): WASM binary ArrayBuffer, Buffer, or WebAssembly Module instance.\n\n**Example:**\n```js\nimport { init } from \"@alfianrafli/growtopia.wasm\";\n\nawait init();\n```\n\n---\n\n### Node.js API\n\n#### `NodeENetServer`\n\nHigh-level Node.js ENet Server host configured for server protocol specs.\n\n**Constructor:**\n```ts\nconstructor(\n  bindIp: string,\n  bindPort: number,\n  peerCount: number,\n  channelLimit: number\n)\n```\n\n**Parameters:**\n- `bindIp`: IP address to bind (e.g., `\"0.0.0.0\"` or `\"127.0.0.1\"`)\n- `bindPort`: UDP port number (e.g., `17091`)\n- `peerCount`: Maximum number of peers (e.g., `1024`)\n- `channelLimit`: Number of ENet channels (typically `2`)\n\n**Properties:**\n- `emitter: Emitter<ENetEvents>` - Event emitter for `connect`, `disconnect`, `receive` events\n- `host: Host` - Underlying WebAssembly Host instance\n- `cache.peers: Collection<number, Peer>` - Active peer cache\n\n**Methods:**\n\n##### `start(): Promise<void>`\nBinds the underlying UDP socket to the configured IP address and port.\n\n##### `startPolling(ms?: number, options?: PollingOptions): void`\nStarts an asynchronous polling loop to process incoming and outgoing ENet events at regular intervals.\n\n**Parameters:**\n- `ms`: Polling interval in milliseconds (default: `15`)\n- `options.autoFreePacket`: Automatically free packets after receive event (default: `true`)\n- `options.autoFreePeer`: Reserved for future use\n\n##### `stopPolling(): void`\nStops the active event polling loop.\n\n##### `service(): Event | null`\nDispatches pending ENet network events synchronously. Returns event object or null.\n\n##### `checkEvents(): Event | null`\nChecks for queued ENet events without waiting.\n\n##### `connect(ip: string, port: number, channelCount: number, data: number): Peer`\nConnects to a remote ENet host endpoint.\n\n**Parameters:**\n- `ip`: Target host IP address\n- `port`: Target host UDP port\n- `channelCount`: Number of ENet channels to allocate\n- `data`: User data integer passed in connect request\n\n**Returns:** Connected `Peer` wrapper instance\n\n##### `destroy(): void`\nReleases all resources held by this host: stops polling, closes the underlying UDP socket, and clears the peer cache. **Safe to call multiple times (idempotent).**\n\n**Events:**\n```ts\ninterface ENetEvents {\n  connect: (peer: Peer) => void;\n  disconnect: (peer: Peer, data: number) => void;\n  receive: (peer: Peer, packet: Packet, channel: number) => void;\n}\n```\n\n**Example:**\n```js\nimport { NodeENetServer, init } from \"@alfianrafli/growtopia.wasm\";\n\nawait init();\nconst server = new NodeENetServer(\"0.0.0.0\", 17091, 1024, 2);\nawait server.start();\nserver.startPolling(15);\n\nserver.emitter.on(\"connect\", peer => {\n  console.log(`Peer ${peer.id} connected`);\n});\n\n// Cleanup when done\nserver.destroy();\n```\n\n---\n\n#### `NodeENetClient`\n\nHigh-level Node.js ENet Client host configured for client protocol specs.\n\n**Constructor:**\n```ts\nconstructor(\n  bindIp?: string,\n  bindPort?: number,\n  peerCount?: number,\n  channelLimit?: number\n)\n```\n\n**Parameters:**\n- `bindIp`: IP address to bind (default: `\"0.0.0.0\"`)\n- `bindPort`: UDP port number (default: `0` for automatic assignment)\n- `peerCount`: Maximum number of peers (default: `1`)\n- `channelLimit`: Number of ENet channels (default: `2`)\n\n**Methods:** Same as `NodeENetServer` (inherits from `NodeENetHost`)\n\n**Example:**\n```js\nimport { NodeENetClient, init } from \"@alfianrafli/growtopia.wasm\";\n\nawait init();\nconst client = new NodeENetClient();\nawait client.start();\n\nconst peer = client.connect(\"127.0.0.1\", 17091, 2, 0);\nclient.startPolling(15);\n\nclient.emitter.on(\"connect\", p => {\n  console.log(\"Connected!\");\n});\n\n// Cleanup\nclient.destroy();\n```\n\n---\n\n### Browser API\n\n#### `BrowserENetServer` / `BrowserENetClient`\n\nHigh-level Browser ENet Host wrapper using WebRTC RTCDataChannel transport.\n\n**Constructor:**\n```ts\n// Server\nconstructor(peerCount: number, channelLimit: number)\n\n// Client\nconstructor(peerCount?: number, channelLimit?: number)\n```\n\n**Parameters:**\n- `peerCount`: Maximum number of peers\n- `channelLimit`: Number of ENet channels\n\n**Properties:**\n- `emitter: Emitter<ENetEvents>` - Event emitter\n- `host: Host` - Underlying WebAssembly Host instance\n- `cache.peers: Collection<number, Peer>` - Active peer cache\n\n**Methods:**\n\n##### `attachDataChannel(channel: RTCDataChannel): void`\nAttaches a WebRTC RTCDataChannel for transporting ENet packet payloads.\n\n**Parameters:**\n- `channel`: Open RTCDataChannel instance\n\n**Important:** Must be called before starting polling.\n\n##### `startPolling(ms?: number, options?: PollingOptions): void`\nStarts polling loop (default: 15ms).\n\n##### `stopPolling(): void`\nStops the active event polling loop.\n\n##### `connect(ip: string, port: number, channelCount: number, data: number): Peer`\nInitiates a connection request to a peer endpoint over WebRTC.\n\n##### `destroy(): void`\nReleases all resources held by this host:\n- Stops polling\n- Removes all event listeners from dataChannel\n- Frees WASM Host\n- Clears peer cache\n- Closes dataChannel if open\n\n**Safe to call multiple times (idempotent).**\n\n**Example:**\n```js\nimport { BrowserENetClient } from \"@alfianrafli/growtopia.wasm/browser\";\n\nconst client = new BrowserENetClient(1, 2);\n\n// Setup WebRTC DataChannel\nconst pc = new RTCPeerConnection();\nconst dc = pc.createDataChannel(\"enet\");\n\nclient.attachDataChannel(dc);\nclient.startPolling(15);\n\nclient.emitter.on(\"connect\", peer => {\n  console.log(\"Connected via WebRTC!\");\n});\n\n// Cleanup\nclient.destroy();\n```\n\n---\n\n### Peer API\n\n#### `Peer`\n\nWrapper around an ENet peer connection.\n\n**Properties:**\n- `id: number` - Peer ID\n- `ip: string` - Remote IP address\n- `port: number` - Remote port number\n- `rtt: number` - Round-trip time in milliseconds\n\n**Methods:**\n\n##### `send(packet: Packet): void`\nSends an ENet packet to this peer.\n\n**Parameters:**\n- `packet`: Packet instance (created with `new Packet(data, kind)`)\n\n##### `disconnect(data?: number): void`\nInitiates a graceful disconnect.\n\n**Parameters:**\n- `data`: Optional disconnect reason code (default: `0`)\n\n##### `disconnectNow(data?: number): void`\nImmediately disconnects without waiting for acknowledgment.\n\n##### `disconnectLater(data?: number): void`\nDisconnects after all queued packets are sent.\n\n##### `reset(): void`\nForcefully resets the connection without notification.\n\n**Example:**\n```js\nserver.emitter.on(\"connect\", peer => {\n  console.log(`Peer ID: ${peer.id}`);\n  console.log(`IP: ${peer.ip}:${peer.port}`);\n  console.log(`RTT: ${peer.rtt}ms`);\n  \n  const packet = new Packet(new Uint8Array([1, 2, 3]), PacketKind.Reliable);\n  peer.send(packet);\n  \n  // Disconnect after 5 seconds\n  setTimeout(() => peer.disconnect(0), 5000);\n});\n```\n\n---\n\n### Packet API\n\n#### `Packet`\n\nRepresents an ENet packet.\n\n**Constructor:**\n```ts\nconstructor(data: Uint8Array, kind: PacketKind)\n```\n\n**Parameters:**\n- `data`: Packet payload as Uint8Array\n- `kind`: Packet delivery kind (see `PacketKind` enum)\n\n**Methods:**\n\n##### `data(): Uint8Array`\nReturns the packet payload.\n\n##### `free(): void`\nFrees the packet memory. **Important:** Call this after processing received packets if `autoFreePacket` is disabled.\n\n**Example:**\n```js\nimport { Packet, PacketKind } from \"@alfianrafli/growtopia.wasm\";\n\nconst payload = new Uint8Array([1, 0, 0, 0, 0]);\nconst packet = new Packet(payload, PacketKind.Reliable);\n\npeer.send(packet);\n```\n\n#### `PacketKind` (enum)\n\n- `PacketKind.Reliable` - Guaranteed delivery, ordered\n- `PacketKind.Unreliable` - No delivery guarantee\n- `PacketKind.UnreliableFragment` - Unreliable, fragmented\n- `PacketKind.ReliableFragment` - Reliable, fragmented\n\n---\n\n### Packet Serialization\n\n#### `TextPacket`\n\nRepresents Growtopia text-based packets (action packets, login).\n\n**Static Methods:**\n\n##### `TextPacket.from(type: number, data: string, extra?: string): TextPacket`\nCreates a TextPacket from raw data.\n\n**Parameters:**\n- `type`: Packet type (typically `3` for action packets)\n- `data`: Main payload string\n- `extra`: Optional extra data string\n\n##### `parse(): Uint8Array`\nSerializes the TextPacket into a Uint8Array buffer.\n\n**Example:**\n```js\nimport { TextPacket } from \"@alfianrafli/growtopia.wasm\";\n\nconst textPacket = TextPacket.from(3, \"action|refresh_item_data\", \"\");\nconst buffer = textPacket.parse();\n\nconst packet = new Packet(buffer, PacketKind.Reliable);\npeer.send(packet);\n```\n\n---\n\n#### `TankPacket`\n\nRepresents Growtopia tank packets (state/motion packets).\n\n**Static Methods:**\n\n##### `TankPacket.from(options: Tank): TankPacket`\nCreates a TankPacket from options.\n\n**Parameters:**\n- `options`: Tank packet fields (see `Tank` interface below)\n\n##### `parse(): Uint8Array`\nSerializes the TankPacket into a Uint8Array buffer.\n\n**Tank Interface:**\n```ts\ninterface Tank {\n  packetType?: number;\n  type?: number;\n  punchID?: number;\n  buildRange?: number;\n  punchRange?: number;\n  netID?: number;\n  targetNetID?: number;\n  state?: number;\n  info?: number;\n  xPos?: number;\n  yPos?: number;\n  xSpeed?: number;\n  ySpeed?: number;\n  xPunch?: number;\n  yPunch?: number;\n  data?: () => Buffer;\n}\n```\n\n**Example:**\n```js\nimport { TankPacket } from \"@alfianrafli/growtopia.wasm\";\n\nconst tankPacket = TankPacket.from({\n  type: 0x3,\n  netID: 10,\n  xPos: 100.5,\n  yPos: 200.25\n});\n\nconst buffer = tankPacket.parse();\nconst packet = new Packet(buffer, PacketKind.Reliable);\npeer.send(packet);\n```\n\n---\n\n#### `Variant`\n\nRepresents Growtopia variant list packets.\n\n**Static Methods:**\n\n##### `Variant.from(options: VariantOptions, functionName: string, ...args: VariantArg[]): Variant`\nCreates a Variant packet.\n\n**Parameters:**\n- `options`: Variant options (`netID`, `delay`)\n- `functionName`: Variant function name (e.g., `\"OnConsoleMessage\"`)\n- `args`: Variant arguments (string, number, or number[])\n\n##### `parse(): TankPacket`\nSerializes the Variant into a TankPacket.\n\n**VariantOptions Interface:**\n```ts\ninterface VariantOptions {\n  netID?: number;   // Target netID (default: -1)\n  delay?: number;   // Delay in ms before execution on client\n}\n```\n\n**Example:**\n```js\nimport { Variant } from \"@alfianrafli/growtopia.wasm\";\n\nconst variant = Variant.from(\n  { netID: 1, delay: 0 },\n  \"OnConsoleMessage\",\n  \"Hello Growtopia!\"\n);\n\nconst tankPacket = variant.parse();\nconst buffer = tankPacket.parse();\nconst packet = new Packet(buffer, PacketKind.Reliable);\npeer.send(packet);\n```\n\n---\n\n### Utilities\n\n#### `Collection<K, V>`\n\nGeneric Map wrapper with additional utility methods.\n\n**Methods:**\n- `set(key: K, value: V): void`\n- `get(key: K): V | undefined`\n- `has(key: K): boolean`\n- `delete(key: K): boolean`\n- `clear(): void`\n- `size: number`\n- `forEach(fn: (value: V, key: K) => void): void`\n- `map<T>(fn: (value: V, key: K) => T): T[]`\n- `filter(fn: (value: V, key: K) => boolean): V[]`\n- `find(fn: (value: V, key: K) => boolean): V | undefined`\n\n---\n\n#### `ExtendBuffer`\n\nExtended Buffer utility with additional read/write methods for Growtopia packet structures.\n\n---\n\n#### `crc32(data: Uint8Array): number`\n\nComputes CRC32 checksum.\n\n---\n\n#### `timeSinceEpoch(): number`\n\nReturns current Unix timestamp in milliseconds.\n\n---\n\n#### `mtuMax: number`\n\nMaximum MTU size constant.\n\n---\n\n## Lifecycle & Resource Management\n\n### Initialization\n\n1. **Always call `init()` before instantiating any ENet hosts:**\n   ```js\n   await init();\n   ```\n\n2. **In Node.js/Bun, WASM is auto-initialized on import for synchronous APIs like `NodeENetServer`**\n\n### Event Handling\n\n3. **Subscribe to events using `emitter.on()`:**\n   ```js\n   server.emitter.on(\"connect\", peer => { /* ... */ });\n   server.emitter.on(\"disconnect\", (peer, data) => { /* ... */ });\n   server.emitter.on(\"receive\", (peer, packet, channelId) => { /* ... */ });\n   ```\n\n4. **Start polling to process events:**\n   ```js\n   server.startPolling(15);\n   ```\n\n### Cleanup\n\n5. **Always call `destroy()` when done:**\n   ```js\n   server.destroy();\n   ```\n\n   **What `destroy()` does:**\n   - **Node.js:** Stops polling, closes UDP socket, clears peer cache\n   - **Browser:** Stops polling, removes dataChannel listeners, closes dataChannel, frees WASM Host, clears peer cache\n\n6. **`destroy()` is idempotent** - safe to call multiple times\n\n7. **After `destroy()`, the host instance cannot be reused. Create a new instance if needed.**\n\n### Packet Memory Management\n\n8. **Packets are auto-freed by default** when using `startPolling()` with `autoFreePacket: true` (default)\n\n9. **Manual packet freeing** (if `autoFreePacket: false`):\n   ```js\n   server.emitter.on(\"receive\", (peer, packet, channelId) => {\n     const data = packet.data();\n     // ... process data ...\n     packet.free(); // Free packet memory manually\n   });\n   ```\n\n### Best Practices\n\n- **Don't reuse destroyed hosts** - always create new instances\n- **Call `destroy()` in cleanup handlers** (e.g., `process.on('SIGINT')`, `window.onbeforeunload`)\n- **For Browser API:** Attach dataChannel before starting polling\n- **For Browser API:** Ensure dataChannel is open before calling `connect()` or sending packets\n\n---\n\n## Environment Support\n\n| Environment | Supported | API |\n|-------------|-----------|-----|\n| Node.js ≥ 10 | ✅ Yes | `@alfianrafli/growtopia.wasm` |\n| Bun.js | ✅ Yes | `@alfianrafli/growtopia.wasm` |\n| Browser (WebRTC) | ✅ Yes | `@alfianrafli/growtopia.wasm/browser` |\n| Deno | ⚠️ Untested | - |\n\n**Platform:**\n- Windows ✅\n- Linux ✅\n- macOS ✅\n- Android (Node.js/Bun) ✅\n\n---\n\n## Links\n\n- **npm Package:** [npmjs.com/package/@alfianrafli/growtopia.wasm](https://npmjs.com/package/@alfianrafli/growtopia.wasm)\n- **Repository:** [github.com/AlfianRafli/growtopia.wasm-ng](https://github.com/AlfianRafli/growtopia.wasm-ng)\n- **Issues:** [github.com/AlfianRafli/growtopia.wasm-ng/issues](https://github.com/AlfianRafli/growtopia.wasm-ng/issues)\n- **Discord Community:** [discord.gg/sGrxfKZY5t](https://discord.gg/sGrxfKZY5t)\n\n---\n\n## License & Credits\n\nThis project is open-source software licensed under the [MIT License](LICENSE).\n\n**This project is based on and derived from the original [growtopia.wasm](https://github.com/StileDevs/growtopia.wasm) project by [StileDevs](https://github.com/StileDevs).** Massive thanks to them for laying the foundation.\n\nAll modifications and current maintenance by [Rafli](https://github.com/AlfianRafli).\n","readmeFilename":"README.md"}