API:Functions

From Spherical
Jump to: navigation, search

This is a function reference for the Sphere v2 API. It is currently based on the official miniSphere API reference.

The plan, in the future, is to turn this page into a simple list enumerating all Sphere functions, objects and methods, and leave the explanatory details to the individual articles.


Making new function/object pages

Simple steps:
  1. Before getting started, please check the Article standards and practices.
  2. Click a red link.
  3. Place the following code in the empty edit box:
    1. For a new function: {{subst:functemp|preamble=REPLACEME|function=REPLACEME|object=REPLACEME|returns=REPLACEME|params=REPLACEME}}
    2. For a new object: {{subst:objecttemp|preamble=REPLACEME|function=REPLACEME|object=REPLACEME|returns=REPLACEME|params=REPLACEME}}
  4. Check the minor edit flag and save.
  5. Click 'edit' at the top of the page to add content.
  6. Try to be objective when writing, and save when you're done.
  7. Remove description from this page, add page link to list at the top of the matching section.


Sphere v2 Core API Reference

As the successor to the original Sphere engine, miniSphere implements nearly the entire Sphere v1 API. However, the v1 API is quite dated and, as of miniSphere 4.0, has been deprecated in its entirety. It is not documented here at all; while games using the legacy functions will continue to run, new code should be written against the modern Sphere v2 API, documented here.

To ease migration of existing Sphere v1 codebases to Sphere v2, legacy and modern API calls may be freely intermingled within the same codebase, and this is true even when the engine is running in compatibility mode.

JSON Game Manifest (game.json)

To take full advantage of the Sphere v2 platform, a game package must include a file named game.json in its root directory. This file holds metadata such as the title and author, as well as some control information which affects how the engine runs the game.

Here's a sample manifest:

{
    "version": 2,
    "name": "Spectacles: Bruce's Story",
    "author": "Fat Cerberus",
    "summary": "Follow Scott Starcross in his quest to stop the Primus.",
    "resolution": "320x240",
    "main": "main.js"
}

JSON fields defined by the Sphere v2 specification are documented below. Because the manifest format is JSON, as many additional fields may be added as needed, and their values accessed from JavaScript through Sphere.Game.

"version" [default: 2]

The Sphere standards version the game was developed against.  If this is 2,
the game runs in Sphere v2 mode.  In Sphere v2 mode, the main script is
loaded as a CommonJS module, which enables use of relative paths in
require() calls (see below), as well as ensuring variable and function
declarations remain local to the module.

If this is 1, the game runs in Sphere v1 compatibility mode.  In this mode,
the main module is executed as normal program code, and miniSphere calls
the global game() function--if one is provided--to begin game execution.

Note: Regardless of the version specified, both Sphere v1 and v2 APIs will
      be available for use by game code.  The version in the manifest
      currently only affects the way the main module is run.  This may
      change in the future, however.

"author" [default: none]

The name of the person or company who developed the game.

"main" [required]

The SphereFS path of the main JavaScript module (see below for more on
SphereFS).  This is the script miniSphere will run when the game is
started.  If no "main" field is present, the game will not start.

"name" [default: "Untitled"]

The title of the game.  This field must be present; if it is not, the game
will not start.

"resolution" [required]

The default screen resolution of the game, expressed as a string of the
form "WxH", specifying the number of pixels across and down.  For example,
720p resolution would be expressed as "1280x720".

Note: The resolution can be changed at runtime by calling screen.resize().

"summary" [default: none]

A short summary of the game.  While there is no imposed length limit, it
is recommended to keep this short (150 characters or less) with no line
breaks.

SphereFS File System

Sphere uses the SphereFS standard to interpret file paths. Under SphereFS, when a relative path is used in an API call, it will be resolved relative to the root of the game package (where game.json is located). To load files from a different location, you can use one of the SphereFS prefixes:

@/: The root of the game's sandboxed file system.  Usually redundant, but
    can be useful to qualify filenames in situations where a bare SphereFS
    filename is ambiguous, for example in a require() call.  This directory
    is read-only; trying to save or modify anything here will throw a
    TypeError.
#/: The engine's system directory.  This contains assets included with the
    engine.  As with `@/`, this is read-only to Sphere games.
~/: The current user's save data directory.  This is generally used to
    store save data and such where the user can easily access it.  Note
    that all games share the same physical directory for this.  That allows
    games to easily share save data.

As an example, the following will create a FileStream which allows reading from the file EatyPig.bin residing in the user's save data directory.

var file = new FileStream('~/EatyPig.bin', FileOp.Read);

Note: Absolute paths are forbidden, and any attempt to circumvent the sandbox to break into the underlying file system, e.g. "@/../maggie.fat", will be met with a sandbox violation error.

Importing

Sphere v2 Platform API

