Using Scaleform
Scaleform GFx is the native GUI for GTA V, based on Flash technology using ActionScript 2, which is a superset of ECMAScript (JavaScript) - read more on Wikipedia.
Development environment
In order to develop custom .gfx assets (optimized SWF) you need to have Adobe Flash Pro CS6, use ActionScript 2 (version 3 has a different virtual machine which is not supported by the version GFx GTA uses) and target Flash Player 8.0.
To convert a .swf file produced by Adobe Flash into .gfx, you need the gfxexport.exe
tool from the Scaleform GFx SDK (version 4.0 is fine).
Limitations
Scaleform doesn’t implement some features from Flash:
- No filters for shapes. At all.
- No blur filter for text either. Can be faked with a glow filter.
- No masking. Will be discussed later on this page.
- No embedded raster graphics. Will be discussed later on this page.
Interfacing
You can interface with scaleforms by performing native calls from the GRAPHICS namespace with scaleform
in their name.
TIMELINE
variable in the global scope.
This variable serves as a kind of public API of the .gfx.
Boilerplate
It’d be pretty time consuming to explain in details how to bootstrap your first gfx thing, so instead please use the boilerplate:
Related files:
boilerplate.zip
Loading
- Use REQUEST_SCALEFORM_MOVIE with the name of the desired gfx (without file extension), for example
mp_car_stats
. - Use HAS_SCALEFORM_MOVIE_LOADED in a loop, to prevent using a non-loaded Scaleform asset.
Invoking functions in GFx
Please note that this is a low-level api, the C# runtime has an easy-to-use high-level abstraction; and even if you don’t know C# you can use it as a reference usage of function calling natives.
> Call BEGIN_SCALEFORM_MOVIE_METHOD to initialize the function call, pass it the handle
of the GFx, and a function name string, which should be a member of the global TIMELINE variable in ActionScript.
> Define arguments, using one of the following functions depending on what type of argument you want to pass:
- SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT
- SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT
- SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL
- _PUSH_SCALEFORM_MOVIE_METHOD_PARAMETER_STRING (only use for short strings like texture names)
- A pair of BEGIN_TEXT_COMMAND_SCALEFORM_STRING, ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME, and END_TEXT_COMMAND_SCALEFORM_STRING for normal strings
> Call END_SCALEFORM_MOVIE_METHOD to finish function call.
Drawing
You can draw scaleform using one of these commands, red, green, blue, alpha and unk parameters can be omitted as they don’t affect anything:
- DRAW_SCALEFORM_MOVIE for drawing gfx in 2D on a specific position
- DRAW_SCALEFORM_MOVIE_FULLSCREEN also draws gfx in 2D, however in fullscreen
- DRAW_SCALEFORM_MOVIE_3D do note that if you have blackout enabled this will be drawn with “solarized” and shifted to yellow colours.
Masking
Can be faked using the function DRAW_SCALEFORM_MOVIE_FULLSCREEN_MASKED, where the first gfx is what you want to render, and the second gfx is a mask for it.
This masking has no antialiasing, it doesn’t perform “smooth” masking, if a particular pixel of masking gfx is not fully transparent, then the underlying pixel will be fully shown.
Using textures
In normal Flash you can simply load an image into MovieClip (see MovieClipLoader class in AS2 docs) using its (http[s]) url, however in-game you need the img
protocol.
Example of correct image url: img://mpcarhud/albany
, where mpcarhud
is the name of a texture dictionary and albany
is the texture name in said TXD.
Useful links
Extra Information
Some scaleforms also allow the use of certain html elements, such as <b>
and <br>
. You can also set certain fonts for some using <FONT FACE='$[fontName]'>
for example, <FONT FACE='$Font2'>
. Here’s a list of usable fonts (Not all work for every scaleform):
$Font2
$Font2_cond
$Font2_cond_NOT_GAMERNAME
$Font5
$Machine
$Stencil
$Lubalin
$Bookman
$Stenberg
$Mistral
$HelveticaBLK
$HelveticaBLKI
$Times
$TradeGothic
$AnnaSC
$EngraversOldEnglish
$Bauhaus
$Redemption
Image and size can also be set, with size being <FONT SIZE='[fontSize]'>
and image being <img src='img://txd/tn'>
Example
Citizen.CreateThread(function()
local scaleformHandle = RequestScaleformMovie("mp_big_message_freemode") -- The scaleform you want to use
while not HasScaleformMovieLoaded(scaleformHandle) do -- Ensure the scaleform is actually loaded before using
Citizen.Wait(0)
end
BeginScaleformMovieMethod(scaleformHandle, "SHOW_SHARD_WASTED_MP_MESSAGE") -- The function you want to call from the AS file
PushScaleformMovieMethodParameterString("Big Text") -- bigTxt
PushScaleformMovieMethodParameterString("Smaller Text") -- msgText
PushScaleformMovieMethodParameterInt(5) -- colId
EndScaleformMovieMethod() -- Finish off the scaleform, it returns no data, so doesn't need "EndScaleformMovieMethodReturn"
while true do -- Draw the scaleform every frame
Citizen.Wait(0)
DrawScaleformMovieFullscreen(scaleformHandle, 255, 255, 255, 255) -- Draw the scaleform fullscreen
end
end)