Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: Booster documentation #841

Draft
wants to merge 1 commit into
base: feat/vitepress-docs
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/eternascript/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default defineConfig({
text: 'Reference',
items: [
{ text: 'Utility APIs', link: '/reference/utility-apis' },
{ text: 'Booster Structure', link: '/reference/booster-structure' },
{ text: 'Booster APIs', link: '/reference/booster-apis' },
]
}
Expand Down
5 changes: 4 additions & 1 deletion docs/eternascript/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ features:
details: Discover the core libraries for working with RNA and the Eterna scripting interface
link: /reference/utility-apis
linkText: Explore
- title: Booster Structure
details: Learn about the structure boosters should follow.
link: /reference/booster-structure.md
linkText: Explore
- title: Booster APIs
details: Discover ways to interact with the Eterna game/design interface
link: /reference/booster-apis
linkText: Explore
---

71 changes: 71 additions & 0 deletions docs/eternascript/reference/booster-apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
outline: [2, 3]
---

# Booster APIs

## General structure

### Accessing the applet

```js
let applet = document.getElementById("maingame");
if (applet == null) return "maingame element missing";
```

from there, APIs can be used like this:

```js
let ok = applet.set_sequence_string(my_seq);
```

### Exploring the API without writing a booster

Every modern browser has some sort of console that lets users input javascript commands.

- Open the puzzle
- Open the javascript console of your browser
- Because the game is loaded in an iframe, you will need to change the console to run commands within the iframe instead of the top-level website page. Somewhere in the console window, there should be a dropdown, likely with "Top" currently selected which will need to be changed to something like "game" or "EternaJS".

## Getters

### get_sequence_string()

Retrieve the current sequence of the puzzle. This includes any bases the user has painted.

#### Type

`() => string`

- Returns: The current sequence present in the puzzle. For example: `"UUUUUUAAAAAAA"`.

#### Example

```js
// When entering a puzzle:
console.log(applet.get_sequence_string()); // AAAAAAAAAAAAAAA
// After painting some bases:
console.log(applet.get_sequence_string()); // AUAUAUAAAAUAUAU
```

### get_full_sequence()

Returns the full sequence currently present in a specific state in the puzzle, including oligos.

The result will be a string containing the sequence of each strand, separated by `&` - such as `"AUUUUU&GGGGG&CCCCCC"`, in which `AUUUUU` is the sequence of the main RNA strand, `GGGGG` is the first oligo's sequence, and `CCCCCC` is the second oligo's sequence.

#### Type

`(index: number) => string`

- `index`: 0-based index of the state to be queried.
- Returns: The full sequence of the given state, including oligos.

#### Example

```js
// When entering a puzzle:
console.log(applet.get_sequence_string()); // AAAAAAAAAAAAAAA
// After painting some bases:
console.log(applet.get_sequence_string()); // AUAUAUAAAAUAUAU
```
26 changes: 26 additions & 0 deletions docs/eternascript/reference/booster-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Booster Structure

## Accessing the applet

```js
let applet = document.getElementById("maingame");
if (applet === null) return "maingame element missing";
```

from there, APIs can be used like this:

```js
let ok = applet.set_sequence_string(my_seq);
```

Read more about the APIs in [Booster APIs](/reference/booster-apis.md).

## Synchronous vs Asynchronous

In order to ensure that multiple boosters and user interaction do not interfere with each other, boosters are run one at a time and the UI is locked preventing user input while a booster is running. For "synchronous" scripts (which do all their work immediately and without stopping), this "just works". However, if a script performs any actions asyncronously (eg using setTimeout/setInterval, promises/async/await, asyncronous network requests, etc), the game will think your code has already ended, when it will actually be running some code after it initially finishes executing and returns a result (either via an explicit `return` or running to the end of the script).

Because of this, in order for asyncronous scripts to be properly handled, it needs to indicate that it is asyncronous and let the game know once it has completed. This is done by the script ending with the statement `return {async: "true"};` and then once it is actually complete, calling `applet['end\_'+sid](r);` where sid is the ID of the script.

EternaScripts also have timeout-checking statements automatically inserted in loops. This causes the code to stop if the script has been running for more than (by default) 10 seconds. In asyncronous scripts, you are likely going to be running code after that timeout happens. To prevent this behavior, you can use the statement `global_timer = new Date();`.

For an example of a syncronous booster, see the [Tsumego](https://eternagame.org/scripts/7070114) script. For an example of a asyncronous booster, see the [Naive Solver script](https://eternagame.org/scripts/6713763).