The Sphere object is provided to allow games to communicate with the underlying Sphere v2 platform. The Sphere object's properties provide access to the engine's name and version number as well as the API level supported, and there are also several methods for managing engine execution.

Sphere.Platform [read-only]

The name of the engine.  In our case, that's "miniSphere".

Sphere.Version [read-only]

The version number of the engine; e.g. "X.X.X".

Sphere.APIVersion [read-only] Sphere.APILevel [read-only]

The API version and level supported by the engine, respectively.  The API
version indicates which version of the Sphere API is supported (currently
v2), while the API level reflects the level of functionality within a
version.  When new classes, methods, or properties are added to the Core
API without breaking compatibility, the API level is bumped.

Sphere.Game [read-only]

An object whose properties describe the currently running game.  The object
consists of everything in the JSON manifest plus any fields synthesized by
the engine.

Sphere.abort(message);

Unconditionally aborts execution and displays an error screen before
closing the engine.  `message` will be displayed on the error screen.

Note: Sphere.abort() bypasses all exception handling mechanisms, including
      the debugger.  Be sure you know what you're doing before you call
      this function.

Sphere.exit();

Shuts down the engine.  Be careful; this function will not return, so any
unsaved data will be lost.

Sphere.restart();

Restarts the currently running game from scratch, as though it were just
loaded.  Unsaved data will be lost.

Sphere.run();

Runs a single iteration of the Sphere v2 event loop.  This function always
returns true, allowing it to be used as part of a loop condition; for
example:

    while (!isDone && Sphere.run()) {
        // do stuff here
    }

Note: Be careful.  This function runs all pending immediate jobs in the job
      queue.  That may lead to undesirable side effects if a Dispatch job
      modifies a global variable, for example.

Sphere.sleep(timeout);

Suspends JavaScript execution for the specified amount of time.  `timeout`
is in seconds, and may include fractions (e.g., 1.5).

Note: Any pending Dispatch.now() jobs will be run before sleeping.
      Depending on how long that takes, Sphere.sleep() may take longer than
      expected to return.

Dispatch API

The Dispatch API is used to set up asynchronous function calls which are later performed from a designated part of the Sphere event loop. This is like an advanced version of Sphere v1 update and render scripts, but better integrated and available throughout the engine.

Dispatch.cancel(token);

Cancels the job associated with JobToken `token`.  Note that for one-time
jobs, cancellation has no effect if the job has already been processed.

Dispatch.cancelAll();

Cancels all one-time jobs currently in the job queue.  To help prevent
mishaps, recurring jobs are not affected by this call and must be cancelled
individually.

Dispatch.later(num_frames, fn);

Sets up a one-time job to call `fn` from the event loop after a specified
number of frames have passed.

Returns a JobToken for use with Dispatch.cancel().

Dispatch.now(fn);

Sets up a one-time job to call `fn` from the event loop on the next tick.
This is useful for performing operations that need to be done from the
event loop with minimal delay.

Returns a JobToken for use with Dispatch.cancel().

Note: Dispatch.now(fn) is *NOT* an alias for Dispatch.later(0, fn).  The
      latter runs at the beginning of the next frame; Dispatch.now() always
      runs on the very next tick even if no frame processing is done.

Dispatch.onRender(fn[, priority]); Dispatch.onUpdate(fn[, priority]);

Sets up a recurring job to call `fn` from a given part of the event loop.
For example, `onRender()` jobs are called before the backbuffer is flipped,
and `onUpdate()` jobs are called at the start of a frame.

`priority` affects the order of calls when there is more than one job.
Render jobs are performed in ascending priority order, while update jobs
are performed in descending priority order.  If no priority is given, the
default is 0.0.  Priority can be negative, and fractional priorities are
honored: 8.12, for example, is considered a higher priority than 8.0.

Returns a JobToken for use with Dispatch.cancel().

Note: Update jobs are processed at the beginning of a frame, while render
      jobs are processed at the end, just before the backbuffer is flipped.
      This ensures that:

      1) Frame loops always have access to up-to-date game state for the
         current frame.
      2) Objects drawn by an asynchronous render job can't be obscured by
         those rendered synchronously.

Random Number Generator API

Games often have need of a good psuedorandom number generator, particularly in the case of RPGs. JavaScript provides a basic generator in the form of Math.random(). Sphere v2 takes it a step further with the powerful RNG object.

miniSphere uses the xoroshiro128+ algorithm to generate high-quality random numbers and allows manually seeding the generator, as well as saving and restoring the exact state of the generator at any time. RNG state is often saved along with other save data as a way to deter save scumming.

RNG.fromSeed(seed);

Constructs a new random number generator seeded using the specified value.
The specific sequence of numbers generated is entirely defined by the seed:
Two generators running in parallel, initialized with the same seed, will
always produce the same sequence.

`seed` is a number greater than zero.  If the seed is fractional, only the
integer part is used; everything after the decimal point is ignored.

