Manual | Physics | Operations | Others
- Fundamental
- Programming
- Import and Export
- Building
- Display: configurable resolution
- Code: Lua, supports multiple source files
- Image: either true-color (PNG, JPG, BMP, TGA) or paletted, up to 1024x1024 pixels per file
- Palette: 256 colors with transparency support
- Sprite: up to 1024x1024 pixels per frame, up to 1024 frames per sprite
- Map: up to 4096x4096 tiles per page
- Font: supports Bitmap and TrueType
- Audio: 1 BGM channel, 4 SFX channels; supports MP3, OGG, WAV, etc.
- Gamepad: 6 buttons for each pad (D-Pad + A/B), up to 2 players
- Keyboard and mouse: supported
A new created project consists of a meta info asset ("info.json") and an entry source ("main.lua"). The meta info indicates basic information of the project in JSON. The entry is where the project starts to execute. You can add supported existing file or create new blank assets into a project. All text-based assets use Unix LF ('\n') for line ending.
Note that it requires external programs to open file dialogs on Linux for opening, saving, exporting, etc. Make sure that at least one of the following is available: "zenity", "kdialog", "matedialog", "qarma".
All assets are stored as raw files under a specific directory in this format.
A text-based project archive is a plain text file with the "*.bit" extension, with all assets encoded in printable UTF-8 characters or Base64 string. This format uses Unix LF ('\n') for line ending.
A binary-based project archive is just a compressed ZIP package replaced with the "*.bit" extension.
Bitty Engine makes backup once you save an asset or a project, click "Project", "Browse Data Directory..." to locate it.
There are shortcuts to capture canvas during running.
- F6: take a screenshot
- F7: start recording frames
- F8: stop recording frames
Bitty project is programmable in the Lua programming language.
Lua is widely used and validated in the software industry, there are a lot of learning materials about the language on the internet. Click to see on the Wikipedia or read the official documentations.
Lua is 1-based for list accessing, Bitty Engine follows the same convention for sequenced structures, like Bytes
, File
, etc. Otherwise it is 0-based for coordinates and graphical units, like Noiser
, Pathfinder
, Image
, Sprite
, Palette
, Map
, etc.
This document uses a meta method form to describe operators. Eg. foo:__len()
denotes #foo
, foo:__add(bar)
denotes foo + bar
, foo:__unm()
denotes -foo
, etc. Just write the symbol form #
, +
, -
, etc. in your calculation.
Additionally, this is not about the syntax, but for description convenience in this document, optional parameter is described between square brackets [optional]
; default value is appended after an equal sign foo = 42
; variadic list is described as ...
.
Lua uses GC to free unused memory automatically, thus you don't have to do so manually most of the time. However resources loaded by Resources.load(...)
are not, consider unloading them properly. See Resources for details.
The ready to use modules, package
, coroutine
, math
, table
, string
, utf8
, debug
are reserved from the original language.
The trivial modules, io
, os
are removed. Bitty Engine offers alternatives.
Bitty Engine offers some handy built-in functions, some are reserved from the original but the behaviour is improved, some are extended.
Functions
-
print(...)
: outputs some values to the console window as message, for debugging purposes -
warn(...)
: outputs some values to the console window as warn, for debugging purposes -
error(...)
: outputs some values to the console window as error, and stops execution, for debugging purposes -
msgbox(msg)
: popups a message box with the specific contentmsg
: the message string
-
input(prompt[, default])
: popups an input boxprompt
: the prompt on the boxdefault
: the default content- returns inputted string, or
nil
for canceled
-
exit()
: exits execution of the current program
A conventional entry program of Bitty project is made up of a setup
function which is called once program starts, and an update
which is called periodically:
function setup()
end
function update(delta)
end
Define another quit
function to run code on execution termination:
function quit()
end
Define focusLost
, focusGained
functions to run code on focus changed:
function focusLost()
end
function focusGained()
end
Define a fileDropped
function to run code on file dropped:
function fileDropped(paths) -- For desktop only.
end
Define a rendererReset
function to run code on renderer reset:
function rendererReset()
end
Generally setup
is used to initial game variables, states, update
is where gameplay logic and rendering goes, and quit
is for persisting necessary data on disk. All these entries above are optional.
Bitty Engine uses a timeout mechanism to avoid unexpected infinite loops, it raises an error when any invoking to the entries takes more than 10 seconds by default. The timeout value can be changed by Debug.setTimeout(...).
This module generates 2D or 3D noise values.
Constructors
Noiser.new()
: constructs a noiser object
Methods
noiser:setOption(key, val)
: sets option value of the specific keykey
: the option key to setval
: the value to set
Available options:
Key | Value | Note |
---|---|---|
"frequency" | Real number | Defaults to 0.01 |
"noise_type" | Can be one in "open_simplex2", "open_simplex2s", "cellular", "perlin", "value_cubic", "value" | Defaults to "open_simplex2" |
"rotation_type_3d" | Can be one in "none", "improve_xy_planes", "improve_xz_planes" | Defaults to "none" |
"fractal_type" | Can be one in "none", "fbm", "ridged", "pingpong", "domain_warp_progressive", "domain_warp_independent" | Defaults to "none" |
"fractal_octaves" | Integer | Defaults to 3 |
"fractal_lacunarity" | Real number | Defaults to 2.0 |
"fractal_gain" | Real number | Defaults to 0.5 |
"fractal_weighted_strength" | Real number | Defaults to 0.0 |
"fractal_pingpong_strength" | Real number | Defaults to 2.0 |
"cellular_distance_function" | Can be one in "euclidean", "euclidean_sq", "manhattan", "hybrid" | Defaults to "euclidean_sq" |
"cellular_return_type" | Can be one in "cell_value", "distance", "distance2", "distance2_add", "distance2_sub", "distance2_mul", "distance2_div" | Defaults to "distance" |
"cellular_jitter" | Real number | Defaults to 1.0 |
"domain_warp_type" | Can be one in "open_simplex2", "open_simplex2_reduced", "basic_grid" | Defaults to "open_simplex2" |
"domain_warp_amplitude" | Real number | Defaults to 1.0 |
noiser:seed(seed)
: seeds theNoiser
for all noise typesseed
: the seed integer
noiser:get(pos)
: gets the value at the specific positionpos
: the position to get, eitherVec2
orVec3
- returns noise value, with range of values from -1.0 to 1.0
noiser:domainWarp(pos)
: applies domain warping at the specific positionpos
: the position to warp, eitherVec2
orVec3
- returns warped position
This module performs a pathfinding algorithm on 2D grids.
Constructors
Pathfinder.new(w, n, e, s)
: constructs a pathfinder object with finite bordersw
: the west edge, minimum in the x directionn
: the north edge, minimum in the y directione
: the east edge, maximum in the x directions
: the south edge, maximum in the y direction
Object Fields
pathfinder.diagonalCost
: gets or sets the walking cost of diagonal direction, defaults to 1.414; set to -1 for not walkable
Methods
pathfinder:get(pos)
: gets the walking cost of a prefilled grid at the specific positionpos
: the position to get- returns walking cost
pathfinder:set(pos, cost)
: sets the walking cost of a grid, initializes a cost matrix with 1 for all grids when first calling to this functionpos
: the position to setcost
: the cost value to set
pathfinder:clear()
: clears prefilled matrix and internal cached datapathfinder:solve(beginPos, endPos, eval)
: resolves for a possible path with the specific evaluatorbeginPos
: the beginning positionendPos
: the ending positioneval
: in form offunction (pos) return number end
, an invokable object which accepts position and returns the walking cost at that point- returns an approachable path, in a list of
Vec2
, could be empty
pathfinder:solve(beginPos, endPos)
: resolves for a possible path with the prefilled cost matrixbeginPos
: the beginning positionendPos
: the ending position- returns an approachable path, in a list of
Vec2
, could be empty
Grid coordinates can be any integer, with range of values from -32,767 to 32,767. A cost matrix will be prefilled once calling the pathfinder:set(...)
function; this data exists until calling pathfinder:clear()
. The pathfinder:solve(...)
function prefers to use invokable to get grid cost, and falls to use prefilled matrix if no evaluator provided. Call pathfinder:clear()
before solving in either way, if any grid data has been changed.
Walking cost is combined with two parts by multiplicative: neighbor cost and map cost. Neighbor cost stands for how much does it cost to walk from the current grid to its neighbor directions as following, in which D
defaults to 1.414:
_________________
| | | |
| D | 1 | D |
|_____|_____|_____|
| | | |
| 1 | | 1 |
|_____|_____|_____|
| | | |
| D | 1 | D |
|_____|_____|_____|
Pathfinder retrieves grid cost from either an evaluator or prefilled matrix. All cost states must be immutable during calling the pathfinder:solve(...)
function. It's not walkable if either part of the cost combination results -1; positive cost means walkable, and the pathfinder prefers lower cost grids.
This module provides a random algorithm organized by object, other than the built-in random function in Lua.
Constructors
Random.new()
: constructs a randomizer object
Methods
random:seed([seed])
: seeds the randomizerseed
: the seed; omit to seed with the current time
random:next(low, up)
: generates a random numberlow
: the low boundup
: the up bound- returns a pseudo random integer with uniform distribution in the range [m, n]
random:next(n)
: generates a random number- returns equivalent to
random:next(1, n)
for a positiven
; returns an integer with all bits random for a zeron
- returns equivalent to
random:next()
: generates a random number- returns a pseudo random real number with uniform distribution in the range [0, 1)
This module performs a raycasting algorithm on 2D grids.
Constructors
Raycaster.new()
: constructs a raycaster object
Object Fields
raycaster.tileSize
: gets or sets the tile size asVec2
, defaults to 8x8raycaster.offset
: gets or sets theRaycaster
offset asVec2
, defaults to 0, 0
Methods
raycaster:solve(rayPos, rayDir, eval)
: resolves for raycastingrayPos
: the ray positionrayDir
: the ray directioneval
: in form offunction (pos) return boolean end
, an invokable object which accepts position and returnstrue
for blocked,false
for pass- returns an approximate intersection position as
Vec2
ornil
, and a secondary value for intersection index asVec2
ornil
This module performs a smooth walking algorithm on 2D grids.
Constants
Walker.None
Walker.Left
Walker.Right
Walker.Up
Walker.Down
Constructors
Walker.new()
: constructs a walker object
Object Fields
walker.objectSize
: gets or sets the object size asVec2
, defaults to 8x8walker.tileSize
: gets or sets the tile size asVec2
, defaults to 8x8walker.offset
: gets or sets theWalker
offset asVec2
, defaults to 0, 0
Methods
walker:solve(objPos, expDir, eval, slidable = 5)
: resolves for a walking stepobjPos
: the object positionexpDir
: the expected directioneval
: in form offunction (pos) return boolean, enum end
, an invokable object which accepts position and returnstrue
for blocked,false
for pass; in addition this evaluator can return a secondary value inWalker.None
,Walker.Left
,Walker.Right
,Walker.Up
,Walker.Down
for one-way walkslidable
: non-zero for slidable at edge, with range of values from 0 to 10- returns a resolved directional
Vec2
, could be zero
This module offers manipulations of ZIP package.
Constructors
Archive.new()
: constructs an archive object
Methods
archive:open(path, access = Stream.Read)
: opens anArchive
file for reading or writingpath
: theArchive
file pathaccess
: can be one inStream.Read
,Stream.Write
,Stream.Append
, for reading, truncated writing, non-truncated writing respectively- returns
true
for success, otherwisefalse
archive:close()
: closes an openedArchive
- returns
true
for success, otherwisefalse
- returns
archive:all()
: gets all entry names in theArchive
- returns an entry list, in a list of string, could be empty or
nil
- returns an entry list, in a list of string, could be empty or
archive:exists(entry)
: gets whether the specific entry exists in theArchive
entry
: the entry name to look for- returns
true
for exists, otherwisefalse
archive:make(entry)
: makes an entry in theArchive
entry
: the entry name to make- returns
true
for success, otherwisefalse
archive:toBytes(entry, bytes)
: reads the specific entry and writes toBytes
entry
: the entry name to readbytes
: theBytes
to receive, its cursor will be at the end- returns
bytes
for success, otherwisenil
archive:fromBytes(entry, bytes)
: writes the specific entry fromBytes
entry
: the entry name to writebytes
: theBytes
to retrieve from start till end, its cursor won't be moved- returns
true
for success, otherwisefalse
archive:toFile(entry, path)
: reads the specific entry and writes to fileentry
: the entry name to readpath
: the file path to receive- returns
true
for success, otherwisefalse
archive:fromFile(entry, path)
: writes the specific entry from fileentry
: the entry name to writepath
: the file path to retrieve- returns
true
for success, otherwisefalse
archive:toDirectory(path)
: reads all the entries and writes to directorypath
: the directory path to receive- returns
true
for success, otherwisefalse
archive:fromDirectory(path)
: writes all the entries from directorypath
: the directory path to retrieve- returns
true
for success, otherwisefalse
Being the same as Lua list, a Bytes
' index starts from 1. Implements a Stream
protocol as memory buffer.
Constructors
Bytes.new()
: constructs a bytes object
Operators
=bytes[index]
: reads a byte from the specific indexindex
: starts from 1- returns byte
bytes[index]=
: writes a byte to the specific indexindex
: starts from 1
bytes:__len()
: gets the length in bytes
Methods
bytes:peek()
: peeks the reading/writing cursor- returns the cursor, starts from 1
bytes:poke(index)
: pokes the reading/writig cursorindex
: starts from 1- returns
true
for success, otherwisefalse
bytes:count()
: gets the length in bytes- returns the length in bytes
bytes:empty()
: gets whether theBytes
is empty- returns
true
for empty, otherwisefalse
- returns
bytes:endOfStream()
: gets whether the cursor is at the end- returns
true
for end, otherwisefalse
- returns
bytes:readByte()
: reads a byte and moves the cursor forward- returns byte
bytes:readInt16()
: reads a 16-bit signed integer and moves the cursor forward- returns 16-bit signed integer
bytes:readUInt16()
: reads a 16-bit unsigned integer and moves the cursor forward- returns 16-bit unsigned integer
bytes:readInt32()
: reads a 32-bit signed integer and moves the cursor forward- returns 32-bit signed integer
bytes:readUInt32()
: reads a 32-bit unsigned integer and moves the cursor forward- returns 32-bit unsigned integer
bytes:readInt64()
: reads a 64-bit signed integer and moves the cursor forward- returns 64-bit signed integer
bytes:readSingle()
: reads a single precision real number and moves the cursor forward- returns single precision real number
bytes:readDouble()
: reads a double precision real number and moves the cursor forward- returns double precision real number
bytes:readBytes([expSize[, bytes_]])
: reads someBytes
and moves the cursor forwardexpSize
: optional, the expected size in bytes to read; omit to read till endbytes_
: optional,Bytes
to receive, its content will be cleared; omit to return a newBytes
- returns the target
Bytes
, its cursor will be at the end
bytes:readString([expSize])
: reads some text and moves the cursor forwardexpSize
: optional, the expected size in bytes to read; omit to read till end- returns the read string
bytes:readLine()
: reads a line of text and moves the cursor forward- returns the read line
bytes:writeByte(val)
: writes a byte and moves the cursor forwardval
: the byte to write- returns the written size in bytes
bytes:writeInt16(val)
: writes a 16-bit signed integer and moves the cursor forwardval
: the 16-bit signed integer to write- returns the written size in bytes
bytes:writeUInt16(val)
: writes a 16-bit unsigned integer and moves the cursor forwardval
: the 16-bit unsigned integer to write- returns the written size in bytes
bytes:writeInt32(val)
: writes a 32-bit signed integer and moves the cursor forwardval
: the 32-bit signed integer to write- returns the written size in bytes
bytes:writeUInt32(val)
: writes a 32-bit unsigned integer and moves the cursor forwardval
: the 32-bit unsigned integer to write- returns the written size in bytes
bytes:writeInt64(val)
: writes a 64-bit signed integer and moves the cursor forwardval
: the 64-bit signed integer to write- returns the written size in bytes
bytes:writeSingle(val)
: writes a single precision real number and moves the cursor forwardval
: the single precision real number to write- returns the written size in bytes
bytes:writeDouble(val)
: writes a double precision real number and moves the cursor forwardval
: the double precision real number to write- returns the written size in bytes
bytes:writeBytes(bytes_[, expSize])
: writes someBytes
and moves the cursor forwardbytes_
: theBytes
to write from start till end, its cursor won't be movedexpSize
: optional, the expected size in bytes to write; omit to write tillbytes_
's end- returns the written size in bytes
bytes:writeString(val)
: writes some text and moves the cursor forwardval
: the string to write- returns the written size in bytes
bytes:writeLine(val)
: writes a line of text and moves the cursor forwardval
: the line to write- returns the written size in bytes
bytes:get(index)
: gets a byte at the specific index, doesn't moves the cursorindex
: the index to get, starts from 1- returns byte
bytes:set(index, val)
: sets a byte to the specific index, doesn't moves the cursorindex
: the index to set, starts from 1val
: the byte to set
bytes:resize(expSize)
: resizes theBytes
expSize
: the expected new size
bytes:clear()
: clears all content and resets the cursor
Constructors
Color.new(r, g, b, a = 255)
: constructs a color objectr
: the red component, with range of values from 0 to 255g
: the green component, with range of values from 0 to 255b
: the blue component, with range of values from 0 to 255a
: the alpha component, with range of values from 0 to 255
Color.new()
: constructs a color object in white
Operators
color:__add(color_)
: adds with anotherColor
componentwiselycolor:__sub(color_)
: subtracts by anotherColor
componentwiselycolor:__mul(num)
: multiplies with another numbernum
: real number
color:__mul(color_)
: multiplies with anotherColor
componentwiselycolor_
: with range of values from 0 to 255 for each component
color:__mul(vec4)
: multiplies with anotherVec4
componentwiselyvec4
: real number for each component
color:__unm()
: takes the oppositeColor
componentwiselycolor:__eq(color_)
: compares with anotherColor
for equality
Object Fields
color.r
: gets or sets the red componentcolor.g
: gets or sets the green componentcolor.b
: gets or sets the blue componentcolor.a
: gets or sets the alpha component
Methods
color:toRGBA()
: converts theColor
to an RGBA integer in little-endiancolor:fromRGBA(int)
: fills theColor
with an RGBA integer in little-endian
Static Functions
DateTime.utc()
: gets the current UTC time- returns
sec
(0-based),min
(0-based),hr
(0-based, since midnight),mday
(1-based, day of the month),mo
(1-based),yr
(since C.E.),wday
(1-based, days since Sun.),yday
(1-based, days since 1, Jan.),isdst
(daylight saving time flag, always 0 for UTC)
- returns
DateTime.now()
: gets the current local time- returns
sec
(0-based),min
(0-based),hr
(0-based, since midnight),mday
(1-based, day of the month),mo
(1-based),yr
(since C.E.),wday
(1-based, days since Sun.),yday
(1-based, days since 1, Jan.),isdst
(daylight saving time flag)
- returns
DateTime.ticks()
: gets a high precision timestamp- returns timestamp in nanoseconds
DateTime.toMilliseconds(ticks)
: converts nanoseconds to millisecondsticks
: nanoseconds- returns milliseconds
DateTime.fromMilliseconds(ms)
: converts milliseconds to nanosecondsms
: milliseconds- returns nanoseconds
DateTime.toSeconds(ticks)
: converts nanoseconds to secondsticks
: nanoseconds- returns seconds
DateTime.fromSeconds(sec)
: converts seconds to nanosecondssec
: seconds- returns nanoseconds
DateTime.sleep(ms)
: sleeps for the specific millisecondsms
: milliseconds
Static Functions
Base64.encode(bytes)
: encodes the specificBytes
to Base64 stringbytes
: theBytes
to encode from start till end, its cursor won't be moved- returns Base64 string
Base64.decode(txt)
: decodes the specific Base64 string toBytes
txt
: Base64 string to decode- returns
Bytes
, its cursor will be at the end
Static Functions
Lz4.encode(bytes)
: encodes the specificBytes
to LZ4 encodedBytes
bytes
: theBytes
to encode from start till end, its cursor won't be moved- returns LZ4 encoded
Bytes
Lz4.decode(bytes)
: decodes the specific LZ4Bytes
toBytes
bytes
: LZ4Bytes
to decode- returns
Bytes
, its cursor will be at the end
Being the same as Lua list, a File
's index starts from 1. Implements a Stream
protocol as file on disk.
Constructors
File.new()
: constructs a file object
Operators
file:__len()
: gets the length in bytes
Methods
file:open(path, access = Stream.Read)
: opens aFile
for reading or writingpath
: theFile
pathaccess
: can be one inStream.Read
,Stream.Write
,Stream.Append
,Stream.ReadWrite
, for reading, truncated writing, non-truncated writing, reading and writing respectively- returns
true
for success, otherwisefalse
file:close()
closes an openedFile
- returns
true
for success, otherwisefalse
- returns
file:peek()
: peeks the reading/writing cursor- returns the cursor, starts from 1
file:poke(index)
: pokes the reading/writing cursorindex
: starts from 1- returns
true
for success, otherwisefalse
file:count()
: gets the length in bytes- returns the length in bytes
file:empty()
: gets whether theFile
is empty- returns
true
for empty, otherwisefalse
- returns
file:endOfStream()
: gets whether the cursor is at the end- returns
true
for end, otherwisefalse
- returns
file:readByte()
: reads a byte and moves the cursor forward- returns byte
file:readInt16()
: reads a 16-bit signed integer and moves the cursor forward- returns 16-bit signed integer
file:readUInt16()
: reads a 16-bit unsigned integer and moves the cursor forward- returns 16-bit unsigned integer
file:readInt32()
: reads a 32-bit signed integer and moves the cursor forward- returns 32-bit signed integer
file:readUInt32()
: reads a 32-bit unsigned integer and moves the cursor forward- returns 32-bit unsigned integer
file:readInt64()
: reads a 64-bit signed integer and moves the cursor forward- returns 64-bit signed integer
file:readSingle()
: reads a single precision real number and moves the cursor forward- returns single precision real number
file:readDouble()
: reads a double precision real number and moves the cursor forward- returns double precision real number
file:readBytes([expSize[, bytes]])
: reads someBytes
and moves the cursor forwardexpSize
: optional, the expected size in bytes to read; omit to read till endbytes
: optional,Bytes
to receive, its content will be cleared; omit to return a newBytes
- returns the target
Bytes
, its cursor will be at the end
file:readString([expSize])
: reads some text and moves the cursor forwardexpSize
: optional, the expected size in bytes to read; omit to read till end- returns the read string
file:readLine()
: reads a line of text and moves the cursor forward- returns the read line
file:writeByte()
: writes a byte and moves the cursor forwardval
: the byte to write- returns the written size in bytes
file:writeInt16()
: writes a 16-bit signed integer and moves the cursor forwardval
: the 16-bit signed integer to write- returns the written size in bytes
file:writeUInt16()
: writes a 16-bit unsigned integer and moves the cursor forwardval
: the 16-bit unsigned integer to write- returns the written size in bytes
file:writeInt32()
: writes a 32-bit signed integer and moves the cursor forwardval
: the 32-bit signed integer to write- returns the written size in bytes
file:writeUInt32()
: writes a 32-bit unsigned integer and moves the cursor forwardval
: the 32-bit unsigned integer to write- returns the written size in bytes
file:writeInt64()
: writes a 64-bit signed integer and moves the cursor forwardval
: the 64-bit signed integer to write- returns the written size in bytes
file:writeSingle()
: writes a single precision real number and moves the cursor forwardval
: the single precision real number to write- returns the written size in bytes
file:writeDouble()
: writes a double precision real number and moves the cursor forwardval
: the double precision real number to write- returns the written size in bytes
file:writeBytes(bytes[, expSize])
: writes someBytes
and moves the cursor forwardbytes
: theBytes
to write from start till end, its cursor won't be movedexpSize
: optional, the expected size in bytes to write; omit to write tillbytes
's end- returns the written size in bytes
file:writeString(val)
: writes some text and moves the cursor forwardval
: the string to write- returns the written size in bytes
file:writeLine(val)
: writes a line of text and moves the cursor forwardval
: the line to write- returns the written size in bytes
Note that when open a file as Stream.Append
, it always writes data at the end of the file, expanding it, and file:poke(...)
are ignored.
Static Functions
Path.combine(...)
: combines a number of paths- returns combined path
Path.split(full)
: splits the specific path into parts- returns
name
,ext
,parent
- returns
Path.existsFile(path)
: gets whether the specific file existspath
: the file path- returns
true
for exists, otherwisefalse
Path.existsDirectory(path)
: gets whether the specific directory existspath
: the directory path- returns
true
for exists, otherwisefalse
Path.copyFile(src, dst)
: copies the specific file to a new pathsrc
: the source pathdst
: the destination path- returns
true
for success, otherwisefalse
Path.copyDirectory(src, dst)
: copies the specific directory to a new path recursivelysrc
: the source pathdst
: the destination path- returns
true
for success, otherwisefalse
Path.moveFile(src, dst)
: moves the specific file to a new pathsrc
: the source pathdst
: the destination path- returns
true
for success, otherwisefalse
Path.moveDirectory(src, dst)
: moves the specific directory to a new path recursivelysrc
: the source pathdst
: the destination path- returns
true
for success, otherwisefalse
Path.removeFile(path, toTrashBin)
: removes the specific filepath
: the file pathtoTrashBin
:true
to remove to the trash bin, otherwise remove permanently- returns
true
for success, otherwisefalse
Path.removeDirectory(path, toTrashBin)
: removes the specific directory recursivelypath
: the directory pathtoTrashBin
:true
to remove to the trash bin, otherwise remove permanently- returns
true
for success, otherwisefalse
Path.touchFile(path)
: tries to create a file at the specific path, will touch its ancestorspath
: the file path- returns
true
for success, otherwisefalse
Path.touchDirectory(path)
: tries to create a directory at the specific path, will touch its ancestorspath
: the directory path- returns
true
for success, otherwisefalse
Static Variables
Path.executableFile
: readonly, gets the executable file pathPath.documentDirectory
: readonly, gets the documents directory pathPath.writableDirectory
: readonly, gets the writable directory pathPath.savedGamesDirectory
: readonly, gets the "Saved Games" directory path on Windows, or same asPath.writableDirectory
on other platforms
Constructors
-
FileInfo.new(path)
: constructs a file information object with the specific pathpath
: the file path
-
DirectoryInfo.new(path)
: constructs a directory information object with the specific pathpath
: the directory path
Methods
-
fileInfo:fullPath()
: gets the full path- returns the full path
-
fileInfo:parentPath()
: gets the path of the parent directory- returns the path of the parent directory
-
fileInfo:fileName()
: gets the file name- returns the file name, without extension
-
fileInfo:extName()
: gets the extension name- returns the extension name, without dot
-
fileInfo:empty()
: gets whether the file represented by theFileInfo
is empty- returns
true
if empty, otherwisefalse
- returns
-
fileInfo:exists()
: gets whether the file represented by theFileInfo
exists- returns
true
for exists, otherwisefalse
- returns
-
fileInfo:make()
: makes a file represented by theFileInfo
if it doesn't exist, fails if its ancestors don't exist- returns
true
for success, otherwisefalse
- returns
-
fileInfo:copyTo(dst)
: copies the file represented by theFileInfo
to a new pathdst
: the destination path- returns
true
for success, otherwisefalse
-
fileInfo:moveTo(dst)
: moves the file represented by theFileInfo
to a new pathdst
: the destination path- returns
true
for success, otherwisefalse
-
fileInfo:remove(toTrashBin)
: removes the file represented by theFileInfo
toTrashBin
:true
to remove to the trash bin, otherwise remove permanently- returns
true
for success, otherwisefalse
-
fileInfo:rename(newName[, newExt])
: renames the file represented by theFileInfo
newName
: the new file namenewExt
: the new extension name; omit to keep the old- returns
true
for success, otherwisefalse
-
fileInfo:parent()
: gets theDirectoryInfo
of theFileInfo
's parent- returns the
DirectoryInfo
of its parent
- returns the
-
fileInfo:readAll()
: reads all content of the file represented by theFileInfo
as string- returns the content string
-
directoryInfo:fullPath()
: gets the full path- returns the full path
-
directoryInfo:parentPath()
: gets the path of the parent directory- returns the path of the parent directory
-
directoryInfo:dirName()
: gets the directory name- returns the directory name
-
directoryInfo:empty()
: gets whether the directory represented by theDirectoryInfo
is empty- returns
true
if empty, otherwisefalse
- returns
-
directoryInfo:exists()
: gets whether the directory represented by theDirectoryInfo
exists- returns
true
for exists, otherwisefalse
- returns
-
directoryInfo:make()
: makes a directory represented by theDirectoryInfo
if it doesn't exist, fails if its ancestors don't exist- returns
true
for success, otherwisefalse
- returns
-
directoryInfo:copyTo(dst)
: copies the directory represented by theDirectoryInfo
to a new pathdst
: the destination path- returns
true
for success, otherwisefalse
-
directoryInfo:moveTo(dst)
: moves the directory represented by theDirectoryInfo
to a new pathdst
: the destination path- returns
true
for success, otherwisefalse
-
directoryInfo:remove(toTrashBin)
: removes the directory represented by theDirectoryInfo
toTrashBin
:true
to remove to the trash bin, otherwise remove permanently- returns
true
for success, otherwisefalse
-
directoryInfo:rename(newName)
: renames the directory represented by theDirectoryInfo
newName
: the new directory name- returns
true
for success, otherwisefalse
-
directoryInfo:getFiles(pattern = '*.*', recursive = false)
: gets sub-files under the directory represented by theDirectoryInfo
pattern
: lookup pattern, supports wildcards, eg."*.txt;*.json"
recursive
: whether lookup its sub-directories- returns a list of
FileInfo
objects
-
directoryInfo:getDirectories(recursive = false)
: gets sub-directories under the directory represented by theDirectoryInfo
recursive
: whether lookup its sub-directories- returns a list of
DirectoryInfo
objects
-
directoryInfo:parent()
: gets theDirectoryInfo
of thisDirectoryInfo
's parent- returns the
DirectoryInfo
of its parent
- returns the
Constructors
Image.new(palette)
: constructs an image object with the specificPalette
assetpalette
: thePalette
loaded byResources.load(...)
Image.new()
: constructs a true-color image object
Object Fields
image.channels
: readonly, gets the channels of theImage
, 1 for paletted, 4 for true-colorimage.width
: readonly, gets the width of theImage
image.height
: readonly, gets the height of theImage
Methods
image:resize(width, height, stretch = true)
: resizes theImage
with the specific sizewidth
: the widthheight
: the heightstretch
:true
to stretch theImage
, otherwise to clip- returns
true
for success, otherwisefalse
image:get(x, y)
: gets theColor
orPalette
index at the specific indexx
: starts from 0y
: starts from 0- returns
Color
or palette index
image:set(x, y, val)
: sets theColor
orPalette
index at the specific indexx
: starts from 0y
: starts from 0val
:Color
orPalette
index- returns
true
for success, otherwisefalse
image:blit(dst, x, y[, w, h[, sx, sy]])
: blits theImage
to another onedst
: the specific destinationImage
x
: the destination xy
: the destination yw
: the destination widthh
: the destination heightsx
: the source xsy
: the source y- returns
true
for success, otherwisefalse
image:fromImage(img)
: loads content from anotherImage
img
: the specificImage
to load- returns
true
for success, otherwisefalse
image:fromBlank(width, height, paletted = 0)
: loads blank contentwidth
: the specific widthheight
: the specific heightpaletted
: 0 for true-color, non-zero for paletted- returns
true
for success, otherwisefalse
image:toBytes(bytes, type = 'png')
: encodes theImage
toBytes
bytes
: theBytes
to receive, its cursor will be at the endtype
: can be one in "png", "jpg", "bmp", "tga", "img"- returns
bytes
for success, otherwisenil
image:fromBytes(bytes)
: decodes the specificBytes
bytes
: theBytes
to retrieve from start till end, its cursor won't be moved- returns
true
for success, otherwisefalse
Constants
Json.Null
Constructors
Json.new()
: constructs a JSON object
Methods
json:toString(pretty = true)
: serializes theJson
to stringpretty
: whether to serialize in a friendly to read format- returns serialized string
json:fromString(txt)
: parsesJson
data from the specific stringtxt
: the text to parse- returns
true
for success, otherwisefalse
json:toTable(allowNull = false)
: serializes theJson
to Lua tableallowNull
:true
to convertJson
null
toJson.Null
, otherwise to Luanil
- returns serialized Lua table
json:fromTable(tbl)
: parsesJson
data from the specific Lua table, ignores incompatible data typestbl
: the table to parse- returns
true
for success, otherwisefalse
Constants
-
Vec2.Zero
: equals toVec2.new(0, 0)
-
Vec2.One
: equals toVec2.new(1, 1)
-
Vec2.Left
: equals toVec2.new(-1, 0)
-
Vec2.Right
: equals toVec2.new(1, 0)
-
Vec2.Up
: equals toVec2.new(0, -1)
-
Vec2.Down
: equals toVec2.new(0, 1)
-
Vec3.Zero
: equals toVec3.new(0, 0, 0)
-
Vec3.One
: equals toVec3.new(1, 1, 1)
-
Vec4.Zero
: equals toVec4.new(0, 0, 0, 0)
-
Vec4.One
: equals toVec4.new(1, 1, 1, 1)
Static Functions
-
Rect.byXYWH(x, y, w, h)
: constructs a rectangle object in real numbers by position and size -
Recti.byXYWH(x, y, w, h)
: constructs a rectangle object in integers by position and size
Constructors
-
Vec2.new([x, y])
: constructs a vector object in 2 dimensions -
Vec3.new([x, y, z])
: constructs a vector object in 3 dimensions -
Vec4.new([x, y, z, w])
: constructs a vector object in 4 dimensions -
Rect.new([x0, y0, x1, y1])
: constructs a rectangle object in real numbers by points -
Recti.new([x0, y0, x1, y1])
: constructs a rectangle object in integers by points -
Rot.new([s, c])
: constructs a rotation object
Operators
-
vec2:__add(vec2_)
: adds with anotherVec2
componentwisely -
vec2:__sub(vec2_)
: subtracts by anotherVec2
componentwisely -
vec2:__mul(num)
: multiplies with another number -
vec2:__mul(vec2_)
: multiplies with anotherVec2
componentwisely -
vec2:__unm()
: takes the oppositeVec2
componentwisely -
vec2:__len()
: gets the length of theVec2
-
vec2:__eq(vec2_)
: compares with anotherVec2
for equality -
vec3:__add(vec3_)
: adds with anotherVec3
componentwisely -
vec3:__sub(vec3_)
: subtracts by anotherVec3
componentwisely -
vec3:__mul(num)
: multiplies with another number -
vec3:__mul(vec3_)
: multiplies with anotherVec3
componentwisely -
vec3:__unm()
: takes the oppositeVec3
componentwisely -
vec3:__len()
: gets the length of theVec3
-
vec3:__eq(vec3_)
: compares with anotherVec3
for equality -
vec4:__add(vec4_)
: adds with anotherVec4
componentwisely -
vec4:__sub(vec4_)
: subtracts by anotherVec4
componentwisely -
vec4:__mul(num)
: multiplies with another number -
vec4:__mul(vec4_)
: multiplies with anotherVec4
componentwisely -
vec4:__unm()
: takes the oppositeVec4
componentwisely -
vec4:__eq(vec4_)
: compares with anotherVec4
for equality -
rot:__add(rot_)
: adds with anotherRot
in angle -
rot:__sub(rot_)
: subtracts by anotherRot
in angle -
rot:__mul(vec2)
: rotates anotherVec2
-
rot:__mul(rot_)
: rotates anotherRot
-
rot:__unm()
: takes the oppositeRot
in angle -
rot:__eq(rot_)
: compares with anotherRot
for equality -
rect:__eq(rect_)
: compares with anotherRect
for equality -
recti:__eq(recti_)
: compares with anotherRecti
for equality
Object Fields
-
vec2.x
: gets or sets the x component -
vec2.y
: gets or sets the y component -
vec2.normalized
: readonly, gets the normalizedVec2
-
vec2.length
: readonly, gets the length -
vec2.angle
: readonly, gets the rotated angle in radians as a vector -
vec3.x
: gets or sets the x component -
vec3.y
: gets or sets the y component -
vec3.z
: gets or sets the z component -
vec3.normalized
: readonly, gets the normalizedVec3
-
vec3.length
: readonly, gets the length -
rect4.x
: gets or sets the x component -
rect4.y
: gets or sets the y component -
rect4.z
: gets or sets the z component -
rect4.w
: gets or sets the w component -
rot.s
: gets or sets the sine component -
rot.c
: gets or sets the cosine component -
rot.angle
: gets or sets the angle in radians denoted by theRot
-
rect.x0
: gets or sets the first x component -
rect.y0
: gets or sets the first y component -
rect.x1
: gets or sets the second x component -
rect.y1
: gets or sets the second y component -
recti.x0
: gets or sets the first x component -
recti.y0
: gets or sets the first y component -
recti.x1
: gets or sets the second x component -
recti.y1
: gets or sets the second y component
Methods
-
vec2:normalize()
: normalizes theVec2
- returns the original length before normalization
-
vec2:distanceTo(vec2_)
: gets the distance between this and anotherVec2
- returns the distance number
-
vec2:dot(vec2_)
: applies a dot multiplication- returns the dot result as number
-
vec2:cross(num)
: applies a cross multiplication- returns the cross
Vec2
- returns the cross
-
vec2:cross(vec2_)
: applies a cross multiplication- returns the cross result as number
-
vec2:angleTo(vec2_)
: gets the angle between this and anotherVec2
as vectors- returns the angle in radians
-
vec2:rotated(angle[, pivot])
: gets the rotatedVec2
angle
: the angle to rotatepivot
: the pivotVec2
to rotate around- returns the rotated
Vec2
-
vec2:rotated(rot[, pivot])
: gets the rotatedVec2
rot
: theRot
to rotatepivot
: the pivotVec2
to rotate around- returns the rotated
Vec2
-
vec3:normalize()
: normalizes theVec3
- returns the original length before normalization
-
vec3:dot(vec3_)
: applies a dot multiplication- returns the dot result as number
-
rect:xMin()
: gets the minimum x component -
rect:yMin()
: gets the minimum y component -
rect:xMax()
: gets the maximum x component -
rect:xMax()
: gets the maximum y component -
rect:width()
: gets the width, equals torect:xMax() - rect:xMin()
-
rect:height()
: gets the height, equals torect:yMax() - rect:yMin()
-
recti:xMin()
: gets the minimum x component -
recti:yMin()
: gets the minimum y component -
recti:xMax()
: gets the maximum x component -
recti:xMax()
: gets the maximum y component -
recti:width()
: gets the width, equals torect:xMax() - rect:xMin() + 1
-
recti:height()
: gets the height, equals torect:yMax() - rect:yMin() + 1
Static Functions
Math.intersects(shapeA, shapeB)
: detects whether two shapes intersects with each othershapeA
: the first shapeshapeB
: the second shape- returns
true
for intersects, otherwisefalse
Both shape parameters can be:
- Point:
Vec2
- Line (segment):
Vec4
,x
,y
for first point,z
,w
for second - Circle:
Vec3
,x
,y
for center,z
for radius - AABB:
Rect
;Recti
is supported as well, but converted toRect
internally to determine against other shapes except for anotherRecti
Constants
Network.None
Network.Udp
Network.Tcp
Constructors
Network.new(onRecv[, onEstb[, onDisc]])
: constructs a network objectonRecv
: callback on receivedonEstb
: callback on connection establishedonDisc
: callback on connection disconnected
The callback of received event is an invokable in form of function (data, size, addr) end
, which accepts three parameters respectively represent for the data has been just received, the data size corresponding to specific types, and the remote adress string. The type of the first parameter is determined by the "data_type" option.
The callback of connection established is an invokable in form of function (addr) end
, which accepts a parameter represents for the remote address string; nil
for failure for outcoming connection. It's invoked when either incoming or outcoming connection established; ignored by UDP.
The callback of disconnected is an invokable in form of function (addr) end
, which accepts a parameter represents for the remote address string. It's invoked when either incoming or outcoming connection disconnected; ignored by UDP.
Object Fields
network.ready
: readonly, gets whether theNetwork
is ready
Methods
network:getOption(key)
: gets the option value of the specific keykey
: the option key to get- returns option value
network:setOption(key, val)
: sets option value of the specific keykey
: the option key to setval
: the value to set
Currently there is only one available option:
Key | Value | Note |
---|---|---|
"data_type" | Can be one in "stream", "bytes", "string", "json", defaults to "json" | Data type for transmission/datagram |
network:open(addr[, protocal])
: opens aNetwork
as either server or clientaddr
: the addressprotocal
: can be one inNetwork.Udp
,Network.Tcp
- returns
true
for success, otherwisefalse
network:close()
: closes aNetwork
, clears all options; will neither be impossible to send nor receive anything after closing- returns
true
for success, otherwisefalse
- returns
An addr
argument is combined with four parts, direction, protocol, address and port:
Part | Value |
---|---|
Direction | > for connecting, < for listening |
Protocol | udp:// , tcp:// |
Address | IP address |
Port | Port number |
For example:
Address string | Connectivity |
---|---|
">tcp://192.168.0.1:12000" | As client, connects to 192.168.0.1 port 12000 via TCP |
"<udp://127.0.0.1:12000" | As server, listens from local host port 12000 via UDP |
"udp://192.168.0.1:12000" | As client, sends to 192.168.0.1 port 12000 via UDP |
"tcp://12000" | As server, listens from port 12000 via TCP |
"192.168.0.1:12000" | As client, connects to 192.168.0.1 port 12000, protocal determined by the explicit protocal parameter |
"12000" | As server, listens from port 12000, protocal determined by the explicit protocal parameter |
network:poll([timeoutMs])
: polls pendingNetwork
events manually; do not need to call this function if a program already entered theupdate(delta)
looptimeoutMs
: the timeout value
network:disconnect()
: disconnects from remote peersnetwork:send(bytes)
: sends the specificBytes
bytes
: theBytes
to send- returns
true
for success, otherwisefalse
network:send(txt)
: sends the specific stringtxt
: the string to send- returns
true
for success, otherwisefalse
network:send(json)
: sends the specificJson
json
theJson
to send- returns
true
for success, otherwisefalse
network:send(tbl)
: sends the specific Lua table asJson
tbl
the Lua table to send- returns
true
for success, otherwisefalse
network:broadcast(bytes)
: broadcasts the specificBytes
bytes
: theBytes
to broadcast- returns
true
for success, otherwisefalse
network:broadcast(txt)
: broadcasts the specific stringtxt
: the string to broadcast- returns
true
for success, otherwisefalse
network:broadcast(json)
: broadcasts the specificJson
json
: theJson
to broadcast- returns
true
for success, otherwisefalse
network:broadcast(tbl)
: broadcasts the specific Lua table asJson
tbl
: the Lua table to broadcast- returns
true
for success, otherwisefalse
A single transmission or datagram cannot be longer than 512KB.
Consider closing and setting a Network
object to nil
as soon as it's no longer in use.
For "stream", it sends and receives raw Bytes
, you are free parsing and serializing for your own protocol.
For "bytes", an extra 32-bit unsigned integer will be automatically packed at head of Bytes
before sending, the size head itself also counts; Bytes
parameter in the received callback doesn't contain that head. In short words, it's transparent between Bitty Engine projects, but it's helpful to communicate with other endpoints to distinguish different messages, and you have to adapt the rule for other Network
endpoints.
For both "string" and "json", the underneath data flow always end up with a zero byte, vice versa, received string and Json
must end up with a terminal zero byte.
Static Functions
-
Platform.surf(url)
: surfs the Internet via browserurl
: the URL address to surf
-
Platform.browse(dir)
: browses the filesystem via explorerdir
: the directory path to browse
-
Platform.hasClipboardText()
: gets whether there is text content in the clipboard- returns
true
for nonempty, otherwisefalse
- returns
-
Platform.getClipboardText()
: gets the text content in the clipboard- returns text content
-
Platform.setClipboardText(txt)
: sets the text content in the clipboardtxt
: the text to set
-
Platform.execute(cmd)
: executes the specific system command; this function invokes native command on desktops, and JavaScript function in browsercmd
: the command to execute
-
Platform.openFile([title[, filter[, multiselect]]])
: popups an open-file-dialogtitle
: the title textfilter
: the file filter, eg."Text files (*.txt);*.txt;All files (*.*);*"
multiselect
:true
for multiselect,false
for single file select- returns selected file path or paths, or
nil
for canceled
-
Platform.saveFile([title[, filter]])
: popups a save-file-dialogtitle
: the title textfilter
: the file filter- returns specified file path, or
nil
for canceled
-
Platform.selectDirectory([title])
: popups a select-directory-dialogtitle
: the title text- returns selected directory path, or
nil
for canceled
Static Variables
Platform.os
: readonly, gets the current running OSPlatform.endian
: readonly, gets the current endian- returns either "little-endian" or "big-endian"
This module declares a minimal protocol to handle asynchronization.
Constants
Promise.Pending
Promise.Resolved
Promise.Rejected
Object Fields
promise.state
: gets the state of thePromise
object, can be one inPromise.Pending
,Promise.Resolved
,Promise.Rejected
promise.value
: gets the fulfilled value of thePromise
object, ornil
Methods
promise:thus(handler)
: sets the specific callback to handle on succeededhandler
: in form offunction (...) end
, an invokable object which accepts optional arguments- returns this
Promise
itself
promise:catch(handler)
: sets the specific callback to handle on failedhandler
: in form offunction ([err]) end
, an invokable object- returns this
Promise
itself
promise:finally(handler)
: sets the specific callback to handle on finishedhandler
: in form offunction () end
, an invokable object- returns this
Promise
itself
This module contains constants indicating accessibilities for other modules.
Constants
Stream.Read
Stream.Write
Stream.Append
Stream.ReadWrite
Experimental feature. This module offers fetching via HTTP.
Functions
Implements a Promise
protocol for HTTP accessing and manipulating.
fetch(url[, options])
: requests the specific HTTP resourceurl
: the URL to requestoptions
: the optionJson
or Lua table- returns
Promise
object
The thus
handler of the returned Promise
object takes an invokable object in form of function (rsp) end
which accepts the responded content. The catch
handler of the returned Promise
object takes an invokable object in form of function (err) end
. The finally
handler of the returned Promise
object takes an invokable object in form of function () end
.
For example:
fetch('https://github.com', {
method = 'GET',
headers = {
['Content-Type'] = 'text/html',
['User-Agent'] = 'Mozilla/5.0 Gecko/20100101 Firefox/83.0'
}
})
:thus(function (rsp)
print(rsp)
end)
:catch(function (err)
print('Error.')
end)
:finally(function ()
print('Finished.')
end)
Option | Values | Description |
---|---|---|
method |
"GET", "POST", "PUT", "DELETE", etc. | Specific method to perform HTTP request |
headers |
Valid HTTP headers | Optional. Header data |
body |
Request body | Optional. Body data |
hint |
"bytes", "string", "json" | Optional, defaults to "string". Prefers how to interpret respond data |
allow_insecure_connection_for_https |
true , false |
Optional, defaults to false , for desktop only. Specifies whether to allow insecure connection for HTTPS |
Static Functions
Resources.load(entry[, hint])
: loads a resource from the specific asset entryentry
: the entry name to loadhint
: the type hint- returns loaded resource, or
nil
Resources.load(path[, hint])
: loads a resource from the specific file pathpath
: the file path to loadhint
: the type hint- returns loaded resource, or
nil
Resources.load(bytes[, hint])
: loads a resource from the specificBytes
; available forTexture
,Sfx
,Music
bytes
: theBytes
to load, its cursor won't be movedhint
: the type hint- returns loaded resource, or
nil
Resources.load(str[, hint])
: loads a resource from the specific asset content as stringstr
: the asset content as string to loadhint
: the type hint- returns loaded resource, or
nil
Resources.load(json[, hint])
: loads a resource from the specificJson
objectjson
: theJson
to loadhint
: the type hint- returns loaded resource, or
nil
Resources.load(tbl[, hint])
: loads a resource from the specific Lua table; similar to theJson
version, but in table formtbl
: the Lua table to loadhint
: the type hint- returns loaded resource, or
nil
Resources.load(img[, hint])
: loads a resource from the specificImage
objectimg
: theImage
to loadhint
: the type hint- returns loaded resource, or
nil
Resources.wait(res)
: waits until the resource is loaded or timeoutres
: the resource to wait for- returns
true
for ready to use, otherwisefalse
Resources.unload(res)
: unloads a resourceres
: the resource to unload
Resources.collect()
: collects all unused resources
The hint
can be one in Palette
, Texture
, Sprite
, Map
, Sfx
, Music
. Bitty Engine can infer asset types from extension or content most of the time. However hint is necessary if there is yet insufficient information to tell a type, or to distinguish as either Sfx
or Music
when loading an audio asset.
For example:
foo = Resources.load('bar.pal') -- Load a palette.
foo = Resources.load({ width = 128, height = 128 }) -- Load a blank texture.
local data = {
width = 8, height = 8,
count = 2,
data = {
{
x = 16, y = 0, width = 8, height = 8,
interval = 0.25,
key = 'idle'
},
{
x = 24, y = 0, width = 8, height = 8,
interval = 0.25,
key = ''
}
},
ref = baz -- Ref by object.
}
foo = Resources.load(data) -- Load a sprite.
local data = {
tiles = {
count = { 8, 8 }
},
width = 60, height = 40,
data = { ... },
ref = 'baz.png' -- Ref by asset name.
}
foo = Resources.load(data) -- Load a map.
foo = Resources.load('bar.mp3', Sfx) -- Load an SFX.
foo = Resources.load('bar.mp3', Music) -- Load a piece of music.
The asynchronous Resources.load(...)
returns a resource handle immediately. It is lazy evaluated, loading is deferred until specific reading and writing access happens. The synchronous Resources.wait(...)
also loads it, it returns immediately if the specific resource is already loaded, otherwise it waits until loaded or timeout.
Consider using Resources.unload(...)
or Resources.collect()
to unload unused resources (loaded by Resources.load(...)
) periodically and properly, or there would be memory leak. One possible practice is to call Lua's GC then collect resources after loading a new level, since the old one is no longer in use:
collectgarbage()
Resources.collect()
Can be loaded by Resources.load(...)
, only happens when Bitty Engine cannot determine specific sub asset type.
Can be loaded by Resources.load(...)
.
Constructors
Font.new(entry, size = 14 | Vec2.new(8, 8), permeation = 1)
: constructs a font object from the specific (TrueType or Bitmap) font asset with the specific size and permeationentry
: the entry name to loadsize
: can be either a number for TrueType, or aVec2
for Bitmappermeation
: indicates how to blur glyph edges with the alpha channel, with range of values from 0 to 255
Font.new(path, size = 14 | Vec2.new(8, 8), permeation = 1)
: constructs a font object from the specific (TrueType or Bitmap) font file with the specific size and permeationpath
: the file path to loadsize
: can be either a number for TrueType, or aVec2
for Bitmappermeation
: indicates how to blur glyph edges with the alpha channel, with range of values from 0 to 255
Font.new(img, size = Vec2.new(8, 8), permeation = 1)
: constructs a font object from the specific (Bitmap)Image
with the specific size and permeationimg
: theImage
to loadsize
: the size asVec2
for a characterpermeation
: indicates how to blur glyph edges with the alpha channel, with range of values from 0 to 255
Font.new(nil, size = 14, permeation = 1)
: constructs a font object from the default font with the specific size and permeationsize
: the size as numberpermeation
: indicates how to blur glyph edges with the alpha channel, with range of values from 0 to 255
Font
is constructed like regular object and managed by GC, do not need to unload it manually. The permeation
parameter indicates how to handle font transparency, zero means using values from a font file, while non-zero means a specified threshold for whether a pixel shall pass (non-transparent) or be blocked (transparent).
Can be loaded by Resources.load(...)
.
Object Fields
texture.width
: readonly, gets theTexture
widthtexture.height
: readonly, gets theTexture
height
Methods
texture:blend(mode)
: sets the blend state of theTexture
with the specific modemode
: the blend mode to set; refer to the blend modes ofCanvas
- returns
true
for success, otherwisefalse
Can be loaded by Resources.load(...)
.
Object Fields
-
sprite.count
: readonly, gets theSprite
frame count -
sprite.width
: readonly, gets theSprite
width of every frame -
sprite.height
: readonly, gets theSprite
height of every frame -
sprite.hFlip
: gets or sets whether theSprite
is flipped horizontally -
sprite.vFlip
: gets or sets whether theSprite
is flipped vertically
Methods
sprite:play(beginIndex = -1, endIndex = -1, reset = true, loop = true, async = false)
: plays the specific animation, use -1 for both begin and end indices to play through all framesbeginIndex
: the begin frame index, starts from 0endIndex
: the end frame index, starts from 0reset
: whether resets to the initial animation frameloop
:true
for loop, otherwise plays onceasync
:true
for asynchronously playing, otherwise plays synchronously- returns
true
for success, otherwisefalse
, and a secondary value for estimated duration if plays synchronously; the secondary value would be always -1 if plays asynchronously
sprite:play(beginStr, reset = true, loop = true, async = false)
: plays the specific animationbeginStr
: the animation name stringreset
: whether resets to the initial animation frameloop
:true
for loop, otherwise plays onceasync
:true
for asynchronously playing, otherwise plays synchronously- returns
true
for success, otherwisefalse
, and a secondary value for estimated duration if plays synchronously; the secondary value would be always -1 if plays asynchronously
sprite:pause()
: pauses playing- returns
true
for success, otherwisefalse
- returns
sprite:resume()
: resumes playing- returns
true
for success, otherwisefalse
- returns
sprite:stop()
: stops playing- returns
true
for success, otherwisefalse
- returns
It communicates across internal threads when play a sprite animation synchronously, this might take lots of time if there are lots of sprites. Consider playing it asynchronously if this matters in your actual project.
Can be loaded by Resources.load(...)
.
Object Fields
map.width
: readonly, gets theMap
widthmap.height
: readonly, gets theMap
height
Can be loaded by Resources.load(...)
.
Can be loaded by Resources.load(...)
.
The coordinate definition in Bitty Engine is as follow:
The zero point is to the top-left corner, the x, y axises increase in right, bottom respectively.
Functions
cls([col])
: clears the screen with the specificColor
col
: optional, defaults to the previous passed value to this function- returns the previous clear
Color
color(col)
: sets the activeColor
with a specific valuecol
: theColor
to set- returns the previous active
Color
color()
: resets the activeColor
to whitesync()
: synchronizes commands to graphics manually, also updatesNetwork
andWeb
links- returns synchronized command count
Functions
plot(x, y[, col])
: draws a pointx
: the x positiony
: the y positioncol
: omit to use the activeColor
line(x0, y0, x1, y1[, col])
: draws a linex0
: the first x positiony0
: the first y positionx1
: the second x positiony1
: the second y positioncol
: omit to use the activeColor
circ(x, y, r, fill = false[, col])
: draws a ciclex
: the x positiony
: the y positionr
: the radiusfill
:true
for fillcol
: omit to use the activeColor
ellipse(x, y, rx, ry, fill = false[, col])
: draws an ellipsex
: the x positiony
: the y positionrx
: the x radiusry
: the y radiusfill
:true
for fillcol
: omit to use the activeColor
pie(x, y, r, startAngle, endAngle, fill = false[, col])
: draws a piex
: the x positiony
: the y positionr
: the radiusstartAngle
: the start angle in radiansendAngle
: the end angle in radiansfill
:true
for fillcol
: omit to use the activeColor
rect(x0, y0, x1, y1, fill = false[, col[, rad]])
: draws a rectanglex0
: the first x positiony0
: the first y positionx1
: the second x positiony1
: the second y positionfill
:true
for fillcol
: omit to use the activeColor
rad
: the radius of the corner arcs of the rectangle
text(txt, x, y[, col, margin = 1, scale = 1])
: draws texttxt
: the text to drawx
: the x positiony
: the y positioncol
: omit to use the activeColor
margin
: the margin distancescale
: the scale factor
tri(p0, p1, p2, fill = false[, col])
: draws a trianglep0
:Vec2
for the first pointp1
:Vec2
for the second pointp2
:Vec2
for the third pointfill
:true
for fillcol
: omit to use the activeColor
Functions
pget(res, index)
: gets theColor
from the specificPalette
resourceres
: thePalette
resourceindex
: starts from 0- returns
Color
pset(res, index, col)
: sets theColor
to the specificPalette
resourceres
: thePalette
resourceindex
: starts from 0col
: theColor
to set
Functions
font(font_)
: sets the activeFont
for thetext(...)
functionfont_
: theFont
resource
font()
: resets the activeFont
to defaultmeasure(txt, font, margin = 1, scale = 1)
: measures the size of the specific texttxt
: the text to measurefont
: theFont
to measure with,nil
to use defaultmargin
: the margin distancescale
: the scale factor- returns
width
,height
for both dimensions respectively
Functions
tex(res, x, y[, w, h[, sx, sy[, sw, sh[, rotAngle, rotCenter = Vec2.new(0.5, 0.5), hFlip = false, vFlip = false, col = Color.new(255, 255, 255, 255)]]]])
: draws the specificTexture
resourceres
: theTexture
resourcex
: the destination x positiony
: the destination y positionw
: the destination width; omit to use the resource widthy
: the destination height; omit to use the resource heightsx
: the source x position to sample, defaults to 0sy
: the source y position to sample, defaults to 0sw
: the source width to sample, defaults to the resource widthsh
: the source height to sample, defaults to the resource heightrotAngle
: the rotation angle in radiansrotCenter
: the rotation centerhFlip
: whether to flip horizontallyvFlip
: whether to flip verticallycol
: additionalColor
multiplied to render theTexture
Functions
spr(res, x, y[, w, h[, rotAngle, rotCenter = Vec2.new(0.5, 0.5), col = Color.new(255, 255, 255, 255)]])
: draws the specificSprite
resourceres
: theSprite
resourcex
: the destination x positiony
: the destination y positionw
: the destination widthy
: the destination heightrotAngle
: the rotation angle in radiansrotCenter
: the rotation centercol
: additionalColor
multiplied to render theSprite
Functions
map(res, x, y, col = Color.new(255, 255, 255, 255), scale = 1)
: draws the specificMap
resourceres
: theMap
resourcex
: the destination x positiony
: the destination y positioncol
: additionalColor
multiplied to render theMap
scale
: positive integer, the scale factor
mget(res, x, y)
: gets the tile index from the specificMap
resourceres
: theMap
resourcex
: starts from 0y
: starts from 0- returns tile index
mset(res, x, y, cel)
: sets the tile index to the specificMap
resourceres
: theMap
resourcex
: starts from 0y
: starts from 0cel
: the tile index
Functions
volume(sfxVol[, musicVol])
: sets the audio volumesfxVol
: volume for all SFX channels, with range of values from 0.0 to 1.0musicVol
: with range of values from 0.0 to 1.0
volume({ sfxVol1, sfxVol2, sfxVol3, sfxVol4 }[, musicVol])
: sets the audio volume{ sfxVol1, sfxVol2, sfxVol3, sfxVol4 }
: volume for SFX channels respectively, with range of values from 0.0 to 1.0 at each, -1 to leave as ismusicVol
: with range of values from 0.0 to 1.0
Functions
play(sfx, loop = false[, fade[, channel]])
: plays the specificSfx
resourcesfx
: theSfx
resourceloop
:true
for loop, otherwise plays oncefade
: the fade in time in secondschannel
: the specific channel to play this sound, starts from 1; omit to pick an available automatically
stop(sfx[, fade])
: stops the specificSfx
resourcesfx
: theSfx
resourcefade
: the fade out time in seconds
Functions
play(music, loop = false[, fade[, pos]])
: plays the specificMusic
resourcemusic
: theMusic
resourceloop
:true
for loop, otherwise plays oncefade
: the fade in time in secondspos
: real number, the specific position in seconds to start from; affects MP3, OGG, WAV, FLAC, and some MOD formats
stop(music[, fade])
: stops the specificMusic
resourcemusic
: theMusic
resourcefade
: the fade out time in seconds
A gamepad is a virtual entity, its buttons are binded to a keyboard or an actual gamepad hardware.
Functions
btn([button[, index]])
: gets whether the specific gamepad button is pressedbutton
: the button index; omit to get any keyindex
: the gamepad index, starts from 1- returns
true
for pressed, otherwisefalse
btnp([button[, index]])
: gets whether the specific gamepad button is released from pressingbutton
: the button index; omit to get any keyindex
: the gamepad index, starts from 1- returns
true
for released, otherwisefalse
rumble(index, lowHz = 100[, hiHz, ms = 100])
: rumbles the specific gamepad, if an actual hardware is binded to any key of the gamepad entityindex
: the gamepad index, starts from 1
For the button
parameter, 0, 1, 2, 3, 4, 5 are for Left, Right, Up, Down, A, B respectively. Seealso the "Gamepad" example under the "Primitives" category.
Functions
key(code)
: gets whether the specific key is pressedcode
: the key code on keyboard- returns
true
for pressed, otherwisefalse
keyp(code)
: gets whether the specific key is released from pressingcode
: the key code on keyboard- returns
true
for released, otherwisefalse
See keycodes for more readable presentation. Seealso the "Keyboard" example under the "Primitives" category.
Functions
mouse([index])
: gets the current mouse (or touch) statesindex
: always 1 for the mouse, or the finger index with touch screens, starts from 1- returns
x
,y
,b1
,b2
,b3
,wheel
for the mouse position and the LMB, RMB, MMB, wheel state respectively,x
andy
could be NaN if the mouse is outside the canvas,wheel
can be negative, positive or zero
Seealso the "Mouse" example under the "Primitives" category.
Functions
camera(x, y)
: sets the camera offset, affects all coordinate-based primitivesx
: the x offsety
: the y offset- returns the previous camera offset
x
,y
, or bothnil
for non-offset
camera()
: resets the camera offset to 0, 0- returns the previous camera offset
x
,y
, or bothnil
for non-offset
- returns the previous camera offset
Functions
clip(x, y, w, h)
: sets the clip areax
: the x offset to clipy
: the y offset to clipw
: the clip widthh
: the clip height- returns the previous clip area
x
,y
,w
,h
, or allnil
for non-clip
clip()
: resets the clip area to none- returns the previous clip area
x
,y
,w
,h
, or allnil
for non-clip
- returns the previous clip area
Functions
blend(mode)
: sets the blend state with the specific modemode
: the blend mode to set; refer to the blend modes ofCanvas
blend()
: resets the blend state to alpha blend
Due to space limitation in the page, read Physics for details.
Static Functions
Application.setOption(key, ...)
: sets option value of the specific keykey
: the option key to set
Available options:
Key | Value | Note |
---|---|---|
"title" | String, title |
Sets the title of the application window |
"minimum_size" | Integers, width , height |
Sets the minimum size of the application window |
"maximum_size" | Integers, width , height |
Sets the maximum size of the application window |
"bordered" | Boolean, bordered |
Sets whether the application window is bordered |
"resizable" | Boolean, resizable |
Sets whether the application window is resizable |
"position" | Integers, x , y |
Sets the position of the application window |
"display_index" | Integers, index |
Sets the index where the application window will be displayed on that device |
Application.setCursor(img[, x, y])
: sets the mouse cursorimg
: the specificImage
to set,nil
to resetx
: the spot x, with range of values from 0.0 to 1.0y
: the spot y, with range of values from 0.0 to 1.0
Application.size()
: gets the application window size- returns
width
,height
- returns
Application.resize(w, h)
: resizes the application windoww
: the expected widthh
: the expected height
Application.resize(size)
: resizes the application windowsize
: can be one in "fullscreen", "windowed"
Application.raise()
: raises the application window
Constants
-
Canvas.BlendModeNone
-
Canvas.BlendModeBlend
-
Canvas.BlendModeAdd
-
Canvas.BlendModeMod
-
Canvas.BlendModeMul
-
Canvas.BlendFactorZero
-
Canvas.BlendFactorOne
-
Canvas.BlendFactorSrcColor
-
Canvas.BlendFactorOneMinusSrcColor
-
Canvas.BlendFactorSrcAlpha
-
Canvas.BlendFactorOneMinusSrcAlpha
-
Canvas.BlendFactorDstColor
-
Canvas.BlendFactorOneMinusDstColor
-
Canvas.BlendFactorDstAlpha
-
Canvas.BlendFactorOneMinusDstAlpha
-
Canvas.BlendOperationAdd
-
Canvas.BlendOperationSub
-
Canvas.BlendOperationRevSub
-
Canvas.BlendOperationMin
-
Canvas.BlendOperationMax
Static Functions
Canvas.compose(srcColFactor, dstColFactor, colOp, srcAlphaFactor, dstAlphaFactor, alphaOp)
: composes a blend value from the specific parameterssrcColFactor
: the specific source color factordstColFactor
: the specific destination color factorcolOp
: the specific color operationsrcAlphaFactor
: the specific source alpha factordstAlphaFactor
: the specific destination alpha factoralphaOp
: the specific alpha operation- returns composed blend option
Static Variables
Canvas.main
: readonly, gets the mainCanvas
Object Fields
canvas.target
: gets or sets the render target of theCanvas
,nil
for the main canvascanvas.autoCls
: gets or sets whether to clear the canvas automatically, eithertrue
orfalse
Methods
canvas:size()
: gets theCanvas
size- returns
width
,height
- returns
canvas:resize(width, height)
: resizes theCanvas
width
: the specific width, 0 to adapt automaticallyheight
: the specific height, 0 to adapt automatically- returns
true
for success, otherwisefalse
Project accepts strategies, add a "strategies" field in "info.json" to enable specific options, eg.
{
...
"strategies": [
"batch_map"
]
}
Currently there is only one available strategy, change and try if it's needed:
Strategy | Description | Note |
---|---|---|
"batch_map" | Hints to batch map for better rendering performance, but occupies more memory | Always on for HTML build |
"linear_canvas" | Hints to set canvas filtering as linear | |
"anisotropic_canvas" | Hints to set canvas filtering as anisotropic |
Constants
Project.new()
: constructs a project object
Static Variables
Project.main
: readonly, gets the mainProject
Methods
project:fullPath()
: gets the full path of theProject
- returns the full path of the
Project
, ornil
- returns the full path of the
project:getAssets([pattern])
: gets all asset names in theProject
pattern
: lookup pattern, supports wildcards- returns a list of asset entries, or
nil
project:load(path)
: loads thisProject
from the specific path; for user constructedProject
onlypath
: the specific path to load from- returns
true
for success, otherwisefalse
project:save(path)
: saves thisProject
to the specific path; for user constructedProject
onlypath
: the specific path to save to- returns
true
for success, otherwisefalse
project:exists(name)
: gets whether the specific asset exists in theProject
name
: the asset name to look for- returns
true
for exists, otherwisefalse
project:read(name)
: reads the content of the specific asset; this method can read all asset types except for codename
: the asset name to read- returns asset content as
Bytes
and its cursor will be at the end, ornil
project:write(name, bytes, overwrite = true)
: writes the specificBytes
to theProject
; for user constructedProject
onlyname
: the asset name to writebytes
: theBytes
to writeoverwrite
:true
to overwrite- returns
true
for success, otherwisefalse
project:remove(name)
: removes the specific asset from theProject
; for user constructedProject
onlyname
: the asset name to remove- returns
true
for success, otherwisefalse
project:strategies()
: gets all effective strategies- returns a strategy list, in a list of string, could be empty or
nil
- returns a strategy list, in a list of string, could be empty or
This module is used for debugging purposes.
Static Functions
Debug.setBreakpoint(src, ln, brk = true)
: sets or unsets a breakpoint programminglysrc
: the source fileln
: the line numberbrk
: whether to set or unset- returns
true
for success, otherwisefalse
Debug.clearBreakpoints([src])
: clears breakpoints programminglysrc
: the source file to clear; omit to clear all in project- returns
true
for success, otherwisefalse
Debug.clearConsole()
: clears the console output programminglyDebug.getTimeout()
: gets the invoking timeout value- returns invoking timeout value
Debug.setTimeout(val)
: sets the invoking timeout value to the specific secondsval
: the timeout value in seconds, 0 to disable timeout
Debug.setTimeout()
: resets the invoking timeout value to default (10 seconds)Debug.trace([message[, level]])
: gets the stack trace- returns the traceback string
Click "Project", "Import..." to browse and import some assets from a ".bit", ".txt", "*.zip" archive. This operation doesn't overwrite conflictions in your editing project.
Click "Project", "Export..." to select and export some assets to a ".bit", ".txt", "*.zip" archive.
Click "Project", "Build", then "Windows"/"MacOS"/"Linux" to make an executable for Windows/MacOS/Linux respectively with the current opened project.
It might require execution permission to launch an exported desktop binary, to apply that permission:
- For MacOS "xattr -cr bitty_stage.app", then "chmod 777 bitty_stage.app/Contents/MacOS/bitty_stage"
- For Linux "chmod 777 x64/bitty"
Click "Project", "Build", then "HTML" to make an executable for browser with the current opened project. It requires a WebAssembly capable browser.
You can upload it to cloud or host it on your own server for others to play.