The draw namespace contains functions for drawing text, shapes and images over the frame. Drawing is done from a handler of the draw event, which runs once a frame in every app state; whatever the handler draws is painted over that frame after the game's own HUD. The event is only raised while a mod has a handler for it, so an idle overlay costs nothing.

Static members#

These elements are static to the class itself and can be accessed like so:

ss.draw.text("Hello", 20, 20, { size = 28 })

Static functions#

Positions are in pixels from the top-left corner of the back buffer. The opts table of each function is optional, as is every key in it; the keys are listed under Draw options.

FunctionReturn ValuesDescription
ss.draw.text( string text, number x, number y, [table opts] ) nil Draws text at the given position. By default x is the left edge of the text; the align option changes which edge it is.
ss.draw.rect( number x, number y, number width, number height, [table opts] ) nil Draws a box with its top-left corner at the given position. Filled by default; the filled option draws an outline instead.
ss.draw.line( number x1, number y1, number x2, number y2, [table opts] ) nil Draws a line between the two given points.
ss.draw.image( string path, number x, number y, [table opts] ) nil Draws an image file of the mod with its top-left corner at the given position. The path is relative to the mod's folder, or absolute. PNG, DDS, BMP, JPG and TGA files are supported. The image is loaded once per path and kept across a device reset.
ss.draw.image_size(string path) number width, number height Returns the pixel size of an image file of the mod. Returns 0, 0 when the file cannot be loaded.
ss.draw.measure( string text, [number size] ) number width, number height Returns the width and height the text would take at the given font size (20 by default), in pixels.

Static fields#

TypeFieldRead-only?Description
integer ss.draw.width Yes The width of the back buffer in pixels. 0 before the first frame.
integer ss.draw.height Yes The height of the back buffer in pixels. 0 before the first frame.

Draw options#

The keys of each function's opts table and their defaults.

ss.draw.text
TypeFieldDescription
number size The font size in pixels. Defaults to 20.
string align Which edge of the text x is: left, center or right. Defaults to left.
boolean shadow Whether to draw a drop shadow under the text. Defaults to true.
color color The colour of the text. Defaults to white.
ss.draw.rect
TypeFieldDescription
boolean filled Whether to fill the box (true) or draw an outline (false). Defaults to true.
color color The colour of the box. Defaults to white.
ss.draw.line
TypeFieldDescription
number width The thickness of the line in pixels. Defaults to 1.
color color The colour of the line. Defaults to white.
ss.draw.image
TypeFieldDescription
number width The width to draw the image at, in pixels. Defaults to the file's own width.
number height The height to draw the image at, in pixels. Defaults to the file's own height.
table uv The part of the image to show, as { u0, v0, u1, v1 } in the range 0 to 1. Defaults to the whole image.
color color A tint applied to the image. Its alpha is the image's opacity. Defaults to white, fully opaque.

Colours#

A colour is a table { r, g, b[, a] } with each component in the range 0 to 255, or a number of the form 0xRRGGBB. A colour left out is white, and an alpha left out is fully opaque. The alpha of an image's tint is the image's opacity.

Limits#

Up to 256 items can be drawn per frame. A draw call outside the draw handler results in an error. Text is rendered through D3DX fonts, one cached per size (Segoe UI, bold); boxes and lines are two triangles each, with the game's render state restored after them. Images are loaded once per path and kept across a device reset, so a window resize does not reload them.

The handler runs on the game loop and the painting happens in the frame's EndScene, so a value read in the handler is at most one frame old on screen.

Example#

-- A speed readout, the position in the field and a progress bar along the bottom of the screen.
ss.on("draw", function(ev)
	local me = ss.vehicle
	if not me then return end
	ss.draw.rect(20, ev.height - 90, 260, 70, { color = { 0, 0, 0, 160 } })
	ss.draw.text(string.format("%.0f km/h", me.speed_kmh), 30, ev.height - 84, { size = 28 })
	ss.draw.text("P" .. tostring(me.race.position), 270, ev.height - 84, { size = 28, align = "right", color = 0xFFC000 })
	ss.draw.line(20, ev.height - 20, 20 + 260 * me.race.progress, ev.height - 20, { width = 4, color = { 80, 200, 255 } })
end)