RNG.fromState(state);

Constructs a new random number generator which starts in the specified
state.  See RNG#state for more information.

new RNG();

Constructs a new random number generator seeded from the current system
time.

RNG#state [read/write]

Gets or sets the current state of this generator.  State is encoded as
a 32-digit hexadecimal string which makes it easy to save and restore.

When setting `RNG#state`, the string given must be exactly 32 characters
and consist only of hexadecimal digits (0-9, A-F), otherwise a TypeError
will be thrown.

RNG#next();

Gets the next random number in the sequence.  Value returned is in the
range [0-1).

Keyboard Routines

What would a game be without the ability for the player to control it? This set of functions allows your game to accept input via the keyboard, the most common input method for a PC game.

Key [enumeration]

Specifies a keyboard key.  Can be one of the following:

    Key.Alt
    Key.AltGr
    Key.Apostrophe
    Key.Backslash
    Key.Backspace
    Key.CapsLock
    Key.CloseBrace
    Key.Comma
    Key.Delete
    Key.Down
    Key.End
    Key.Enter
    Key.Equals
    Key.Escape
    Key.F1
    Key.F2
    Key.F3
    Key.F4
    Key.F5
    Key.F6
    Key.F7
    Key.F8
    Key.F9
    Key.F10
    Key.F11
    Key.F12
    Key.Home
    Key.Hyphen
    Key.Insert
    Key.LCtrl
    Key.LShift
    Key.Left
    Key.NumLock
    Key.OpenBrace
    Key.PageDown
    Key.PageUp
    Key.Period
    Key.RCtrl
    Key.RShift
    Key.Right
    Key.ScrollLock
    Key.Semicolon
    Key.Slash
    Key.Space
    Key.Tab
    Key.Tilde
    Key.Up
    Key.A
    Key.B
    Key.C
    Key.D
    Key.E
    Key.F
    Key.G
    Key.H
    Key.I
    Key.J
    Key.K
    Key.L
    Key.M
    Key.N
    Key.O
    Key.P
    Key.Q
    Key.R
    Key.S
    Key.T
    Key.U
    Key.V
    Key.W
    Key.X
    Key.Y
    Key.Z
    Key.D1
    Key.D2
    Key.D3
    Key.D4
    Key.D5
    Key.D6
    Key.D7
    Key.D8
    Key.D9
    Key.D0
    Key.NumPad1
    Key.NumPad2
    Key.NumPad3
    Key.NumPad4
    Key.NumPad5
    Key.NumPad6
    Key.NumPad7
    Key.NumPad8
    Key.NumPad9
    Key.NumPad0
    Key.NumPadEnter
    Key.Add
    Key.Decimal
    Key.Divide
    Key.Multiply
    Key.Subtract

Note: Keys D0-D9 refer to the row of numbers above the letter keys and
      below the function keys, while NumPad0-NumPad9 refer to the numbers
      on the numeric keypad.

Keyboard.Default [read-only]

Gets the default keyboard device.  miniSphere currently only supports a
single keyboard.

Keyboard#capsLock [read-only] Keyboard#numLock [read-only] Keyboard#scrollLock [read-only]

Gets the state of the corresponding lock key.  true if the lock is on,
false if not.

Keyboard#clearQueue();

Removes all keys from the keyboard queue.  If another key is not pressed
in the interim, the next getKey() will return null.

Keyboard#getChar(key, shifted);

Gets the character(s) that would be generated if a specified key is pressed
on this keyboard.  For example, Key.A becomes "a" (or "A" if shifted).
`shifted` specifies whether to assume the Shift key is pressed.

An empty string is returned if the specified key is not associated with a
character (a modifier key, for example).

Keyboard#getKey();

Gets the next key in the keyboard queue, or null if the queue is empty.

Keyboard#isPressed(key);

Returns true if the user is currently pressing the specified key.  `key`
should be a member of the Key enumeration.

Joystick Routines

Joystick.Null [read-only]

Gets the null joystick.  When polled, a null joystick returns neutral
values for all inputs.  Joystick.Null can be used in place of a real
Joystick object to simplify input code.

Joystick.getDevices();

Gets an array of Joystick objects, one for each connected gamepad or
joystick.

Joystick#name [read-only]

Gets the name of the device, as reported by the Allegro backend.  Xbox
controllers are reported as "XInput Joystick <n>"

Joystick#numAxes [read-only]

Gets the number of analog axes supported by the device.

Joystick#numButtons [read-only]

Gets the number of buttons supported by the device.

Joystick#getPosition(axisID);

Polls the device and gets the current position along the specified analog
axis.  To get the number of axes supported by a device, use the `numAxes`
property.

Note: Axes are numbered sequentially, starting from 0.  Which physical axis
      is associated with any given axis ID will vary from device to device.
      For gamepads with analog sticks, though, it's generally a safe bet
      that the primary analog stick will be mapped to the first two axes.

