III

Introduction

This is the official documentation for Awesome_E's modded player actions.

Requirements

block1 The first parameter of the comment block (shown above) contains all of the webplayer command text (shown below).


The code below shows the basic structure of a webplayer command:

_ae_webplayer_action: { "name": "isComputer" }

In order to be recognized by the webplayer, there are a few requirements:

  1. You must acquire secret blocks. Otherwise, you will not have access to the "comment" block that is required to perform any webplayer actions.
  2. You must be using the comment block, or if inside a conditional, the "»" block.
  3. Both the "comment" block and the "»" block have the ID 22. No other blocks will be recognized by the modded webplayer.
  4. Every webplayer command must begin with _ae_webplayer_action:, then have all of its JSON data after it.
  5. Your entire command string is put into the first parameter of the comment block.

Every command has two traits at the root level:

  1. Name: This is the name of the command
  2. Args: These are arguments that describe the behavior of that command. If the command does not require any arguments, you may omit (remove) this trait.

*Note: In this documentation, arguments for commands may appear as "args" (referring to the entire list [arg0, arg1, arg2, ...]) or as "arg0","arg1", etc. (individual arguments).

Any additional traits are ignored.

Additional Data

block2 Any additional data is passed through the second parameter of the comment block (shown above). It replaces any location where the string "_data" (with quotes) shows up.

Usage:

_ae_webplayer_action: { "name": "checkKey", "args": ["_data"] }

This is NOT required. If you are new to using webplayer actions, I recommend skipping this section until you need to pass variable data into your webplayer action.

Examples:

  1. "args":["_data"] with parameter data LAST_TOUCH_X will be replaced with the output "args":[512]
  2. "args":["_data"] with parameter data USERNAME will be replaced with the output "args":[Awesome_E] and will throw a parsing error because Awesome_E is not a defined variable in the player's JS file
  3. "args":[""_data""] with parameter data USERNAME will be replaced with the output"args":["Awesome_E"] and will run successfully

Constants

These actions will return the same value every time and are useful for identifying basic information about the user's device to enhance their experience with the project.

Is Web Explorer

block3 Because you want to use the data that the webplayer action returns, you should use the "»" block, as that will convert the output into something Hopscotch can read. If you are in the modded player, the variable gets set to 1; otherwise it gets set to 0.

_ae_webplayer_action: { "name": "isWebExp" }

This action returns true every time, allowing for a quick and easy method to detect whether a user is in my modded player. In my modded player, it simply returns 1.

You can use this action to determine whether other modded features will work in the current player.

nameargsoutput
isWebExp<This command has no arguments>1

Is Computer

block4 This will set the variable "On Computer" to 1 or 0, depending on whether the user is on a computer. If run from the Hopscotch App, the blank string returned from the "»" block is still not equal to 1, so it gets set to 0.

_ae_webplayer_action: { "name": "isComputer" }

This action returns 1 if the user is on a computer and 0 if they are not.

One use case of this is removing touch controls for a platformer for computer players in order to free up screen space, then adding keyboard support to better the user experience (UX).

nameargsoutput
isComputer<This command has no arguments>0 or 1

User Time Zone

block5 This Hopscotch code will set the variable "Time Zone" to the device's time zone.

_ae_webplayer_action: { "name": "user-tz" }

This action returns the user's time zone, rounded to the nearest hour offset from UTC/GMT time. For example, EDT returns -4 because it is 4 hours behind UTC/GMT.

While the recent addition of user variables allows you to do this by checking the hour and the Unix Timestamp, this option is available for non-subscribers as well as older player versions.

nameargsoutput
user-tz<This command has no arguments>integer, -12 to 12

Dark Mode Enabled

block8 This Hopscotch code will set the variable "Dark Mode" to 1 if the user is in dark mode in the modded player when the action is run.

Usage:

_ae_webplayer_action: { "name": "user-darkmode" }

This actions returns 1 if the user is in dark mode, and 0 if the user is not.

This is useful in projects that default to a light-theme because it would allow the default to be set to dark mode if the user prefers dark mode, and it would also allow the user to switch the project theme by toggling their system setting.

nameargsoutput
user-darkmode<This command has no arguments>0 or 1

JavaScript Debug

