wasm4

An opinionated binding for WASM-4, a retro game framework using WebAssembly

game
moon add moonbitlang/wasm4@0.2.9
Download zip
Version
0.2.9
License
Apache-2.0
Last updated
9 months ago
Downloads
60
README

#Wasm4 Binding for MoonBit

This is an opinionated binding for Wasm4 in MoonBit.

#Prerequisites

#Usage

  • Add this package: moon add moonbitlang/wasm4
  • Develop with this package as other packages
  • Optionally export a function called start that will be executed once on initialization and export a function called update that will be executed at 60Hz for the expected backend
  • Import a memory with the module of env and name of memory
  • Build with moon build --target <wasm-gc or wasm> with the respective backend
  • Execute npx wasm4 run <target>.wasm. The target should be located in target/wasm/release/build/<package path>/<package name>.wasm for wasm backend, or target/wasm-gc/release/build/<package path>/<package name>.wasm for wasm-gc backend. The browser should open automatically and display the game. Enjoy

#Examples

The snake example (adapted from the Wasm4 documentation) demonstrates the usage. You may execute

moon build --source-dir example/snake --target wasm npx wasm4 run example/snake/target/wasm/release/build/snake.wasm

and enjoy the game.

#References

#
ADSR

pub struct ADSR {
sustain : UInt
release : UInt
decay : UInt
attack : UInt
}

An ADSR volume envelop

The envelope starts at zero volume, then raises to the peak volume over the attack time, lowers to the sustain volume during the decay time, remains at the sustain volume during the sustain time, and finally fades to zero volume during the release time. Duration of each phase is specified in frames (1/60th of a second).

#
ADSR::new

fn ADSR::new(sustain : UInt, release? : UInt, decay? : UInt, attack? : UInt) -> ADSR

An ADSR volume envelop

The envelope starts at zero volume, then raises to the peak volume over the attack time, lowers to the sustain volume during the decay time, remains at the sustain volume during the sustain time, and finally fades to zero volume during the release time. Duration of each phase is specified in frames (1/60th of a second).

#
ADSRVolume

pub struct ADSRVolume {
sustain : UInt
peak : UInt
}

The volume of an ADSR envelope

The volume used for the sustain duration, and the peak volume (default to 100 if zero) reached by the attack duration.

#
ADSRVolume::new

fn ADSRVolume::new(sustain : UInt, peak? : UInt) -> ADSRVolume

The volume of an ADSR envelope

The volume used for the sustain duration, and the peak volume (default to 100 if zero) reached by the attack duration.

#
BlitFlag

pub(all) struct BlitFlag {
one_bit_per_pixel : Bool
flip_x : Bool
flip_y : Bool
rotate : Bool
}

one_bit_per_pixel: Sprite pixel format: 1BPP or 2BPP flip_x: flip the sprite horizontally flip_y: flip the sprite vertically rotate: rotate the sprite anti-clockwise 90 degrees, applied after any flipping

#
Color

type Color

#
GamePad

pub struct GamePad {
button_1 : Bool
button_2 : Bool
button_left : Bool
button_right : Bool
button_up : Bool
button_down : Bool
}

impl Default for GamePad
impl Eq for GamePad

#
Mouse

pub struct Mouse {
x : Int
y : Int
left : Bool
middle : Bool
right : Bool
}

impl Default for Mouse
impl Eq for Mouse

#
Netplay

pub struct Netplay {
index : UInt
active : Bool
}

Status of netplay

The index is from 1 to 4 (inclusive)

#
Note

pub struct Note {
note : UInt
bend : UInt
}

Notes with pitch bend

@param note Specified in MIDI note format, e.g. 60 = C4, 69 = A4. @param bend Bend note upwards. 0 = Nothing, 255 = One 256th away from the next note above

#
Note::new

fn Note::new(note : UInt, bend? : UInt) -> Note

Notes with pitch bend

@param note Specified in MIDI note format, e.g. 60 = C4, 69 = A4. @param bend Bend note upwards. 0 = Nothing, 255 = One 256th away from the next note above

#
Sprite

type Sprite

#
Sprite::blit

fn Sprite::blit(self : Sprite, x : Int, y : Int, width : Int, height : Int, flags : BlitFlag) -> Unit

Copies pixels to the framebuffer.

@param spritePtr raw pixel data stored in either 1BPP or 2BPP format. @param x X position in the destination framebuffer. @param y Y position in the destination framebuffer. @param width Width of the sprite. @param height Height of the sprite. @param flags Flags that modify behavior.

#
Sprite::blit_sub

fn Sprite::blit_sub(self : Sprite, x : Int, y : Int, width : Int, height : Int, src_x : Int, src_y : Int, stride : Int, flags : BlitFlag) -> Unit

Copies a subregion within a larger sprite atlas to the framebuffer. Same as blit, but with 3 additional parameters.

@param srcX Source X position of the sprite region. @param srcY Source Y position of the sprite region. @param stride Total width of the overall sprite atlas. This is typically larger than width. For info on other parameters, see blit().

#
ToneChannel

pub(all) enum ToneChannel {
Pulse1
Pulse2
Triangle
Noise
}

#
ToneFlag

pub struct ToneFlag {
channel : ToneChannel
mode : ToneMode
pan : TonePan
}

Flags that modify behavior of tone

#
ToneFlag::new

fn ToneFlag::new(channel? : ToneChannel, mode? : ToneMode, pan? : TonePan) -> ToneFlag

Flags that modify behavior of tone

#
ToneMode