Joystick#isPressed(buttonID);

Polls the device and returns true if the specified button is currently
depressed.  To get the number of buttons supported by a device, use the
`numButtons` property.

Note: Buttons are numbered sequentially, starting from 0.  As with axes,
      which physical button is associated with any given button ID will
      vary from device to device.

Mouse Routines

These methods allow access to the mouse, another common input method for games. As with the Keyboard API, the Mouse API provides access to an event queue which accumulates mouse clicks and other events until the game is ready to process them.

MouseKey [enumeration]

Specifies a mouse click or other event (such as a wheel movement).  Can
be one of the following:

    MouseKey.Left
    MouseKey.Middle
    MouseKey.Right
    MouseKey.WheelUp
    MouseKey.WheelDown

Mouse.Default [read-only]

Gets the default mouse device.  miniSphere currently only supports a single
mouse.

Mouse#x [read-only] Mouse#y [read-only]

Gets the immediate X and Y position of the mouse cursor relative to the
game's rendering area.

Mouse#clearQueue();

Removes all events from this mouse's event queue.  If another event is not
received in the interim, the next getEvent() will return null.

Mouse#getEvent();

Gets the next event in this mouse's event queue.  `null` is returned if the
queue is empty.

The object returned has the following properties:

    event.key

        A MouseKey value representing the type of the click or other event.
        For example, a left mouse click is represented as MouseKey.Left.

    event.x
    event.y

        The X and Y position of the mouse cursor relative to the rendering
        area at the time the event was received.

Mouse#isPressed(key);

Gets whether the specified mouse button is currently pressed.  `key` is one
of the MouseKey constants listed above.

Note: This function always returns false for virtual keys such as WheelUp
      and WheelDown.

Graphics API

Unlike in Sphere 1.x, in second-generation games all rendering, both 2D and 3D, is done through the Galileo API. Galileo represents a more modern, polygon- based approach to graphics. Scenes are built from groups of Shape objects representing graphics primitives (triangle strips, fans, etc.).

screen [global variable]

A Surface object (see below) representing the primary render target--
specifically, the backbuffer.  Anything drawn to this surface will become
visible to the player when calling `screen.flip()`.

screen.frameRate [read/write]

Gets or sets the frame rate used to regulate `screen.flip()` (see below).
Set this to Infinity to disable the frame limiter.

screen.frameSkip [read/write]

Gets or sets the maximum number of frames the engine is allowed to skip in
order to maintain the desired frame rate.

screen.fullScreen [read/write]

Gets or sets whether the engine is running in fullscreen mode.  Set this to
`true` for fullscreen, or `false` for windowed.

screen.width [read-only] screen.height [read-only]

Gets the width and height of the screen resolution.

screen.clipTo(x, y, width, height);

Changes the clipping rectangle.  Anything drawn outside of the clipping
rectangle won't be rendered.  The effect lasts until the next backbuffer
flip.

screen.flip();

Performs event loop processing and flips the backbuffer to the screen.
`screen.frameRate` determines the maximum number of flips to perform per
second; this makes it easier to regulate your game's update rate.

After a flip, the backbuffer is cleared to black.  If you need to perform a
long operation without disturbing the contents of the screen, you should
use Sphere.run() instead of screen.flip() to run the event loop.

Note: Calling screen.flip() resets the clipping rectangle.  See the entry
      for screen.clipTo() above.

screen.now();

Returns the number of frames (including skipped frames) processed by the
engine since it started running.

Note: This value will wrap around to zero after around 4.3 billion frames.
      That typically isn't an issue: at 60 FPS, a game would need to run
      continuously for *over 2 years* before it would roll over.

screen.resize(width, height);

Changes the game's resolution.  The change is not persistent and lasts only
until the engine is closed.

Color.Red [read-only] Color.Green [read-only] Color.Blue [read-only] Color.Transparent [read-only] etc...

Gets a copy of a predefined color.  The entire X11 color set is provided,
giving you access to such colors as `DodgerBlue` and `Chartreuse` in
addition to the standard red, green, blue, yellow, etc.

Each of these is an accessor which returns a new Color object every time
it is invoked.  This ensures that code like what's shown below won't cause
undesirable side effects:

    var color = Color.Red;
    color.blue = 255;  // we needed magenta instead

The downside to this is that e.g. `Color.Red === Color.Red` evaluates to
false, but this is rarely an issue in practice.

Color.is(color1, color2);

Returns true if `color1` refers to the same physical color as `color2`
without regard to their alpha components.  Otherwise returns false.

Note: This is not the same as comparing the color objects' .name properties
      because Color#name encodes the alpha channel in addition to the
      physical color.

Color.mix(color1, color2[, w1, w2]);

