PICO-8 Wiki
Advertisement
stat( n )
Returns information about the current runtime environment.
n
The ID of the information to return. (See below.)

The stat() function returns information about the current runtime environment. Each kind of information has an ID (a number), described below.

You can display this metric on the game screen with print(), write it to the console with printh(), or perhaps use it some other way to adjust the behavior of your program.

{0…2} Memory and CPU usage

stat(0) returns the memory usage:

  • This number is in KiB. 1 would represent 1024 bytes allocated. The fractional portion is accurate, so 1.875 would represent 1920 bytes.
  • Accounts for all Lua data, such as variables and tables.
  • Ranges from 0 to 2048. (As of 0.1.11g, Lua is allowed up to 2 MiB of data.)
  • Does not include peek()/poke()-able RAM such as sprite or video RAM.
  • Does not include cartridge ROM.

stat(1) returns the total CPU usage:

  • Begins at 0 at the start of the first _update() after the most recent _draw().
  • Progresses towards 1 as it nears time for the next frame to begin. Therefore, 1 would represent 1/30s elapsed when using _update(), or 1/60s for _update60().
  • A value higher than 1 indicates that the program has gone over its processing budget for code and drawing this frame. Frames may be dropped to compensate, or overall execution may be slowed.

stat(2) returns the system CPU usage:

  • This number uses the same range and behavior as stat(1).
  • This number only increases while work is being done in unseen code. For instance, clearing the screen about 70 times would push stat(2) past 1.0. Almost all of the work would be done inside of calls to cls(), which is a system call. However, spending the whole frame calculating pi wouldn't budge stat(2), because it wouldn't involve any system calls.

{3} Unknown

stat(3) returns a number, 0 at the time of writing, whose purpose is unknown.

{4} Clipboard contents

The system clipboard contents can be found in stat(4), as a string.

See Clipboard for full details on usage and limitations.

{5} PICO-8 version

The running PICO-8 version ID can be found in stat(5), as a number.

This is the same number as the "version" ID in the p8 file. (e.g. 16 for 0.1.11g)

{6} Parameter string from a third-party load

When a cart calls load() to load another cart, it can provide an arbitrary string as the third argument. This string is accessible to the loaded cart by calling stat(6). If PICO-8 is run from the command line, the -p flag can be used to provide this argument instead.

If the load() call also included a breadcrumb string, the loaded cart can access this with stat(100).

{7} Frame rate

stat(7) returns the current frame rate, as the number of frames rendered per second.

Specifically, the frame rate is the number of times per second PICO-8 is able to call the game's _draw() function in the game loop (if provided), or the number of times the game calls flip(). When using the game loop, the expected frame rate is 30 frames per second (fps) with an _update() function or 60 fps with an _update60() function, but may be fewer if the draw or update functions take too long and PICO-8 skips _draw() calls to catch up. This makes frame rate an interesting measure of game performance for games that do a lot of calculation between frames.

{8} Target frame rate

stat(8) returns the intended frame rate of the system, currently either 30 or 60. See _update() for more details on how to choose one or the other.

{9} PICO-8 frame rate

stat(9) appears to return the number of times the PICO-8 application itself has updated in the last second. This will tend to be similar to the refresh rate of the physical display, but may vary with system load. It is independent of the current game's update rate. If you configure PICO-8 to show an FPS indicator, this is the value being shown.

{10…11} Unknown

stat(10…11) returns a number, 0 at the time of writing, whose purpose is unknown.

{12…15} Pause menu location

stat(12) through stat(15) represents the coordinate position of the pause menu if the player were to pause the game at that moment, as the x and y coordinates of the upper left corner and bottom right corner, respectively.

Various things determine the contents of the pause menu dynamically, including menuitem() calls, load() parameters, whether the game was loaded with Splore, and possible future extensions. PICO-8 calculates the size and position of the menu based on its contents.

{16…26} Sound and music status

stat(16) through stat(19) return the index of the sound effect currently playing on the four channels, respectively. If no sound is playing on the channel, stat() returns -1.

stat(20) through stat(23) return the note number (0 through 31) of the sound effect currently playing on the four channels, respectively. If no sound is playing on the channel, stat() returns -1.

From zep: "Note that the row number may not be very precise depending on what is going on with the host operating system's audio mixer. Also in the case of the web player which needs to have a large mixing buffer, the result is often slightly earlier that what is audible."

stat(24) is the music pattern ID currently being played, as a result of the most recent call to music().