pub(all) enum ToneMode {
Duty_1_8
Duty_1_4
Duty_1_2
Duty_3_4
}

#
TonePan

pub(all) enum TonePan {
Center
Left
Right
}

#
disk_read

fn disk_read(bytes : FixedArray[Byte], size : UInt) -> Int

Reads up to size bytes from persistent storage into bytes.

@return the number of bytes read, which may be less than size

#
disk_write

fn disk_write(bytes : FixedArray[Byte], size : UInt) -> Int

Writes up to size bytes from bytes into persistent storage.

Any previously saved data on the disk is replaced. @return the number of bytes written, which may be less than size.

#
get_draw_colors

fn get_draw_colors(index : UInt) -> UInt

Gets the draw color at the given index.

@param index the index of the draw color to get, from 1 to 4 (inclusive) @return the index of the palette that the draw color is set to

#
get_frame_buffer

fn get_frame_buffer(index : UInt) -> UInt

Get the palette index of the pixel at the specified index.

Parameters

  • index : The index of the frame buffer to retrieve. Must be a UInt and should be within the valid range of the frame buffer (0 to 160 * 160 - 1).

Returns

  • the index of the palette.

#
get_gamepad

fn get_gamepad(index? : UInt) -> GamePad

Gets the state of the gamepads.

@param index the index of the gamepad to get, from 1 to 4 (inclusive) @return the state of the gamepads

#
get_mouse

fn get_mouse() -> Mouse

Gets the state of the mouse.

@return the state of the mouse

#
get_netplay

fn get_netplay() -> Netplay

Gets the state of the netplay.

@return the state of the netplay

#
get_palette

fn get_palette(index : UInt) -> Color

Gets the color of the palette at the given index.

@param index the index of the palette to get, from 1 to 4 (inclusive) @return the color at the given index

#
get_system_hide_gamepad_overlay

fn get_system_hide_gamepad_overlay() -> Bool

#
get_system_preserve_framebuffer

fn get_system_preserve_framebuffer() -> Bool

#
hline

fn hline(x : Int, y : Int, len : Int) -> Unit

Draws a horizontal line between (x, y) and (x + len - 1, y)

DRAW_COLORS color 1 is used as the line color

#
line

fn line(x1 : Int, y1 : Int, x2 : Int, y2 : Int) -> Unit

Draws a line between two points

DRAW_COLORS color 1 is used as the line color

#
oval

fn oval(x : Int, y : Int, width : Int, height : Int) -> Unit

Draws an oval (or circle).

DRAW_COLORS color 1 is used as the fill color, DRAW_COLORS color 2 is used as the outline color.

#
rect

fn rect(x : Int, y : Int, width : Int, height : Int) -> Unit

Draws a rectangle.

DRAW_COLORS color 1 is used as the fill color, DRAW_COLORS color 2 is used as the outline color.

#
rgb

fn rgb(color : UInt) -> Color

#
screen_height

let screen_height : UInt

#
screen_width

let screen_width : UInt

#
set_draw_colors

fn set_draw_colors(palette : UInt, index? : UInt) -> Unit

Sets the draw color at the given index.

@param index the index of the draw color to set, from 1 to 4 (inclusive) @param palette the index of the palette to set the draw color to, from 1 to 4 (inclusive), or 0 for transparent

#
set_frame_buffer

fn set_frame_buffer(index : UInt, palette : UInt) -> Unit

Manipulate the framebuffer directly.

@param index the index of the pixel to set, from 0 to 160 * 160 (exclusive) @param palette the index of the palette to set the pixel to, from 1 to 4 (inclusive)

#
set_palette

fn set_palette(index : UInt, color : Color) -> Unit

Sets the color of the palette at the given index.

@param index the index of the palette to set, from 1 to 4 (inclusive) @param color the color to set

#
set_system_hide_gamepad_overlay

fn set_system_hide_gamepad_overlay(b : Bool) -> Unit

#
set_system_preserve_framebuffer

fn set_system_preserve_framebuffer(b : Bool) -> Unit

#
sprite

fn sprite(bytes : FixedArray[Byte]) -> Sprite

#
text

fn text(s : String, x : Int, y : Int) -> Unit

Draws text using the built-in system font. The string may contain new-line (\n) characters.

The font is 8x8 pixels per character DRAW_COLORS color 1 is used as the text color, DRAW_COLORS color 2 is used as the background color.

#
tone

fn tone(frequency : (UInt, UInt), duration : ADSR, volume : ADSRVolume, flags : ToneFlag) -> Unit

Plays a sound tone

@param frequency Start frequency and optional end frequency presented in hertz @param duration Duration of the tone in frames (1/60th of a second), up to 255 frames for each phase @param volume Volume of the sustain and attack durations, between 0 and 100 @param flags Flags that modify behavior

#
tone_note_mode

fn tone_note_mode(frequency : (Note, Note?), duration : ADSR, volume : ADSRVolume, flags : ToneFlag) -> Unit

Plays a sound tone in note mode

@param frequency Start frequency and optional end frequency presented in MIDI note @param duration Duration of the tone in frames (1/60th of a second), up to 255 frames for each phase @param volume Volume of the sustain and attack durations, between 0 and 100 @param flags Flags that modify behavior

#
trace

fn trace(s : String) -> Unit

Prints a message to the debug console

#
vline

fn vline(x : Int, y : Int, len : Int) -> Unit

Draws a vertical line between (x, y) and (x, y + len - 1)

DRAW_COLORS color 1 is used as the line color

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io