While unconventional for drag-n-drop programming, logging data, alerting it, or freezing the project for an input can be extremely useful for debugging a project (especially because you aren't editing it in the Hopscotch app when you run it in my player).

The following actions perform standard JavaScript methods to help with just that.

Console Log

block1

This will log hello,123 to the browser console:

_ae_webplayer_action: { "name": "js-console-log", "args": [ "hello", 123 ] }

As the name implies, this simply logs a message to the browser console.

nameargsoutput
js-console-logItems to log in the browser console. Array entries are joined with commas.<nothing>

Alert

block6

This will alert the current object's X Position to the user:

_ae_webplayer_action: { "name": "js-alert", "args": ["_data"] }

This behaves exactly like js-console-log, but it alerts the arguments in a popup dialog instead of logging them to the browser console.

This is more useful for testing projects from iOS, since you need a Mac to access the browser's console (which is not accessible to everyone) whereas a popup dialog will show up on the iOS device itself.

nameargsoutput
js-alertItems to display in the popup. Entries are joined with commas.<nothing>

Prompt

block7

This will freeze the project to ask for the user's favorite fruit (prefilled with "Apple"), then save that user input to the variable "Preference"

_ae_webplayer_action: { "name": "js-prompt", "args": ["Enter your preferred fruit:", "Apple"] }

Stops the project to ask for a user input, which is returned as output.

This is useful in cases where you don't want other objects to continue executing code while the user is inputting text. For example, if you want to space objects apart when game starts, you wouldn't want any objects to set position before the user inputs the global value.

namearg0arg1output
js-promptThe prompt message [string]Default (prefilled) value [string]<nothing>

User Interface

These actions interact with the user interface in the player.

Restart Project

block1

This code restarts the project:

_ae_webplayer_action: { "name": "restart" }

As the name indicates, this action will restart the project. It runs the click action for the restart button, giving the project a full restart.

This may be useful for an "instant retry" mechanism in a speedrun project in a place where the player cannot progress.

nameargsoutput
restart<This command has no arguments><nothing>

Achievement

block1

This is the current syntax of the achievement command:

_ae_webplayer_action: { "name": "achievement", "args": [ "<img src=\"https://i.imgur.com/S3Q882k.png\" width=\"48\"/><div><span class=\"achievement-name\">Starbound</span><span class=\"achievement-description\">Collect 10 stars</span></span></div><i class=\"fa fa-close\" onclick=\"banner(false)\"></i>" ] }

The achievement action creates a dropdown from the upper-righthand corner, alerting the user that they unlocked a rare achievemnt in your game.

Current Syntax (supports custom HTML):

namearg0output
achievementHTML to display inside of the achievement banner <string><nothing>

The following syntax can also be used:

_ae_webplayer_action: { "name": "achievement", "args": [ "Starbound", "Collect 10 stars", "https://i.imgur.com/S3Q882k.png" ] }

The new syntax aims to simplify the creation of an achievement. It does get rid of custom HTML support, but it is supported alongside the original syntax.

Revised Syntax:

namearg0arg1arg2output
achievementName <string>Description <string>Image URL [string]<nothing>

Checking Hardware

Check One Key in a List

block9

The following code will return whether the right arrow or the letter "D" is pressed:

_ae_webplayer_action: { "name": "checkKey", "args": [39,68] }

This action will return 1 if ANY of the keys in the arguments are currently being pressed.

nameargsoutput
checkKeyEvery keycode to check for, in a comma-separated list0 or 1

Advanced: If you want to have the keys being checked to be controlled by variables, use the "»" block with a data parameter, then pass in "_data" into the arguments list.

Check All Keys in a List

block9

The following code will check if the shift key AND the letter "H" are prressed:

_ae_webplayer_action: { "name": "checkKeyAll", "args": [16,72] }

This action, like checkKey, will check if certain keys are pressed. However, it will only return 1 if ALL KEYS on the list are being pressed.

nameargsoutput
checkKeyAllEvery keycode to check for, separated by commas0 or 1

Advanced: If you want to have the keys being checked to be controlled by variables, use the "»" block with a data parameter, then pass in "_data" into the arguments list.

Check Controller Buttons

block9

This conditional will be run if the or Y button is pressed:

_ae_webplayer_action: { "name": "checkControllerButton", "args": [0,0,2] }

The code below will check if both the left and right bumper buttons are pressed.
LB + RB (XBOX) / L1 + R1 (PS)

_ae_webplayer_action: { "name": "checkControllerButton", "args": [ 0, 2, [4,5] ] }

This code will check if either the left or right joysticks are pressed on the 2nd connected controller (index 1):

_ae_webplayer_action: { "name": "checkControllerButton", "args": [ 1, 2, [10,11] ] }

Both pressed → 1, either → 1, none → 0

block18

This will set the variable P1 Left Trigger to the left trigger's X value on the first controller (controller 0):

_ae_webplayer_action: { "name": "checkControllerButton", "args": [0,0,6] }

The value stored can range from anywhere between 0 (not pressed) and 1 (fully pressed), inclusive. If checking if a button press is equal to 1, triggers will need to be fully pressed. Otherwise, check above a certain threshold or if the button press is not 0.

This action checks the press state of buttons on a controller. It can:

  1. Check the press state of any one button
  2. Check if any buttons in a given array are pressed
  3. Check if all buttons in a given array are pressed
namearg0arg1arg2output
checkControllerButtonsController IDModeButton IDnumber

Controller ID

This is the index of the controller, as determined by the browser. The first controller connected will have and ID of 0, the second controller 1, and so on.

Mode

You can check controller buttons using the following modes:

  1. Checks the value of the specified controller button. This will return a floating point number between 0 and 1, inclusive.
    NOTE: Most buttons will either return 0 or 1, but some buttons, such as triggers, can return decimals.
  2. Checks if any of the specified button IDs are pressed. Returns 1 if any button is pressed, otherwise returns 0
  3. Checks if all of the specified button IDs are pressed. Returns 1 if every button is pressed, otherwise returns 0

Button ID

Every button on the controller is mapped to an ID. You can test your gamepad inputs using this website or refer to the following controller mappings:

controller1

Original XBOX Controller Image

controller2

Original PlayStation Controller Image

Advanced: If you want to have the buttons being checked to be controlled by variables, use the "»" block with a data parameter, then pass in "_data" into the arguments list.

Check Controller Axes

block19

The following command will set Left Joystick Y to the vertical (Y) value of the left joystick on the first connected controller:

_ae_webplayer_action: { "name": "checkControllerAxis", "args": [0,1] }

block20

This command will set P2 Right Stick X to the hoizontal (X) value of the right joystick on the second connected controller:

_ae_webplayer_action: { "name": "checkControllerAxis", "args": [1,2] }

This action returns the value of one of your controller's axes. Each joystick is separated into 2 axes, one for X direction (horizontal inputs) and one for Y direction (vertical inputs).

namearg0arg1output
checkControllerButtonsController IDAxis IDnumber

Controller ID

This is the index of the controller, as determined by the browser. The first controller connected will have and ID of 0, the second controller 1, and so on.

Axis ID

For most controllers, axes 0 and 1 are the X and Y values (respectively) of the left joystick, and axes 2 and 3 are the X and Y values (respectively) of the right joystick.

Output

A floating point number between -1 and 1, depending on the position of each joystick or axis.

Read the Last Scroll Point

Local Save Data

These actions allow you to work with data that gets stored locally in the user's web browser. This data will persist between plays and whenever the user closes the browser (unless in private browsing mode, in which case the data gets cleared by the browser). While Hopscotch offers an easier-to-use implementation called "User Variables", this feature is free, although it only works in my modded player.

Read from Save Data

block10

This code will set the variable "Level" to the local save called "Stage". If that doesn't exist, it will default to 1, as specified in the arguments:

_ae_webplayer_action: { "name": "newdata-read", "args": ["Stage",1] }

Reading from local savedata allows you to retrieve information previously stored locally in the user's browser. For example, you can load a stage/level so that a user can save their progress.

namearg0arg1output
savedata-readproperty <string>default <number/string>value <string>

property refers to the name of the local save, e.g. "Level"

default is the value returned if the local save does not exist.

value is the value saved under the specified property name.

Write to Save Data

block14

When put into the block shown above, this code will create a local save called "Stage", and it will have the value of the variable "Level":

_ae_webplayer_action: { "name": "newdata-write", "args": ["Stage","_data"] }

Writing to Save Data refers to either creating a new property or modifying an existing one. This action allows you to specify a property to update, as well as its new value.

If the property does not already exist, it will be created. Otherwise, it will be overwritten.

namearg0arg1output
savedata-writeproperty <string>value <number/string><nothing>

property refers to the name of the local save, e.g. "Level"

value is the new value to be stored under that local save.

Delete Save Data

block14

This will delete the locally stored "Stage":

_ae_webplayer_action: { "name": "newdata-delete", "args": ["Stage"] }

This action simply deletes any value that was stored under the specified property, which makes for a fast and simply reset mechanism in a game.

namearg0output
savedata-writeproperty <string><nothing>

URL Actions

These actions allow you to display approved webpages in frames or navigate to them. I am keeping a list of apprroved and rejected subdomains that determine whether the action will run or throw a popup error.

URL Popup

block1

The following code will create a popup of HS Tools:

_ae_webplayer_action: { "name": "url-iframe", "args": ["https://ae-hopscotch.github.io/hs-tools/"] }

The URL Popup action displays a given URL in an iframe on the current page, which will be put on top of the project being played.

namearg0output
url-iframeurl <string><nothing>

Go to URL

block1

The following code will redirect the user to HS Tools:

_ae_webplayer_action: { "name": "url-goto", "args": ["https://ae-hopscotch.github.io/hs-tools/"] }

This action will redirect the page to the URL passed in as input.

namearg0output
url-gotourl <string><nothing>

Hopscotch Data

With these actions, you can display any user information provided by Hopscotch's v2/users API, which currently only includes nickname, avatar type, and plants.

Load User Data

block1

The code below will load the user data for user 5947972

_ae_webplayer_action: { "name": "userdata-read", "args": ["5947972"] }

This block retrieves the user data of a specified User ID and stores it temporarily (until you leave or reload the page).

namearg0output
userdata-loaduser_id <integer><nothing>

You must load user data before reading it with the read user data command. Also, since it retrieves data from the internet, you will need some wait time between loading the data and reading traits. See the demo for a "wait until loaded" block (not a rainbow block/ability, just one block).

Read User Traits

block11

This code will set the variable "Nickname" to the nickname of user 5947972, which is Jeffery Jr.

_ae_webplayer_action: { "name": "userdata-read", "args": ["5947972","nickname"] }

This block allows you to read user traits of users that have already been loaded usingthe userdata-read command. If no trait is specified in the second argument, this action will return the entire dictionary (JSON object).

namearg0arg1output
userdata-readuser_id <integer>trait [string]string or integer; the trait's value

*Currently, you can specify trait as "nickname", "avatar_type", or "plants". You can also omit the trait.

Global Variables

Global Variables provide you access to realtime variables that can be read from any device in the modded player. These are tied to the user and not the project, meaning that the same variables are shared across all of your projects. You can access variables that you set in one project in the future from any project, as long as the creator's user ID is the same. If you want your variables to be project-specific, I recommend adding the project UUID before the variable name. (Example: 10iu14ay37-world_record)

However, these are not intended for multiplayer use, as there are dedicated blocks to better manage multiplayer than just using global variables.

Connect to the Server

block1 Run this exact command to connect to the global variables server:

_ae_webplayer_action: { "name": "globalvar-connect" }

This action will connect the project to the global variables server.

Run this command before reading or writing any global variables. I recommend running this block on game starts so you have access to global variables almost immediately.

(I don't automatically run this for every project because I don't want every project, most of which are not modded in any way, to connect automatically and use bandwidth.)

nameargsoutput
globalvar-connect<This command has no arguments><nothing>

Read Global Values

block12

This Hopscotch block (above) will set the project's "High Score" variable to the global variable called global_best, using the code below:

_ae_webplayer_action: { "name": "globalvar-read", "args": ["global_best"] }

Once you have connected to the global variables server, run this command along with a key (variable name) to read the data stored under it.

namearg0output
globalvar-readkey <string>any; the key's value

*Note: key simply refers to a string that the value is stored under. Essentially, it is just the variable name.

Write Global Values

block15

Using the command below, the Hopscotch block (shown above) will set the global variable called global_best to the current project's high score.

_ae_webplayer_action: { "name": "globalvar-write", "args": ["global_best","_data"] }

After connecting to the global variable server, running the globalvar-write block will override the specified key with the value you provide. More times than not, you will run this block inside of a conditional.

namearg0arg1output
globalvar-writekey <string>new value <any><nothing>

Multiplayer Actions

Multiplayer actions provide the foundation for the core aspects of multiplayer: creating, joining, and leaving rooms, in addition to reading and writing user-specific and global (limited to each room, of course) data.

To prevent code modification, multiplayer actions will not execute if the project is run from the Project Builder.

Start a Session

block1

Use this exact code in your game to start a session:

_ae_webplayer_action: { "name": "socket-create" }

This action starts a multiplayer session with a random join code consisting of only numbers and lowercase letters. For safety reasons, there is no configuration to change this join code.

nameargsoutput
socket-create<This command has no arguments><nothing>

Join a Session

block1

Use this code in your game to join a session, where abc123 is the join code. If you don't have it already, leave it blank to prompt the user to enter one.

_ae_webplayer_action: { "name": "socket-join", "args": ["abc123"] }

This action prompts the user to join a multiplayer room by entering/pasting in the 6-character join code generated by the host's device. Be aware that reading session data in the same rule may cause issues in the project, as joining a session requires a small amount of time.

If you have the user provide a join code through a Save Input block, you can pass it through to the socket-join command arguments to use that code to join a room.

namearg0output
socket-joincode [string]<nothing>

Leave the Session

block1

Run this exact code to leave the multiplayer room:

_ae_webplayer_action: { "name": "socket-leave" }

This command will disconnect you from the multiplayer room. If you are currently the host of this room, it will end the game for everyone.

nameargsoutput
socket-leave<This command has no arguments><nothing>

Get the User's ID

block17

This Hopscotch code will save the user's index to the project variable called "Player ID"

_ae_webplayer_action: { "name": "socket-playerdata", "args": ["get-index"] }

As the name implies, this command returns the user's index in the multiplayer room. The host is 0, and the player indices are in chronological order of time joined.

namearg0output
socket-playerdata"get-index"User ID <number>

If you are the first person to join a host's game, this command will return 1. If you are the second person to join, it will return 2. And so on...

Read Room Properties

block21

The code below will set the variable to the current room ID:

_ae_webplayer_action: { "name": "socket-room", "args": ["id"] }

This command lets you read several room properties. Using this command, you can read the following:

namearg0output
socket-roomproperty <string>string or integer; depends on property

Write Room Properties

block1

The code below will lock the multiplayer room and prevent new people from joining:

_ae_webplayer_action: { "name": "socket-room", "args": ["lock"] }

This command lets you write several room-level properties. In the first argument, pass in one of the following:

namearg0arg1output
socket-roomproperty <string>varies*<nothing>

*For set-limit, this takes in an integer between 1 and 64. For other commands, there is no input.

Read Session Data

block10 This command will set the user's game variable "Level" to the room's value for level. This can be useful when you are trying to sync a scene, room, or stage in your project.

_ae_webplayer_action: { "name": "socket-read", "args": [-2, "level"] }

block13 Assume the Clone Index is 3 (and the object renders the player with ID 3). Since "_data" resolves to 3, the above command will set self "Powerup" to player 3's power:

_ae_webplayer_action: { "name": "socket-read", "args": ["_data", "power"] }

This command reads the value at the path provided for any given user. You can read nested traits using the . operator (Example: if the host stores level data in an array, you can get the first item with level_data.0)

In the example shown, the second parameter of the "»" block refers to the Player's index, with 0 being the host and -1 being a shorthand for "self" (your actual index will be greater than or equal to zero)

namearg0arg1output
socket-readPlayer ID <integer>Property Path <string>Property Value <any>

Player ID

Players IDs are as follows:

Property Path

*If player_scores is the following:

[
    { "name": "A", "score": 1 },
    { "name": "B", "score": 2 }
]

block11

Then this code will set "Nickname" to the name of the first item when sorting by highest score:

_ae_webplayer_action: { "name": "socket-read", "args": [-2, "player_scores.<sort:desc:score:0>.name"] }

Output: B

This is the path to the variable you're storing, where . reads nested values.

Note: the sort operator follows the form <sort:[direction]:criteria?:index>, where:

Write Session Data

block16

This block will set the current (self, as defined in the first argument) user's power (in the remote server, for this game) to the value of the self variable passed into the data parameter.

_ae_webplayer_action: { "name": "socket-write", "args": [-1, "power", "_data"] }

This command writes data to the server when given the following: a player index to write to, the property path (same as read), and the value.

namearg0arg1arg2output
socket-writePlayer ID <integer>Property Path <string>Value <any><nothing>

Player ID refers to the target user, that is, the user whose data will be overwritten.

In most cases, you will be using -2 or -1 because you will only write data to the game as a whole or to update information about your player.

Property Path refers to what you are setting; it's essentially the name of the variable (unless it's nested, then it's the path to that variable). For more information on the structure of property paths, refer to the property path section in "Read Session Data"

Value will override the existing value, and it can be a number, string, boolean, or undefined (undefined will delete the property).