Caution: There is a bug in PICO-8 versions prior to 0.1.12: If no music is currently playing, an ID of 0 will be returned instead of -1, but this does not mean music pattern 0 is actively playing. In affected versions, workarounds like checking stat(25) are necessary to detect whether music is actually playing.

stat(25) is the number of music patterns played since the most recent call to music().

stat(26) is the number of ticks (notes or rests) played on the current pattern.

{27…29} Unknown

stat(27…29) returns a number, 0 at the time of writing, whose purpose is unknown.

{30…36} Mouse and keyboard in "devkit mode"

From inside a cart, "devkit mode" can be enabled for platforms that have mouse and keyboard attached:

poke(0x5f2d, 1)

Once enabled, stat(...) can be used to read mouse and keyboard values:

  • stat(30) -> true if a keypress is in stat(31), false otherwise
  • stat(31) -> the key being pressed, as a string
  • stat(32) -> mouse X coord
  • stat(33) -> mouse Y coord
  • stat(34) -> mouse button bitmask (1=primary, 2=secondary, 4=middle)
  • stat(35) -> (unknown, returns 0 in testing)
  • stat(36) -> mouse wheel delta since previous update

When the user presses one or more keys, PICO-8 sets stat(30) to true, and then sets stat(31) to the next keypress to be read. When the application sees stat(30) is true and reads the keypress via stat(31), PICO-8 will then refresh the value of both stats, based on whether or not there are more keypresses remaining to be reported. This can be checked multiple times per frame to fully read all keys pressed since last frame.

An example of reading the keyboard:

function _update()
  while stat(30) do
    handle_keypress(stat(31))
  end
end

Some special keys can be detected using these standard Lua escape sequences:

Key Sequence Notes
Backspace "\b"
Enter "\r" By default, Enter and P bring up the pause menu. If either is detected, poke(0x5f30,1) can be used to temporarily suppress this action.
Esc "\27" or "\x1b" Only seen when the user is exiting the pause menu or halting execution. Neither action can be suppressed.
Tab "\t"

Modifier keys:

The Shift key is not reported separately. Instead, it changes the character that is returned from stat(31). For instance, if the player presses Shift+H, a double-wide heart character will be returned. Other modifier keys are invisible to PICO-8 programs.

Usage notes:

Conceptually, PICO-8 is a small game console, similar to an NES or GameBoy. It may be running on a machine without a keyboard or mouse connected, such as a game cabinet with only game controllers, or even a small system-on-a-chip implementation with integrated controls. For that reason, this is referred to as "devkit mode", intended for debugging and tools. It's not forbidden to write games that use this mode, but games that do may find a limited audience.

If PICO-8 is running in a context where mouse and keyboard cannot be safely relied on (for instance, on the BBS), it will display a notice that devkit mode has been enabled. This is so the user will not be confused if they cannot control the game. This notice will come up the first time a relevant stat() is read; this knowledge can be used to make sure the notice will not obscure something important at a bad time.

{80…85,90…95} Time of day

A PICO-8 cart can access the current time of day, in the host system's local time zone:

  • stat(90) -> year, e.g. 2018
  • stat(91) -> month of year, 1-12
  • stat(92) -> day of month, 1-31
  • stat(93) -> hour of day, 0-23
  • stat(94) -> minute of hour, 0-59
  • stat(95) -> second, 0-61 (usually 0-59, see note below)

A corresponding set of values, but in UTC time, are available at stat(80) through stat(85).

Note: PICO-8 and/or Lua appear to be using the standard C tm_time interface to provide these values, and as such, you should be aware that the current second is allowed to go past 59, to 60 or 61, in the event of leap seconds occurring.

{100…104} BBS information

The following are not officially documented and mostly unknown, but all appear to be related to BBS functionality:

  • stat(100) -> Returns breadcrumb label.
  • stat(101) -> For BBS carts, stat(101) returns the current BBS ID. (per zep on Twitter)
  • stat(102) -> For BBS carts, returns site (e.g. "www.lexaloffle.com"). For local carts, returns 0.
  • stat(103) -> Unknown, returns 0 in limited testing.
  • stat(104) -> Unknown, returns false in limited testing.

(If you know more details about any of these, please update this section.)

Examples

function _update()
  -- game update code...
end

function _draw()
  cls()

  -- game draw code...

  print('mem:'..stat(0), 0, 0, 7)
  print('cpu:'..stat(1), 0, 6, 7)
end

See also

Advertisement