Calculates a weighted average of two colors.  `w1` and `w2` are optional
and specify the relative weights of `color1` and `color2` respectively.  If
the weights are omitted, the mix is 50/50.

Color.of(name);

Returns a Color object from `name`, which can either be the name of a
predefined X11 color without spaces (e.g. "chartreuse"), or an ARGB
signature such as "#800000FF".  If `name` cannot be resolved to a color,
throws a TypeError.

new Color(red, green, blue[, alpha]);

Constructs a new Color object.  Color objects are used to specify the color
of elements such as vertices and primitives.  Color components should be in
the range [0.0-1.0] and out-of-range values will be silently clamped.
`alpha` specifies opacity and defaults to 1.0 if not provided.

Color#red [read/write] Color#green [read/write] Color#blue [read/write] Color#alpha [read/write]

Gets or sets the individual components of the color.  Values outside the
range of [0-1] are accepted, but the engine will automatically clamp them
during rendering.

Color#name [read-only]

Gets the name of the Color according to its component values such that
Color.of(color.name) will give back a Color with the same values.  Useful
for saving and reading back colors from save files.

Color#clone();

Returns a copy of this Color object.  Changes to the clone will not affect
the original object.

Color#fade(alpha);

Scales this color's alpha channel by `alpha`, between 0.0 and 1.0, and
returns the result.  The red, green, and blue components are not modified.
This is useful when you need to make a predefined color translucent, for
instance:

    var translucentBlue = Color.Blue.fade(0.5);

Font.Default [read-only]

Gets the default engine font.  This is the font used for the FPS counter
and system messages.

new Font(filename);

Constructs a Font object from a font file.  Currently only the Sphere RFN
font format is supported.

Font#fileName [read-only]

Gets the full, canonical SphereFS filename of the file used to construct
this Font object.

Font#height [read-only]

Gets the line height, in pixels, for text rendered using this font.

Font#drawText(surface, x, y, text[, color[, wrap_width]]);

Renders `text` to the specified surface at (x,y).  `color` defaults to
Color.White if not provided, and `wrap_width` specifies the width in which
to constrain the text.  If `wrap_width` is not provided, no wrapping is
performed.

Font#getTextSize(text, wrap_width);

Gets the size, in pixels, of `text` if it were rendered by Font:drawText()
with the specified wrap width.  Return value is an object with `width` and
`height` properties.

Font#wordWrap(text, wrap_width);

Wraps `text` as if it were drawn with Font#drawText() using the specified
wrap width.  Returns an array of strings, representing the lines in the
wrapped text.

When drawing large amounts of word-wrapped text every frame, for example in
a text box, this function should be used to pre-wrap the text since
performing wrapping calculations every frame can get expensive.

new Texture(filename);

Constructs a new Texture object from an image file.  Unlike images in
Sphere v1, these cannot be rendered directly but instead must be used to
texture a Shape object.

Note that Textures are read-only.  If you need a writable image, you should
use a Surface object instead.

new Texture(width, height, pixels);

Constructs a new Texture from a pixel buffer.  `width` and `height` specify
the size of the texture image, and `pixels` is an ArrayBuffer containing
the RGBA pixel data to use to initialize the image.  The pixel data should
not be padded (i.e. stride is equal to width).

An error is thrown if the ArrayBuffer doesn't contain enough pixel data to
describe the entire texture.

Texture#fileName [read-only]

Gets the full, canonical SphereFS filename of the file used to construct
this Texture object.  For synthesized textures, returns null.

Texture#width [read-only] Texture#height [read-only]

Gets the width or height of the texture, in pixels.

new Model(shapes[, shader]);

Constructs a Model out of the provided array of Shape objects.  `shader` is
the Shader to use when rendering the model.  See below for more information
on shaders.

When a Model is created, its transformation matrix is set to the
identity matrix.  If `shader` is not provided, the default shader program
will be used (see `Shader.Default`).

Model#shader [read/write]

Gets or sets the Shader to use when drawing this model.

Model#transform [read/write]

Gets or sets the transformation matrix to use when drawing this model.

Model#draw(surface);

Draws the model on `surface`.  Any transformations defined for the model
(see below) are applied as if all the shapes comprising it were a single
primitive.

Model#setFloat(name, value); Model#setInt(name, value); Model#setMatrix(name, transform);

Sets the value of a GLSL uniform.  When the model is drawn, if its shader
program contains a uniform called `name` of the proper type, the value will
be uploaded to that uniform.  It is safe to call this even if the uniform
turns out not to exist (in which case the call is effectively a no-op).

Shader.Default [read-only]

Gets the default Galileo shader program.  This is a very barebones shader
which uses screen coordinates for vertices and performs only basic texture
mapping.

new Shader(options);

Constructs a Shader from a set of shader sources.  `options` should be an
object with the following properties:

    options.vertex

        The name of the file containing source code for the GLSL vertex
        shader.

    options.fragment

        The name of the file containing source code for the GLSL fragment
        shader.

Note that HLSL (DirectX) shaders are not supported, even on Windows.

ShapeType [enumeration]

Specifies the type of graphics primitive represented by a Shape object.
Can be one of the following:

    ShapeType.Auto
    ShapeType.Fan
    ShapeType.Lines
    ShapeType.LineLoop
    ShapeType.LineStrip
    ShapeType.Points
    ShapeType.Triangles
    ShapeType.TriStrip

new Shape(vertices[, texture[, type]]);

Constructs a primitive shape out of the provided array of vertices textured
with the Image specified by `texture`.

Each vertex can have the following properties:

    vertex.x, vertex.y

        The location of the vertex.  The final location of each vertex can
        be modified by using a transformation matrix (see Matrix above).

    vertex.u, vertex.v

        The texture coordinates of the vertex.  This is used to control
        which part of the texture will be applied to this vertex.  If u/v
        is not provided for a vertex, it will be assumed to be have its u/v
        at (0, 0).

    vertex.color

        The color of the vertex.  The vertex colors will be multiplied with
        texture pixels to determine the final color of each pixel in a
        shape.

`type` specifies the type of primitive (see ShapeType above).  If `type` is
ShapeType.Auto (the default), the type is determined automatically based on
the number of vertices.

Shape#texture [read/write]

The Image to use when texturing the shape. This can be null, in which case
the vertex colors alone will determine the shape's appearance.

Shape#draw(surface[, transform]);

Draws the shape.  `transform` is the Transform to use, and `surface` is the
Surface to draw on.  If `surface` is omitted, the shape is drawn on the
backbuffer.

new Surface(width, height[, fill_color]);

Constructs a new surface with the specified width and height, optionally
filled with 'fill_color'.  If a fill color is not provided, the created
surface will be filled with transparent pixels.

Surfaces are meant to used as render targets from drawing operations.  This
enables static elements of a scene, such as a HUD, to be rendered in
advance, potentially improving performance.

new Surface(filename);

Constructs a new Surface whose initial contents are taken from the
specified image file.

Surface#width [read-only] Surface#height [read-only]

Gets the width and height of the surface, in pixels.

Surface#toTexture();

Returns a Texture created from the current contents of this Surface.  Note
that drawing to the surface afterwards will not affect the texture, which
is read-only.

new Transform();

Constructs a transformation matrix.  The object represents a 4x4 matrix
and is initialized to identity.

Transform#identity();

Re-initializes this matrix as an identity matrix.

Transform#compose(otherMatrix);

Composes this transform with another.  `otherMatrix` is multiplied from the
left such that transformations are performed in the order you specify.

Transform#rotate(theta[, vx, vy, vz]);

Applies a rotation transformation to this matrix.  `theta` is the angle of
rotation, in radians.  (vx, vy, vz) is the vector to rotate about.  For
example the default is (0, 0, 1) which rotates about the Z axis.

Transform#scale(sx, sy);

Applies a scaling transformation to this matrix.  `sx` and `sy` are the
horizontal and vertical scaling factors, respectively.

Transform#translate(tx, ty);

Applies a translation transformation to this matrix.  `tx` and `ty` are the
horizontal and vertical translations, respectively.

Audio API

Playing sounds and music are both handled in miniSphere by Audialis, the evolution of Sphere 1.x's audio subsystem. Audialis allows you to create mixers which can be used to adjust certain parameters across all sounds associated with that mixer. This is useful for implementing global volume controls, for example.

Mixer.Default [read-only]

Gets the default Audialis audio mixer.  The default mixer outputs 44.1 kHz
16-bit stereo sound, i.e. CD quality.

new Mixer(frequency, bits[, channels]);

Constructs a new Mixer object.  Any sounds played through the mixer will use
the format specified by the parameters above.  `frequency` is the sample
rate, `bits` specifies the bit depth (allowed values are 8, 16 and 24), and
`channels` is the number of channels, ranging [1-7].  Channel counts of 5 or
higher imply an additional LFE channel (i.e. 5.1, 6.1, 7.1).

Do note that this creates a _hardware_ mixer.  If the requested format is
not supported by the system, an error will be thrown ("unable to create
hardware voice").

Mixer#volume [read/write]

Gets or sets the output volume of the mixer.  This will affect the volume
of any sounds played through the mixer.

new Sample(filename);

Constructs a Sample from the specified audio file.  The audio data is
loaded into memory in its entirety and multiple instances can be played
simultaneously with no latency, making this very useful for sound effects.
Supported formats are Ogg Vorbis (.ogg), WAV, and FLAC.

Note: Compressed formats like Vorbis will be decompressed during loading,
      potentially using a large amount of RAM.  It is therefore not
      recommend to use `Sample` objects for, e.g., background music.  Use a
      `Sound` instead.

Sample#fileName [read-only]

Gets the full, canonical SphereFS path of the audio file used to construct
this sample.

Sample#play(mixer[, options]);

Plays the sample on the specified mixer.  Each time this is called, a new
stream is started, allowing many instances of the sound to be playing
simultaneously.

`options`, if present, must be an object and can include the following
properties (all optional):

    options.volume

        The volume level to play the sound at.  1.0 is full volume, 0.0 is
        silent.  Volume levels higher than 1.0 will amplify the sound but
        may cause distortion.  Volume is 1.0 if not specified.

    options.pan

        A volume between -1.0 and 1.0 specifying the left/right balance.
        -1.0 is full left, +1.0 is full right, and 0.0 is dead center.  Pan
        is 0.0 (center) if not specified.

    options.speed

        Playback speed, where 1.0 is normal speed.  Also affects pitch.
        Speed is 1.0x if not specified.

Sample#stopAll();

Stops playback of all active instances of this sample.

new Sound(filename);

Constructs a Sound object from the specified audio file.  Supported sound
formats are Ogg Vorbis (.ogg), WAV, MOD, S3M, IT, and FLAC.  Note that
unlike in Sphere 1.x, mp3 and MIDI formats are not supported.

Sound#fileName [read-only]

Gets the full, canonical SphereFS filename of the file used to construct
this Sound object.

Sound#length [read-only]

Gets the length of the sound in microseconds.

Sound#pan [read/write]

Gets or sets the current pan (balance). 0.0 is dead center, -1.0 is full
left, and 1.0 is full right.

Sound#playing [read-only]

true if the sound is currently playing, false otherwise.

Sound#position [read/write]

Gets or sets the playback position within the sound, in seconds.

Sound#repeat [read/write]

Gets or sets whether the sound will automatically repeat when it reaches
the end.

Sound#speed [read/write]

Gets the current playback speed of the sound.  1.0 is normal, 2.0 is double
speed, etc.  Note that changing the playback speed affects the pitch as
well.

Sound#volume [read/write]

Gets or sets the current volume of the sound.  0.0 is silent, 1.0 is full
volume.  Higher values are allowed, but may introduce distortion due to
clipping.

Sound#pause();

Pauses the sound.  If it is already paused, this has no effect.

Sound#play([mixer]);

Begins or resumes sound playback.  When called with no `mixer` argument,
Sound#play() will resume playback for a paused sound.  Otherwise, the sound
is started from the beginning on the specified mixer.

Sound#stop();

Stops the sound.  Playback position will be reset to the beginning (0.0s),
even if the sound was not playing.

new SoundStream([frequency[, bits[, channels]]]);

Constructs a sound stream, which plays arbitrary sound data provided by the
game at runtime.  This may be used, for example, to generate sound
procedurally or add support for an unsupported audio format in script.
`frequency` specifies the stream's sample rate and 'channels' the number of
audio channels, ranging [1-7].  Channel counts of 5 and higher imply an
additional LFE (subwoofer) channel.

The default stream format is 8-bit 22050Hz with 1 channel.

SoundStream#bufferSize [read-only]

Gets the total number of samples in the stream's buffer.

SoundStream#buffer(data);

Writes audio data to the stream buffer.  `data` is an ArrayBuffer,
TypedArray or DataView containing the data to write.  While a stream is
playing, audio data should be fed into it continuously to prevent skipping.

SoundStream#pause();

Pauses playback of the stream.  Has no effect if the stream is already
paused.

SoundStream#play([mixer]);

Starts the stream playing, or if no mixer is specified, resumes a paused
stream.  Before beginning playback, it is recommended to pre-buffer a few
seconds of audio into the stream (see SoundStream:buffer() below).  This
will minimize the risk of a buffer underrun and subsequent skipping during
playback.

SoundStream#stop();

Stops playback of the stream and frees its buffer.  This should be called
when you are done using a stream.  The stream may be reused after a stop()
call, but you will have to feed new audio data.

File System API

miniSphere provides the FS object to allow games to access asset and save files, create or remove directories, and so on.

FS.createDirectory(dir_name);

Creates the specified directory and any of its parent directories that
don't already exist.

FS.deleteFile(filename);

Deletes `filename` from the file system.

FS.exists(filename);

Checks whether the specified file exists and returns true if it does.
Otherwise, returns false.

FS.readFile(filename);

Reads all data from the specified file and returns it as an ArrayBuffer.
This avoids the need to explicitly open and close a file when all you want
to do is read its contents into memory.

FS.removeDirectory(dir_name);

Deletes the specified directory.  The directory must be empty or an error
will be thrown.

FS.rename(srcname, destname);

Renames the file named by `srcname` to `destname`, both of which are
assumed to be full SphereFS paths.  This can also be used to move a file
between directories; if so, the destination directory must already exist.

FS.resolve(path);

Resolves a path (which may contain relative components) to its canonical
SphereFS representation.  This can be useful when data is associated with
individual assets, such as map files, and you need to ensure the same data
is pulled for a given file regardless of the path used to access it.

Note that the resource referred to by the path doesn't need to exist.  As
with other FS methods, FS.resolve() will throw an error if an absolute path
is passed in.

FS.writeFile(filename, data);

Writes an entire file in one go.  If a file already exists with the given
filename, it will be overwritten.  'data' is an ArrayBuffer, TypedArray or
DataView containing the data to be written.

new FileStream(filename, op);

Constructs a FileStream that provides access to the contents of a specified
file.  `op` specifies the file operation requested and must be one of the
following:

    FileOp.Read

        Read data from the file.  The file must exist and will be opened in
        read-only mode.  Any attempt to write to the file will throw a
        TypeError.

    FileOp.Write

        Write data to the file.  Be careful: If the file already exists,
        its contents will be overwritten.  If that behavior is not desired,
        use `FileOp.Update` instead.

    FileOp.Update

        Amend the file.  If a file by the specified name doesn't exist, it
        will be created.  For convenience, the file pointer is initially
        placed at the end of the file.

Requesting write access to a file residing in a read-only directory (e.g.,
the system directory `#/`) will throw a TypeError.

FileStream#dispose();

Disposes of the FileStream object, after which it should not be used.
Attempting to read or write to a stream after it is disposed of will throw
an error.

Note: While it's not strictly necessary to call `dispose()` on FileStreams,
      it may take some time for the garbage collector to get to them.  If
      there's an active FileStream in write mode for a given file, an error
      will be thrown if you try to construct another one.

FileStream#fileName [read-only]

Gets the full, canonical SphereFS filename of the underlying file.

FileStream#position [read/write]

Gets or sets the file position, which determines where in the file the next
read or write will start from.  Expressed in bytes.

Note: For files opened for writing, it is valid to seek past the end of the
      stream.  In this case the next write will be at the new position and
      the intervening space filled with NUL bytes.

FileStream#size [read-only]

Gets the size of the underlying file, in bytes.

FileStream#read(num_bytes);

Reads data from the file, up to the specified number of bytes, and returns
it as an ArrayBuffer.  The file must be opened for reading.

FileStream#write(data);

Writes data to the file and advances the file pointer.  `data` should be an
ArrayBuffer, TypedArray or DataView containing the data to be written.

Networking API

miniSphere provides basic support for TCP sockets. There are two object types: Socket and Server. A Server is persistent and listens for connections on a given port, while Sockets represent individual client connections.

new Server(port[, backlog_size]);

Constructs a new server which listens for connections on the specified
port.  `backlog_size` specifies the size of the backlog.  If the backlog
fills, new connections will be dropped.

Server#accept();

If one or more connections are waiting in the backlog, removes it from the
queue and returns a Socket object representing the connection.  Otherwise,
returns null.  This should be called regularly to prevent the backlog from
filling up.

Server#close();

Shuts down the server.  Any connections in the backlog will be dropped and
no new connections can be made until a new Server is created.

new Socket(hostname, port);

Connects to `hostname` on `port` and constructs an Socket representing the
connection.  The hostname can either be a named address (e.g. google.com)
or an IP address (e.g. 127.0.0.1).  As this operation is non-blocking, a
Socket object will be returned even if the connection can be not be made;
you must poll Socket#connected to find out when the connection has opened.

Socket#bytesPending [read-only]

Gets the number of bytes of data currently in the receive buffer.  Call
Socket#read() to retrieve this data.

Note that more data may be received between the time this is checked the
time a read is performed.  It's recommended to poll this value from time to
time and perform reads in order to keep the size of the receive buffer
down.

Socket#connected [read-only]

Gets whether the connection has been established.  As long as this is
false, you cannot call any other methods on the socket object.  Doing so
will cause an error to be thrown.

Socket#remoteAddress [read-only]

Gets the IP address of the upstream end of the socket.  Throws an error if
accessed before a connection has been established.

Socket#remotePort [read-only]

Gets the port that the remote machine is using for the connection.
Generally not a useful statistic, but it's there if you need it.  Throws an
error if accessed before a connection is established.

Socket#close();

Disconnects the socket.  Note that any given Socket object is tied to a
specific session and so cannot be reused after it has been closed.

Socket#read(num_bytes);

Reads up to `num_bytes` bytes from the socket and returns an ArrayBuffer
containing the data received.  This method is non-blocking: If more bytes
are requested than are available, only the available data will be returned.

Socket#write(data);

Writes data to the socket, which can be read at the other end.  `data` can
be either an ArrayBuffer, TypedArray view, or DataView.