New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

alchemy-engine

Package Overview
Dependencies
Maintainers
0
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

alchemy-engine

Create 2D browser games with pixi.js

0.3.0
latest
Source
npm
Version published
Weekly downloads
12
-83.56%
Maintainers
0
Weekly downloads
 
Created
Source

:alembic: alchemy engine

👾 Easily make 2D browser games with pixi.js

:sparkles: Features

  • 100% Type-Safe
  • Batteries included (get started using one CLI command)
  • Reactive - Re-render view when state changes
  • Object pooling
  • Timer - Run logic every X ticks
  • Animations
  • Debug overlay
  • Keyboard input
  • Sounds
  • Sprite sheet generation
  • Scenes
  • CLI - Create project and components
  • CI - Workflows to build, test and deploy to itch.io
  • Screen shake
  • Uses vite for a super fast and modern dev server

Getting started

Run the init command from within a Git repo

npx alchemy@latest init

This will:

  • Copy template files
  • Add alchemy-engine and pixi.js as dependencies

API Docs

Module API

These are imported directly from alchemy-engine

create

Convenience functions to create Pixi objects

sprite
import { sprite } from 'alchemy-engine'

sprite(container, getTexture('./square-1')])
animatedSprite
import { animatedSprite } from 'alchemy-engine'

animatedSprite(container, getTextures(['./square-1', './square-2']))
text
import { text } from 'alchemy-engine'

text(container, textStyle, 'Hello world')
htmlText
import { htmlText } from 'alchemy-engine'

htmlText(container, textStyle, 'Hello world')
bitmapText
import { bitmapText } from 'alchemy-engine'

bitmapText(container, textStyle, 'Hello world')
container
import { container } from 'alchemy-engine'

container(_container)
graphics
import { graphics } from 'alchemy-engine'

graphics(container)
rectangle
import { rectangle } from 'alchemy-engine'

rectangle(container, { x: 0, y: 0, width: 10, height: 10 })

event

onClick

Convenience functions for mouse input

import { onClick } from 'alchemy-engine'

onClick(container, () => {
  console.log('Clicked!')
})
onHover
import { onHover } from 'alchemy-engine'

onHover(container, {
  onOver() {
    console.log('Hovered!')
  },
  onOut() {
    console.log('Not hovered!')
  },
})

sync

sync
syncPosition

keys

arrowKeys

Constants for all arrow keys

import { arrowKeys } from 'alchemy-engine'

export const keys = ['a', 'w', 's', 'd', ...arrowKeys] as const

position

TODO

getAllChildren

TODO

getAllLeafChildren

TODO

debug

logObject

Nicely log a Pixi object. Set label property for best result.

import { logObject } from 'alchemy-engine'

const sprite = new Sprite()
sprite.label = 'sprite'
logObject(sprite)

boundsToString

Enables easier logging of sprite bounds

import { boundsToString } from 'alchemy-engine'

console.log(boundsToString(sprite))

contains

Check if a point is within the bounds of an object

import { contains } from 'alchemy-engine'

if (contains(sprite, { x: 1, y: 1 })) {
  // point is within bounds of sprite
}

intersects

Check if the bounds of two objects are intersecting

import { intersects } from 'alchemy-engine'

if (intersects(sprite1, sprite2)) {
  // sprites are intersecting
}

type guards

isAnimatedSprite
import { isAnimatedSprite } from 'alchemy-engine'

if (isAnimatedSprite(sprite)) {
  // sprite is of type AnimatedSprite
}

loadDataFromImage

This function can be used to for example load a level from image data

import { loadDataFromImage } from 'alchemy-engine'
import map from '~/public/asset/map.png?url'

const { pixels, width, height } = await loadDataFromImage(map)
console.log(pixels)
// ['255-255-255', '0-0-0']

pool

Docs

Scene API

The arguments passed to a scene

{
  textures,
  container,
  input,
  state,
  timer,
  sound,
  app,
  timer,
  useScreenShake,
}: Scene

getTexture

Get a texture

function myScene(scene: Scene) {
  sprite(scene.container, scene.getTexture('./texture-1'))
}

getTextures

Get multiple textures

function myScene(scene: Scene) {
  animatedSprite(
    scene.container,
    scene.getTextures(['./texture-1', './texture-2']),
  )
}

useScreenShake

Enable the use of screen shake

screenShake takes a number between 0 and 1

const screenShake = useScreenShake(container)

screenShake(0.5)

animate

These functions all require an onUpdate and duration argument

Optionally you can pass a startValue (default: 0) and endValue (default: 1)

  • sine
  • easeOut
  • easeIn
  • linear

app

The Pixi Application instance

music

Record<MusicName, Howl>

Example:

scene.music.bgm.loop(true).play()

sound

Record<SoundName, Howl>

Example:

scene.sound.coin.play()

setScene

Takes sceneKey as an argument

setScene('mainMenu')

global

timer

A timer that doesn't get cancelled when changing scenes

container

A scene specific Pixi container. Will be destroyed when scene is changed.

state

Set state to trigger sync and subscribe functions

internalState

subscribe, subscribeKey, proxy

Re-exported from valtio

Changes from valtio versions:

  • Triggers once up front when called
  • Unsubscribes when changing scene

timer

delay

Resolves a promise after X ticks

// Wait 100 updates
await scene.timer.delay(100)

repeatUntil

Execute a callback every update until duration is reached

await scene.timer.repeatUntil(3, (time, deltaTime) => {})

repeatEvery

Execute a callback indefinitely every interval updates

Returns a cancel function

const cancel = repeatEvery(3, (time, deltaTime) => {})

input

debouncedKey

scene.input.debouncedKey(
  'd',
  () => {
    s.position.x += 1
  },
  // Delay between key presses
  10,
)

isKeyDown

Check if a key is currently being pressed

scene.timer.repeatEvery(1, () => {
  if (scene.input.isKeyDown(['a', 'ArrowLeft'])) {
    s.position.x -= 1
  }
  if (scene.input.isKeyDown(['d', 'ArrowRight'])) {
    s.position.x += 1
  }
})

random

There is a built-in seedable random module.

To set the seed, pass it in to createGame

createGame({
  randomSeed: 99,
})

The module uses the same API as park-miller, with some additions:

chance(percentage) => boolean

CLI

dev

Start the dev server. Listens to changes to source code, sprite, src/public/asset/sound and src/public/asset/music folders.

npx alchemy dev

sprite

Generate sprite sheet

npx alchemy sprite

sound

Load sounds

npx alchemy sound

Local development

Run ./go.sh to test that things work

See also

FAQs

Package last updated on 01 Mar 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts