aroma

The Native Client game engine powered by Lua

nacl

Interface to the NaCl container.

prefetch

nacl.prefetch ( resource_table )

Causes Aroma to block and fetch a collection of resources at once. The browser will download all the resources in parallel, which will take much less time than requesting them individually.

This will not return any of the resources, it will only cache their values on the client so when you do ask for the request later it will be available without blocking the game.

nacl.prefetch({
  images = {
    "thing.png",
    "world.png",
  }
})

track_event

nacl.track_event ( category , action , label , value , interactive )

This will attempt to send a custom event to Google Analytics. Only works if Google Analytics is available on the game page.

if player.beat_game then
  nacl.track_event("my_game", "player_event", "win")
end

aroma

The aroma object serves two parts. It contains all Aroma submodules, which are also listed on this page, and it is where callback functions are assigned.

Callbacks are functions that you create and assign to the aroma object. They will be called by the engine when certain events happen.

You only need to assign these callback functions when if you are using them, leaving them out is perfectly okay. You should never need to call these functions manually (but you can).

Here is the complete list of callbacks:

draw

aroma.draw ( )

Where all of your drawing code should go.

function aroma.draw()
  aroma.graphics.print("hello world", 10, 10)
end

focus

aroma.focus ( has_focus )

Called when the focus of the game window has changed

function aroma.focus(has_focus)
  print("Focus changed:", has_focus)
end

keypressed

aroma.keypressed ( key_name , key_code )

Called when a key is pressed down. Given two arguments:

  • key_name — A string representing the name of the key pressed

  • key_code — An integer representing the code of the key

function aroma.keypressed(key_name, key_code)
  print("Key pressed:", key_name, key_code)
end

keyreleased

aroma.keyreleased ( key_name , key_code )

Callen when a key is released.

Arguments are the same as aroma.keypressed.

update

aroma.update ( dt )

Where game state updates should go. Takes one argument, dt, the amount of time in seconds since the last frame.

You should not draw from this function, nothing will show up.

function aroma.update(dt)
  player.x = player.x + speed * dt
end

aroma.graphics

Functions responsible for drawing things on the screen or changing the state of drawing.

draw

aroma.graphics.draw ( drawable , x , y , [rotate] , [scale_x] , [scale_y] , [origin_x] , [origin_y] )

Draws a drawable object on the screen. Right now the only drawable objects are images.

rotate is clockwise rotation in degrees.

origin_x and origin_y can be used to control the origin of rotation.

drawq

aroma.graphics.drawq ( drawable , quad , x , y , [rotate] , [scale_x] , [scale_y] , [origin_x] , [origin_y] )

Similar to aroma.graphics.draw, but takes a Quad as second argument.

A Quad can be used to only draw a portion of an image. Useful for drawing sprites from a single image.

local img = aroma.graphics.newImage("hi.png")
local q = aroma.graphics.newQuad(5, 5, 10, 10, img:getWidth(), img:getHeight())

-- draws the part of the image specified by the quad at 10, 10
function aroma.draw()
  aroma.graphics.drawq(img, q, 10, 10)
end

newFont

font = aroma.graphics.newFont ( font_name , [alphabet] )

Creates a new font and returns it. Fonts are rendered by the browser in a <canvas> tag and then passed back to Aroma.

font_name must be a valid CSS font value.

alphabet is an optional string whose characters will be the glyphs available in the font. Defaults to all numbers, letters, and symbols on an English keyboard.

Custom fonts can be made available by embedding fonts into the stylesheet of the host page using @font-face.

local monospace = aroma.graphics.newFont("32px monospace")

-- only numbers can be written with this font
local numbers = aroma.graphics.newFont("10pt serif", "0987654321")

newImage

image = aroma.graphics.newImage ( image_url )

Loads and image by url and returns it as an Image object.

Images can be drawn to the screen using aroma.graphics.draw.

local image = aroma.graphics.newImage("hello.png")

function aroma.draw()
  aroma.graphics.draw(image, 10, 10)
end

newImageFont

font = aroma.graphics.newImageFont ( image , alphabet )

Creates a new font from an image and returns it. Unlike aroma.graphics.newFont, letters are extracted from a bitmap instead a typeface from the browser.

  • image — An image url or an ImageData object.
  • alphabet — A string of letters as they appear in the image.

The image must be formatted as a single row of letters where each letter is separated by a spacer color:

number font

The spacer color is always the top left color in the image, so place a spacer column as the leftmost thing in the image. The spacer column can be any width.

The rightmost part of the image must also be a spacer column, or the last letter will be left out.

-- write some text with the font above
local number_font = aroma.graphics.newImageFont("numbers.png", " 1234567890")
aroma.graphics.setFont(number_font)

function aroma.draw()
  aroma.graphics.print("1337", 10, 10)
end

newQuad

quad = aroma.graphics.newQuad ( x , y , width , height , source_width , source_height )

Creates a new Quad for use with aroma.graphics.drawq.

source_width and source_height are typically the width and height of the image the quad is being used on.

x, y, width, height represent the rectangle that should be drawn from the image.

newShader

shader = aroma.graphics.newShader ( vertex_shader_source , fragment_shader_source )

Create a new shader.

pop

aroma.graphics.pop ( )

Pops the current transformation off the transformation stack.

print

aroma.graphics.print ( [font] , text , x , y , [rotate] , [scale_x] , [scale_y] , [origin_x] , [origin_y] )

Draws text on the screen. If font is not provided, the default font will be used. See aroma.graphics.setFont.

push

aroma.graphics.push ( )

Copies and pushes the current transformation onto the transformation stack.

rectangle

aroma.graphics.rectangle ( [render_style] , x , y , width , height )

Draws a rectangle on the screen.

The color of the rectangle is the current color. See aroma.graphics.setColor.

render_style is an optional string that determines how the rectangle is drawn. "fill" is the default. Must be one of the following:

  • "fill"
  • "line"

reset

aroma.graphics.reset ( )

Resets graphics state to default. This includes:

  • Background color
  • Drawing color
  • Blend mode

rotate

aroma.graphics.rotate ( deg )

Modifies the current transformation to rotate all draws by deg degrees.

The center of origin is at (0,0). It is helpful to combine this with translation control the center of origin relative to the object being drawing.

scale

aroma.graphics.scale ( sx , sy )

Modifies the current transformation by scaling all draws by sx and sy.

setBackgroundColor

aroma.graphics.setBackgroundColor ( red , green , blue , alpha )

Set the color the screen is cleared to after every frame.

getColor

red , green , blue , alpha = aroma.graphics.getColor ( )

Gets the current color for drawing.

setColor

aroma.graphics.setColor ( red , green , blue , [alpha] )

Set the current color for drawing.

-- draw a red rectangle
function aroma.draw()
  aroma.graphics.setColor(255,0,0)
  aroma.graphics.rectangle(10,10, 50,50)
end

setDefaultShader

aroma.graphics.setDefaultShader ( shader )

Replaces the shader responsible for all drawing. Be careful with this. If the shader does not work in a specific way then nothing may be drawn or Aroma may crash.

shader must be a shader created with aroma.graphics.newShader.

setFont

aroma.graphics.setFont ( font )

Sets the current font. font must be a font return by aroma.graphics.newFont.

getFont

font = aroma.graphics.getFont ( )

Gets the current font.

getHeight

height = aroma.graphics.getHeight ( )

Gets the height of the viewport in pixels.

setLineWidth

aroma.graphics.setLineWidth ( width )

Set the width of lines lines drawn.

getWidth

width = aroma.graphics.getWidth ( )

Gets the width of the viewport in pixels.

translate

aroma.graphics.translate ( tx , tx )

Modifies the current transformation by translating all draws by tx and ty.

function aroma.draw()
  aroma.graphics.translate(20, 20)
  -- will be drawn at 25, 25
  aroma.graphics.rectangle(5, 5, 10, 10)
end

Image

Images can be drawn with

getWidth

width = image:getWidth ( )

Gets the width of the image.

getHeight

height = image:getHeight ( )

Gets the height of the image.

setWrap

image:setWrap ( horiz_wrap , vert_wrap )

Sets the wrapping mode of the image when overdrawn (by something like drawq). By default wrap is set to "clamp".

Possible values for each:

  • "clamp" — the color at the edge of the texture will be used to fill the extra space.

  • "repeat" — The texture will repeat to fill extra space.

setFilter

image:setFilter ( min_filter , mag_filter )

Sets how images are filtered when they are scaled. By default wrap is set to "linear" for both min and mag.

  • min_filter — applied when the image is rendered smaller than its original dimensions.

  • mag_filter — applied when the image is rendered larger its original dimensions.

Posible values include:

  • "linear" — The colors of nearby pixels are blended, creates a smoothing effect.

  • "nearest" — no blending is done. This is the best filter to use when working with pixel art.

Font

Represents a loaded font. Created with aroma.graphics.newFont.

Can be drawn with setFont or print.

Quad

Represents a rectangular portion of something. Created with aroma.graphics.newQuad.

Drawn with aroma.graphics.drawq.

flip

quad:flip ( x , y )
  • x — Flips Quad horizontally if true

  • y — Flips Quad vertically if true

aroma.audio

Functions for working with sound.

newSource

audio = aroma.audio.newSource ( source_url , [source_type] )

Loads a new source by url. Returns an AudioSource.

source_type is an optional value that determines how the sound is loaded. "static" is the default. The following types are valid:

  • "static" — The function will block until the entire audio source is loaded into memory and ready be played. Uses the Web Audio API. Suitable for short samples such as sound effects.

  • "streaming" — Uses the <audio> tag. The function will not wait for the entire file to download, will only verify that the file exists. Playback of the sound might be delayed. Can also be unreliable. Suitable for background music.

local bg = aroma.audio.newSource("game/theme.ogg", "streaming")
local effect = aroma.audio.newSource("game/shoot.ogg")

bg:play() -- not guaranteed to play immediately, could still be downloading

effect:play() -- guaranteed to play

AudioSource

A static or stremaing audio srouce. Created with aroma.audio.newSource.

play

source:play ( )

pause

source:pause ( )

stop

source:stop ( )

setLooping

source:setLooping ( looping )

aroma.image

Functions for manipulating images and image data.

newImageData

data = aroma.image.newImageData ( image_url )

aroma.keyboard

Functions for querying information about the keyboard.

isDown

is_down = aroma.keyboard.isDown ( key_name )

Checks if a key is currently pressed down.

function aroma.update()
  if aroma.keyboard.isDown(" ") then
    print("Space is pressed!")
  end
end

aroma.timer

Functions relating to the internal timer.

getFPS

fps = aroma.timer.getFPS ( )

Gets the frames per second of the game.

getTime

time = aroma.timer.getTime ( )

Gets the value of the internal timer in seconds. The value by itself is meaningless but it useful when compared against other times.