{"_id":"5velte-ph4ser","_rev":"3-b3f3f832051216dacdbf0022afc908d3","name":"5velte-ph4ser","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"5velte-ph4ser","version":"1.0.0","keywords":["svelte","phaser","game","webgl"],"license":"MIT","_id":"5velte-ph4ser@1.0.0","maintainers":[{"name":"codemonkey.games","email":"daniel@codemonkey.games"}],"homepage":"https://github.com/easierbycode/svelte-phaser#readme","bugs":{"url":"https://github.com/easierbycode/svelte-phaser/issues"},"dist":{"shasum":"9c4094c26dee1638d47a9db9e8edc195a4854d68","tarball":"https://registry.npmjs.org/5velte-ph4ser/-/5velte-ph4ser-1.0.0.tgz","fileCount":25,"integrity":"sha512-EktfL/F3HcNci+x/QH3JF9Lnvx8LMfA4rLTuerMJT4ZzF63uzPrZ1UGMJDToEsk5SYpFMVb30R2axcVgzR3STA==","signatures":[{"sig":"MEQCIFny5FjbpqkOkTCXSz8nMqnaZ86sV7zqXBjXsd4vxDD6AiB1KTL4Br2RJJpoRuCICwtu8CTMm9IQnQerynd/8ZJS0A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62615},"type":"module","types":"./src/index.ts","svelte":"./src/index.ts","exports":{".":{"types":"./src/index.ts","svelte":"./src/index.ts","default":"./src/index.ts"},"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"}},"gitHead":"18a5131372e3b968f6a39ed9608992d8a69c68cc","_npmUser":{"name":"codemonkey.games","email":"daniel@codemonkey.games"},"repository":{"url":"git+https://github.com/easierbycode/svelte-phaser.git","type":"git"},"_npmVersion":"10.8.2","description":"Svelte 5 components and hooks for building Phaser 4 games","directories":{},"_nodeVersion":"22.5.1","_hasShrinkwrap":false,"devDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"peerDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/5velte-ph4ser_1.0.0_1783546562447_0.828334340586641","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"5velte-ph4ser","version":"1.0.1","keywords":["svelte","phaser","game","webgl"],"license":"MIT","_id":"5velte-ph4ser@1.0.1","maintainers":[{"name":"codemonkey.games","email":"daniel@codemonkey.games"}],"homepage":"https://github.com/easierbycode/svelte-phaser#readme","bugs":{"url":"https://github.com/easierbycode/svelte-phaser/issues"},"dist":{"shasum":"a2855e904b7f29f1100eb5f2fc867fcb766fa01a","tarball":"https://registry.npmjs.org/5velte-ph4ser/-/5velte-ph4ser-1.0.1.tgz","fileCount":25,"integrity":"sha512-M085DFIFfj2TkKrxVjIPJozVfgNxXHG4yeV3jOtfzYtqlljwm1474sQeCcC4pZ8kNI8PaOJUcHwU3pB08VFTUQ==","signatures":[{"sig":"MEUCIGrFkpUNXZYjDjHTbnkKH0p9O3tgltP2jdzxC9OO7ASLAiEAxbly4UzK0km6wyx0hA4HB+fLUBsh3YnVf1GBOKvNfdg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64348},"type":"module","types":"./src/index.ts","svelte":"./src/index.ts","exports":{".":{"types":"./src/index.ts","svelte":"./src/index.ts","default":"./src/index.ts"},"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"}},"gitHead":"96e5ac202f5b2fbe4346109a1b82aebbb960b9ed","_npmUser":{"name":"codemonkey.games","email":"daniel@codemonkey.games"},"repository":{"url":"git+https://github.com/easierbycode/svelte-phaser.git","type":"git"},"_npmVersion":"10.8.2","description":"Svelte 5 components and hooks for building Phaser 4 games","directories":{},"_nodeVersion":"22.5.1","_hasShrinkwrap":false,"devDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"peerDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/5velte-ph4ser_1.0.1_1784471242247_0.20773340056474976","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"5velte-ph4ser","version":"1.0.2","description":"Svelte 5 components and hooks for building Phaser 4 games","license":"MIT","repository":{"type":"git","url":"git+https://github.com/easierbycode/svelte-phaser.git"},"type":"module","svelte":"./src/index.js","types":"./src/index.js","exports":{".":{"svelte":"./src/index.js","types":"./src/index.js","default":"./src/index.js"},"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"}},"keywords":["svelte","phaser","game","webgl"],"devDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"peerDependencies":{"phaser":"^4.0.0","svelte":"^5.0.0"},"gitHead":"96e5ac202f5b2fbe4346109a1b82aebbb960b9ed","_id":"5velte-ph4ser@1.0.2","bugs":{"url":"https://github.com/easierbycode/svelte-phaser/issues"},"homepage":"https://github.com/easierbycode/svelte-phaser#readme","_nodeVersion":"24.18.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-IxTOA9Sk/WgZ3ai19WJeyJCmgMPo22vKghFlWZogTYHaipUZf1HLyYA48OfRWIOM3VyC8C2Hac304OSN1ENeYg==","shasum":"1e006790a280a104829ea1324bc3750802ee9753","tarball":"https://registry.npmjs.org/5velte-ph4ser/-/5velte-ph4ser-1.0.2.tgz","fileCount":25,"unpackedSize":65412,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCT/+eq2F7MJfSHL6hMFrlIgkEp0mzm3JkMvtYxoQQ8oAIhAM7LOGRPIL190nRxjo2XG5EzHnc1gjMHmUz3+BLV26cQ"}]},"_npmUser":{"name":"codemonkey.games","email":"daniel@codemonkey.games"},"directories":{},"maintainers":[{"name":"codemonkey.games","email":"daniel@codemonkey.games"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/5velte-ph4ser_1.0.2_1787104839780_0.7343103132961353"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-08T21:36:02.386Z","modified":"2026-08-19T02:00:40.099Z","1.0.0":"2026-07-08T21:36:02.592Z","1.0.1":"2026-07-19T14:27:22.391Z","1.0.2":"2026-08-19T02:00:39.940Z"},"bugs":{"url":"https://github.com/easierbycode/svelte-phaser/issues"},"license":"MIT","homepage":"https://github.com/easierbycode/svelte-phaser#readme","keywords":["svelte","phaser","game","webgl"],"repository":{"type":"git","url":"git+https://github.com/easierbycode/svelte-phaser.git"},"description":"Svelte 5 components and hooks for building Phaser 4 games","maintainers":[{"name":"codemonkey.games","email":"daniel@codemonkey.games"}],"readme":"# svelte-phaser\r\n\r\nSvelte 5 components and hooks for building [Phaser 4](https://phaser.io) games.\r\n\r\nA modern rewrite of the original [svelte-phaser](https://github.com/mattjennings/svelte-phaser)\r\n(Svelte 3 / Phaser 3) using runes, snippets and callback props — targeting\r\nSvelte ^5 and Phaser ^4.\r\n\r\n## The two layers\r\n\r\n| Layer | What | Where it works |\r\n| --- | --- | --- |\r\n| **Core** (`svelte-phaser/core`, JSR: `@easierbycode/svelte-phaser`) | Pure TypeScript: context getters, event hooks, prop appliers, and compiler-free hooks (`useSprite`, `useArcadePhysics`, `createGame`, …). Reactivity flows out through `svelte/store` and in through per-step prop syncing — no runes, no `.svelte` files. | Anywhere — including installed from **JSR**, which only accepts JS/TS modules. |\r\n| **Components** (`svelte-phaser`) | `.svelte` components (`<Game>`, `<Scene>`, `<Sprite>`, …) built on the core, with fine-grained `$effect` prop bindings. | npm / workspace installs, where your bundler's Svelte plugin compiles library source. |\r\n\r\n> Why the split? JSR's module graph only accepts JavaScript/TypeScript — `.svelte`\r\n> files (and rune code, which needs the Svelte compiler) cannot be published there\r\n> ([jsr-io/jsr#861](https://github.com/jsr-io/jsr/issues/861)). The core layer is\r\n> designed to be fully usable without the compiler, so the JSR package is a real,\r\n> working game-binding API — not a stub.\r\n\r\n## Install\r\n\r\nFrom JSR (core API):\r\n\r\n```sh\r\nnpx jsr add @easierbycode/svelte-phaser\r\n```\r\n\r\nFrom a workspace / local checkout (components + core) — note the unscoped\r\n`svelte-phaser` name on the npm registry belongs to the original Svelte 3\r\nproject, so install this package by path:\r\n\r\n```sh\r\nnpm install phaser svelte\r\nnpm i 5velte-ph4ser\r\n```\r\n\r\n(see [examples/dino](examples/dino), which consumes it via `file:../..`)\r\n\r\n## Components example\r\n\r\n```svelte\r\n<script lang=\"ts\">\r\n  import Phaser from 'phaser'\r\n  import { Game, Scene, Sprite, Text } from 'svelte-phaser'\r\n\r\n  function preload(scene: Phaser.Scene) {\r\n    scene.load.image('player', 'assets/player.png')\r\n  }\r\n</script>\r\n\r\n<Game width={800} height={600} physics={{ default: 'arcade' }}>\r\n  <Scene key=\"main\" {preload}>\r\n    {#snippet loading(progress)}\r\n      <Text x={400} y={300} text={`Loading ${Math.round(progress * 100)}%`} />\r\n    {/snippet}\r\n\r\n    <Sprite texture=\"player\" x={400} y={300} />\r\n  </Scene>\r\n</Game>\r\n```\r\n\r\n### Components\r\n\r\n- `<Game>` — creates the `Phaser.Game`. Accepts game config as props, a\r\n  `booting` snippet, and `bind:instance`.\r\n- `<Scene key>` — creates and registers a `Phaser.Scene`. Accepts `preload` /\r\n  `create` / `init` callbacks, a `loading` snippet (receives progress 0–1),\r\n  and `bind:instance`.\r\n- `<Sprite>`, `<Text>`, `<TileSprite>`, `<Rectangle>`, `<Container>` — game\r\n  objects. Props apply reactively; omitted props keep Phaser defaults.\r\n  Phaser events surface as callback props (`onpointerdown`,\r\n  `onanimationcomplete`, …).\r\n- `<ArcadePhysics>` — enables an arcade body on the parent game object\r\n  (`velocityX`, `bounce`, `collideWorldBounds`, `circle`, …).\r\n- `<ArcadeCollider with={...} overlapOnly oncollide={...}>` — collides the\r\n  parent game object with other objects, or with names (string targets are\r\n  matched against `gameObject.name`, including objects spawned later).\r\n- `<Spawner>` — provides `getSpawner()` context so gameplay code can\r\n  imperatively `spawn(Component, props)` (bullets, pickups, …). Spawned\r\n  components receive an `onDestroy` prop to remove themselves.\r\n\r\n### Context + events (both layers)\r\n\r\n```ts\r\nimport {\r\n  getGame, getScene, getSpawner, getGameObject, getContainer,\r\n  onGameEvent, onSceneEvent, onInputEvent, onArcadePhysicsEvent,\r\n} from 'svelte-phaser'\r\n\r\nconst scene = getScene()\r\nonGameEvent('step', () => { /* runs every game step */ })\r\nonInputEvent('pointerdown', () => { /* ... */ })\r\n```\r\n\r\n## Hooks example (core / JSR API)\r\n\r\nThe hooks create the same objects without any library `.svelte` files. Pass a\r\nprops *getter* — it is re-read every game step and only changed values are\r\nre-applied to Phaser:\r\n\r\n```svelte\r\n<script lang=\"ts\">\r\n  import { createGame, createScene, useSprite, useArcadePhysics }\r\n    from '@easierbycode/svelte-phaser'\r\n\r\n  // inside your own components:\r\n  const sprite = useSprite(() => ({ texture: 'player', x, y }))\r\n  useArcadePhysics(() => ({ velocityX, collideWorldBounds: true }), sprite)\r\n</script>\r\n```\r\n\r\n- `createGame(config)` → `{ game, booted }` (`booted` is a store)\r\n- `createScene({ key, preload, create })` → `{ scene, loading, progress }` (stores)\r\n- `createSpawner()` → `{ spawn }` — mounts components imperatively with the\r\n  current context (uses Svelte's public `mount`/`unmount`)\r\n- `useSprite / useText / useTileSprite / useRectangle / useContainer(getProps)`\r\n- `useArcadePhysics(getProps, gameObject?)`, `useArcadeCollider(props, gameObject?)`\r\n- `applyGameObjectProps(...)` etc. — the underlying idempotent prop appliers\r\n\r\nAll hooks must be called during component initialisation (they use Svelte\r\ncontext and lifecycle under the hood).\r\n\r\n## Examples\r\n\r\n- [examples/dino](examples/dino) — a complete dino-runner game (a port of\r\n  [dino](https://github.com/easierbycode/dino)): runes-driven game state\r\n  rendered declaratively with `<Container>`/`<Rectangle>`/`<Text>`, keyed\r\n  `{#each}` obstacle spawning, `onGameEvent`/`onInputEvent`, and reactive\r\n  theme/color customization. `cd examples/dino && npm install && npm run dev`.\r\n  The deployable full-stack version (Deno Deploy + PostgreSQL leaderboard)\r\n  lives at [dino-sp](https://github.com/easierbycode/dino-sp).\r\n- [mario-sp](https://easierbycode.com/mario-sp)\r\n\r\n## Publishing\r\n\r\n- **JSR**: `npx jsr publish` from this directory publishes the core layer as\r\n  `@easierbycode/svelte-phaser` (see `jsr.json`). Run `npm install` here first\r\n  so the bare `svelte`/`phaser` specifiers type-check, then validate with\r\n  `npx jsr publish --dry-run`.\r\n- **npm**: the package ships uncompiled `.svelte`/TS source, which\r\n  `@sveltejs/vite-plugin-svelte` compiles in the consuming app (the `svelte`\r\n  export condition points at the source). The unscoped `svelte-phaser` npm\r\n  name is taken by the original project, so publishing to npm requires a\r\n  scoped rename (e.g. `@easierbycode/svelte-phaser`) in package.json.\r\n\r\n## Requirements\r\n\r\n- svelte ^5.0\r\n- phaser ^4.0\r\n- For the component layer: a bundler with the Svelte plugin\r\n  (e.g. Vite + `@sveltejs/vite-plugin-svelte`)\r\n","readmeFilename":"README.md"}