Skip to main content



  • Layer - Layer of the scene. Layers parametrization can be found here: config.json.
  • Drawing area - Effect drawing framebuffer (usual aspect ratio: 3x4 or 9x16).
  • Visible area - Final frame framebuffer. The size is the same or less than drawing area. Equals to the screen size in pixels. Visible and drawing area centers are considered to be the same.

Information getters#

MethodDescriptionReturn typeExample values
Api.getFRXVersion()FRX versioninteger2, 3, 31
Api.getPlatform()Platform namestring"ios", "android"
Api.drawingAreaWidth()Drawing area widthinteger920
Api.drawingAreaHeight()Drawing area heightinteger1280
Api.visibleAreaWidth()Visible area widthinteger1080
Api.visibleAreaHeight()Visible area heightinteger1920
Api.getNamedState(name)Gets named stateanyfalse
Api.modelview()Transposed modelView matrix for each facearray object[[1.33,1.09,...0.89],..]
Api.projection()Transposed projection matrix for each facearray object[[1.33,1.09,...0.89],..]
Api.getRotationVector()Device orientation quaternionarray object[0.8, 0.5, 0.3, -0.1]


Boolean getter names:

  • smile,
  • mouth_open,
  • brows_up,
  • brows_down,
  • has_glasses,
  • eyes_state.

The name of the parametre should be passed as "string" type. For example, Api.getNamedState("smile") returns true if the smile is detected, otherwise - returns false. Api.getNamedState("eyes_state") returns array obj consists of 2 boolean values, the 1st for left and the 2nd for the right eye opening state.


Sound files configured in Sounds section in config.json. Sounds are identified by their names.

Current methods don't affect sounds in video files.

Api.playSound(fileName, isLooped, speedFactor)Play sound fileName.
Api.playSoundRange(fileName, startTime, stopTime, isLooped, speedFactor)Play sound fileName in range from startTime to stopTime.
Api.stopSound(fileName)Stop sound.
Api.pauseSound(fileName)Pause sound.
Api.setSoundVolume(fileName, volume)Set volume of sound fileName. Volume value should be from 0 to 1.


Video and GIF files configured in Media section in config.json. It's identified by layer names. Only one video/GIF can be attached to one layer.

Api.setVideoFile(layerId, fileName)Attach given video/GIF file to specified layer. Existing video/GIF is replaced.
Api.playVideoRange(layerId, startTime, stopTime, isLooped, speedFactor)Play video/GIF range. Doesn't restart currently played media. Times in seconds.
Api.pauseVideo(layerId)Pause the video/GIF. Next playVideo resumes from last position.
Api.stopVideo(layerId)Stop the video/GIF. Next playVideo start from the very beginning.


Api.setRecognizerFeatures(features)Set recognizer features to be enabled. Available values: "background", "hair", "skin_segmentation", "occlusion", "lips_segmentation", "eyes_segmentation", "lips_shine", "face_acne", "eye_bags", "hair_strand", "glasses", "eyes_correction", "lips_correction"


Api.setRecognizerFeatures(["background", "hair"]);
Api.setRecognizerFeatures([]); // All features disabled


There are 2 methods:

Api.meshfxMsg(command, instanceId, index, stringParam)Send message to meshfx
Api.meshfxReset()Reset effect to initial state
Api.isMirrored()true if mirrored rendering was requested


Instantiates 3d mesh for specific instanceId by file name.

Mesh creating with for the 3rd instanceId loaded from SnakeAnimation03.bsm2:

Api.meshfxMsg("spawn", 3, 0, "SnakeAnimation03.bsm2");

!glfx_FACE can be used instead of file name. It is face mesh from FRX.


Deletes 3d mesh with specified instanceId

Api.meshfxMsg("del", 3);


Sets the file as a texture with index for specified instanceId.

Random selection from 2 variants:

Api.meshfxMsg("tex", 3, 0, Math.random() < 0.5 ? "diffuse1.png" : "diffuse2.png");

In most cases textures are set in materials. This method can be used to change textures during animation playback for example. Index of texture to be changed should match the shader selectable texture index had been set in cfg.toml Samplers param of the required material.(For particular example tex_diffuse = 0 could be used)

animOnce, animOnceRev, animLoop#

This set of methods can be used to control animations queue.

Play "Start" animation once:

Api.meshfxMsg("animOnce", 3, 0, "Start");

