Some App Cloner modding options allow the use of placeholders. These placeholders allow text to be substituted at runtime. Starting with App Cloner 2.14.5 a new placeholder syntax is used.

The general placeholder syntax is:

{**placeholder**}

{**placeholder**:*value*}

{**placeholder**|*<options>*}

{**placeholder**:*value*|*<options>*}

Some placeholders require a value and some placeholders additionally support one or more options, which are specified as a comma-separated list of name / value pairs separated by a colon, e.g. **option**:value,**option**:value, etc.

See below for a summary of number-specific options, which include arithmetic operations, the modulus operator and formatting options.

Since App Cloner 2.14.5 you may enable placeholders in the **Welcome message** option, which can be useful for testing placeholder expressions.

## Clone number

{**clone-number**}

{**clone-number**|*<number options>*}

Substitutes the 1-based clone number of the current clone. Clone #1 substitutes the number 1, clone #2 substitutes the number 2, etc.

NOTE: The legacy placeholder syntax for the clone number is #, ##, ### and so on, which substitutes a certain length of 0-padded digits.

## Clone index

{**clone-index**}

{**clone-index**|*<number options>*}

Similar to clone number but substitutes the 0-based clone index of the current clone. Clone #1 substitutes the number 0, clone #2 substitutes the number 1, etc.

## App name

{**app-name**}

Substitutes the name of the cloned app. This placeholder has no options.

NOTE: The legacy placeholder syntax for the app name is {NAME}.

## Random number

{**random-number**|min:<min>,max:>max>}

{**random-number**|min:<min>,max:>max>,*<number options>*}

Substitutes a random integer number between a minimum value (inclusive) and a maximum value (exclusive). If **min **is not provided, 0 is assumed, if **max **is not provided, 100 is assumed. For instance, {random-number|min:10,max:20} generates a random number from 10 to 19 (with a total of 10 possible numbers).

IMPORTANT: The default random number generator seed is the clone’s identity seed. This means by default it will always use the same random number (even after restarting the cloned app) until you generate a new identity using the **New identity** option. To provide an alternate seed value you can use the **seed **option.

{**random-number**|min:<min>,max:>max>,seed:*<seed>*}

{**random-number**|min:<min>,max:>max>,seed:*<seed>*,*<number options>*}

You may consider using date or time placeholders to substitute the seed value (see below).

NOTE: The legacy placeholder syntax for the random number is *, **, *** and so on, which substitutes a certain length of 0-padded digits.

## Identity seed

{**identity-seed**}

{**identity-seed**,*<number options>*}

Substitutes the identity seed, which is a number that is randomized every time you generate a new identity using the **New identity** option. This is used as default seed value for the random number and **** placeholders. The identity seed is maintained by App Cloner, which is why App Cloner must remain installed.

## Identity index

{**identity-index**}

{**identity-index**,*<number options>*}

Substitutes the identity index, which is a number that is incremented every time you generate a new identity using the **New identity** option. While the identity index starts at 0 for new clones, you do not have direct control over its value (you cannot reset it unless you uninstall & reinstall App Cloner). Use the **mod **number option (see below) to limit the identity index to a certain range. The identity index is maintained by App Cloner, which is why App Cloner must remain installed.

## Current date

{**current-date**}

{**current-date**|format:*<format>*}

Substitutes the current date in the form of yyyyMMdd (without any separators). You can provide a custom date format according to this specification.

## Current time

{**current-time**}

{**current-time**|format:*<format>*}

Substitutes the current time in the form of HHmmss (without any separators, using the 24-hour clock). You can provide a custom time format according to this specification.

## Current millis

{**current-millis**}

{** current-millis**,

*<number options>*}

Substitutes the current milliseconds since Unix epoch, for instance 1651363200000 represents midnight 1st of May 2022 UTC. You may want to use this as **seed **option for the random number placeholder, if you want to generate different random values continuously, e.g. {random-number|max:50,seed:{current-millis}}.

## Started millis

{**started-millis**}

{** started-millis**,

*<number options>*}

Substitutes the milliseconds since Unix epoch when the app process was started. You may want to use this as **seed **option for the random number placeholder, if you want to generate different random values each time the app process is started, e.g. {random-number|max:50,seed:{started-millis}}.

## Resource string

{**res-string**:*name*}

Substitutes the resource string for the given resource name. To use this option you should be familiar with string resources of Android apps. This is useful if you want to substitute a language-independent string, e.g. when skipping dialogs that contain certain resource text.

## File contents

{**file-contents**:*path*}

{**file-contents**:*path*|row:*<row>*}

{**file-contents**:*path*|row:*<row>*,column:*<column>*}

{**file-contents**:*path*|row-index:*<row index>*}

{**file-contents**:*path*|row-index:*<row index>*,column-index:*<column index>*}

Substitutes the contents of a local file at the given file path. You may use other placeholders inside the path to substitute the clone number / index, a random number or the date / time before the contents of the file is read.

By default the placeholder is substituted by the entire file contents. By providing the **row **or **row-index** options, you can substitute a specific row of the file only (**row **is the 1-based, e.g. 1 is the first row, while **row-index** is 0-based, e.g. 0 is the first row; no header column is expected).

If you have CSV (comma-separate values) data, you can then use the **column **or **column-index** options to look up a specific column of the previously selected row containing y (again, **column **is the 1-based, e.g. 1 is the first column, while column**-index** is 0-based, e.g. 0 is the first column).

The file must use UTF-8 encoding.

If the cloned app does not have the read storage permission granted, it will prompt you to grant this permission. While the permission is not granted, the placeholder will be substituted by an empty string. If the cloned app relies on the placeholder being correctly substituted you may consider granting the permission after the clone is installed but before it is started. Alternatively, you may consider setting the target SDK version to 22 (see Manifest & resource options), which will auto-grant all permissions after installation.

## Number options

The following options apply to number placeholders. They are applied in the order shown below.

**mod**:*<modulus>*

The **mod **option applies the modulus operator to the number value. This ensures that the number is always inside a given range. For instance, **mod:1000** ensures that the number is always mapped to the range 0 to 999. For instance, 999 will remain 999 but 1000 will be mapped to 0, while 1999 will be 999 again and 2000 will be mapped back to 0, and so on.

**pow**:*<power>*

The **pow **option raises the number value to the given power.

**mul**:*<factor>*

The **mul **option multiplies the number value by the given factor.

**mul**:*<divisor>*

The **div **option divides the number value by the given divisor.

**add**:*<number>*

The **add **option adds the the number.

**sub**:*<number>*

The **sub **option subtracts the the number.

**digits**:*<length>*

The digits option ensures that a number is formatted with 0-padding, so that it has at least the given number of digits. For instance, **digits:3** formats the number 0 as 000, the number 10 as 010, while the number 100 remains 100.

You can combine the **mod **option and **digits **options to create a fixed length pool of a certain range of numbers, e.g. 000 to 999 or 0000 to 9999.

## Examples

The following placeholder expression reads a row from a file called file.txt. For each new identity generated it substitutes rows in the range 1 to 10 for clone #1, rows in the range 11 to 20 for clone #2 and so on.

{file-contents:file.txt|row-index:{identity-index|mod:10,add:{clone-index|mul:10}}}

The following placeholder expression uses a different approach, concatenating two 2-digit numbers. The first 2-digit number is the clone index, 00, 01, etc. The second 2-digit number is the identity index in range 00 to 99. This results in a 4 digit number for the final row index: 0000-0099 for clone #1, 0100-0199 for clone #2, etc.

{file-contents:file.txt|row-index:{clone-index|digits:2}{identity-index|mod:100,digits:2}}