Then play "attack" animation once in reverted way:

Api.meshfxMsg("animOnceRev", 3, 1, "attack");

Then play "Idle" in a loop:

Api.meshfxMsg("animLoop", 3, 2, "Idle");
  • animOnce plays animation once and switches to the next one.
  • animOnceRev plays animation in a reverted way.
  • animLoop plays animation in a loop without switching to the next one.

Commands with index = 0 replace active animation. index >= 1 replace animations in queue. Maximum queue size is 4.


Sets inverted bone weight. Because of invertion, the maximum weight is 0, and the minimal is 100.

Api.meshfxMsg("dynImass", 0, 0, "bone1"); // ( "dynImass", mesh id, weight, bone name)


Creates imitation of Gravity power for particular mesh id.

Api.meshfxMsg("dynGravity", 0, 0, "0 -1000 0"); // ("dynGravity", mesh id, 0, "x y z")


Creates collider sphere. It helps to add a limitation to bones movements. For example, you can use it if you need to prevent skinned hair from colliding with the face.

Api.meshfxMsg("dynSphere", 0, 0, "0 0 0 100"); // ("dynGravity", mesh id, 0, "x y z radius"), where xyz is coordinates of Sphere's center


Sets mesh friction. A higher value causes a lower effect. In most cases the range is from 95 to 100.

Api.meshfxMsg("dynDamping", 0, 95); // ("dynDamping", mesh id, coefficient)


Binds 2 bones.

Api.meshfxMsg("dynConstraint", 0, 100, "bone_3 bone_5"); // ("dynConstraint", mesh id, binding length, "bone1 bone2")


Allows setting vec4 variable in shader. Additional variable must exist in shader glfx_GLOBAL.

Api.meshfxMsg("shaderVec4", 0, 0, "0.5 1.0 123.0 4.56"); // (0 - always 0, 0 - shader variable id, "" - variables string. Maximum 4)

Shader variables declaration example:

// The first four are default
mat4 glfx_MVP;
mat4 glfx_PROJ;
mat4 glfx_MV;
vec4 glfx_QUAT;
// Next added, id 0
vec4 js_morph_params;
// id 1 and so on


Use added mesh for morphing. Several meshes with different weight can be used - resulting morphing is a mix of all the meshes with their weights. Mesh weight should be set to 0 to exclude it.

Api.meshfxMsg("warp", 0, 100); // (0 - morph object id in the scene, 100 - weight percentage)

Usually, mesh for morphing is set in cfg.toml as warp_mesh parametre value. To apply/edit morphing from JavaScript in runtime warp_mesh value should be set to "!script".


Api.recordStart(maximumDuration)Starts video record. maximumDuration is a maximum record duration time. 0 - infinity, system maximum.
Api.recordStop()Stops video record.


Api.showHint(hint_message)Show user hint.
Api.hideHint()Hide user hint.
Api.print(message)Log message.

Example effect: fx_Snake_b1 (FaceDefault.FBX).


Platform definition#

Api.haptic_is_ios_api_available()Returns true if iOS API is available on device.
Api.haptic_is_android_api_available()Returns true if Android is API available on device.

Common API (always available)#

Api.haptic_vibrate()Trigger default vibration on all supported devices.

iOS API: Taptic Engine (iPhone 6S, 6S Plus)#

Will trigger default taptic feedback on iPhone 7 and above.

Api.haptic_peak()Trigger Peak taptic effect.
Api.haptic_pop()Trigger Pop taptic effect.
Api.haptic_canceled()Trigger Canceled taptic effect.
Api.haptic_try_again()Trigger Try again taptic effect.
Api.haptic_failed()Trigger Failed taptic effect.

iOS API: Haptic Feedback (iPhone 7, 7 Plus, and above)#

Api.haptic_success()Trigger success taptic effect.
Api.haptic_warning()Trigger warning taptic effect.
Api.haptic_error()Trigger error taptic effect.
Api.haptic_light()Trigger light taptic effect.
Api.haptic_medium()Trigger medium taptic effect.
Api.haptic_heavy()Trigger heavy taptic effect.
Api.haptic_selection()Trigger selection taptic effect.

Android API#

Api.haptic_vibrate_with_params(duration_ms, amplitude)Arguments:
Duration in ms (e.g. 1500);
Amplitude from 1 to 255 (-1 is default, 0 means that vibration is disabled).
Last updated on