# 리듬 닥터 에디터 가이드북 - r19
# 영어 원문 문서 보러가기 (View English Version)
- [English Version](https://hackmd.io/@WillFlame/rybdnRtwu)
# 조건문
조건문을 이용하면 레벨의 특정 요구 사항을 충족하는 경우에만 레벨 내의 일부 이벤트를 동작하게 할 수 있습니다.
조건문은 대부분의 이벤트에 적용이 가능합니다.
먼저, 조건문에 입장하는 방법은 두 가지가 있습니다.
**1. 이벤트 편집 메뉴의 가장 왼쪽 위의 표지판 모양 UI 이용하기
(대부분의 이벤트에 존재합니다)**

**2. 액션 탭에 있는 조건문 버튼 이용하기**

조건문 메뉴는 이렇게 생겼습니다:

이 메뉴에는 이벤트의 쉬운 접근 및 재사용을 위해 여러분이 레벨에서 사용하는 모든 조건이 포함될 것입니다.
## 조건문 만들기

조건문의 **이름**은 말그대로 제목으로만 쓰이니, 제작자 여러분이 알아차릴 수 있을만한 이름을 이용하시기 바랍니다.
조건문에는 **다섯 가지** 유형이 존재합니다:
- **마지막 히트** : 행의 최근 적중을 기준으로 트리거가 작동합니다.
- 특정 행 및 히트 유형을 추가로 지정할 수 있습니다.
- **사용자 지정** : 사용자가 설정한 것에 근거하여 트리거가 작동합니다.
- 매우 복잡한 것들을, 자세한 내용은 아래를 참고하시기 바랍니다.
- **실행 횟수** : 이벤트가 사용된 횟수를 기준으로 트리거가 작동합니다.
- 주의 : 이벤트가 두 번 이상 실행되기 위해서는 레벨이 반복(루프)을 포함해야합니다.
- **언어** : 사용자가 게임에 적용한 언어에 따라 트리거가 작동합니다.
- 다른 언어로 된 대화 또는 떠 있는 텍스트에 유용하게 사용할 수 있습니다.
- **플레이어 모드** : 레벨이 1P(플레이어 모드)인지 2P인지 여부에 따라 트리거가 작동합니다.
또한 조건문 편집창의 아래쪽 **삭제** 버튼을 클릭하여 트리거를 삭제할 수 있습니다.
다만, 조건문을 삭제한다는 것은 해당 조건문을 사용하는 이벤트에서 그 조건문이 모두 삭제된다는 것이므로 유의해 주시기 바랍니다.
조건문을 생성하면, 조건문 선택 메뉴에서 조건문을 수정하거나 복제할 수 있습니다.

복제 버튼(왼쪽)은 조건문을 복사(클론)할 수 있고 렌치 버튼(오른쪽)은 조건을 수정할 수 있습니다. 조건문을 복제해도 복제하기 전의 원래 조건문을 사용한 모든 이벤트에 복제한 조건이 자동으로 적용되는 것은 아닙니다.
## 이벤트에 조건문을 추가하기
이벤트를 작동시킬지 여부는 이벤트에 조건문을 추가하여 적용할 수 있습니다.
**파랑색**으로 테두리가 강조표시된 곳은 해당 조건문이 참일때 발동하도록 되어있고, **빨강색**으로 테두리가 강조표시된 곳은 해당 조건문이 거짓일때 발동하도록 되어있습니다.
*이벤트가 작동하기 위해선 이벤트에 있는 조건문의 모든 조건이 충족되어야 합니다.*
예를 들어, 이 조건문들이 적용된 이벤트는 가장 최근 히트가 정확(Perfect)이고 언어가 영어로 설정되어 있지 않은 경우에만 작동하도록 되어있습니다.

조건문이 있는 이벤트의 표지판 기호에 커서를 갖다대면 어떤 조건문이 적용되어 있는지 요약되어 표시됩니다.

## 조건문의 실행기간
오른쪽 상단의 시계 아이콘을 사용하여 시간 내에 이벤트의 조건문을 모두 충족해야 이벤트가 작동하도록 할 수 있는 **기간**을 설정할 수 있습니다. 지속 시간 내에 모든 조건이 충족되지 않으면 이벤트가 작동하지 않습니다. 플레이헤드가 이벤트를 통과하기 전에는 조건문의 충족여부에 대해 검사하지 않습니다.
조건문은 **모든 프레임**을 검사하므로 이벤트가 여러 번 작동할 수 있습니다. 예를 들어, 8박자의 지속기간 있는 이벤트는 만약 다음 8박자에 대해 모든 조건이 충족되면 두 번 이상 트리거될 수 있음을 의미합니다.
기간이 0일 경우에는 이벤트가 타임라인을 통과할 때 즉시 한 번만 작동합니다.
-----
# 플레이스타일 설정하기
Setting the play style allows you to change the behaviour of the playhead (the scrolling white line on the timeline). Note that changing the play style **will not** change the behaviour of the music. The music will continue playing as if the play style did not change.
There are 6 possible play styles: Normal, Loop, LoopBeatsOnly, Prolong, Immediately, and ExtraImmediately.
**절대로 반복하거나, 바 1로 건너뛰기를 하지 마세요. 문제를 유발할 수 있습니다.(유니티 크래시 등등)**
## Normal
Ths is the default behaviour. The playhead advances through bars in sequential order.
## 반복
This causes the playhead to restart the current bar upon reaching the end of the current bar. This will repeat until the play style is changed to something else.
## LoopBeatsOnly
This causes the playhead to restart the current bar upon reaching the end of the current bar, but subsequent times only plays the beats (i.e. without the vfx).
## Prolong
This causes the playhead to stop at the end of the current bar until the play style is changed to something else. The game **will wait for the end of a bar** (music-wise) before changing the play style away from Prolong in order to maintain sync.

*The playhead will remain here until the play style is changed.*
Note that since the playhead no longer moves, **you will get stuck** unless you have a conditional that eventually triggers and changes the play style.
Using the `activeDialogues` mod automatically sets the play style to Prolong, which lets dialogue remain on screen until user input is received.
## Immediately
This causes the playhead to jump to another bar **after a prebar of approximately 667ms**. The absolute bar number can be given, or a relative bar number from the current bar can be given instead.

Unlike the `SetNextBar()` custom method, this event can be executed in the middle of a bar (or even the middle of a beat).
This will almost certainly cause your level to desync from the music, as the jump is performed immediately after the prebar delay ends. This can be remedied with some planning.
## ExtraImmediately
This is similar to Immediately, but causes the playhead to jump to another bar quicker, with **a delay of approximately 300ms**.
This will also almost certainly cause your level to desync from the music.
----
@huantian#4880 님이 만든 도움이 될 만한 영상입니다. (영어로 되어있음): https://discord.com/channels/296802696243970049/833132643234349097/844302910862917683
----
# Tags
Tags allow groups of events to be executed together, as many times as needed.

Multiple events can be given the same tag. When the tag is run, all the events will be executed as if the playhead jumped to the first event with the tag and started running from there. **Note that the maximum distance between events with the same tag is 1 bar**. Any longer and you will encounter unexpected behaviour.
> A common way to work around the 1 bar maximum is by creating a 99-beat bar at the very end of the level.
Tagged events can be called as many times as needed simply by running the tag multiple times. This allows for event re-use and better organization. Tags can also be disabled, which prevents them from being run.
> **Note: Currently, tagged Play Sound events are not well-supported. When running the tag, the Play Sound event will be triggered slightly later than expected (approximately 300ms).** There are 2 workarounds (not recommended):
> - Moving the Play Sound event earlier relative to other tagged events.
> - You may need to create a useless event to act as an anchor if there are no other tagged events.
> - Running the tag with the custom method and changing the execution time to OnPreBar.
> - This will cause other tagged VFX events will be executed at a different relative time.
## Tagging Events
Pressing Shift-0 will toggle the visibility of the tag field on each event. Each event can only contain one tag. Upon tagging, the lower-left corner of the event will be coloured orange.

Tagged events do not play when the playhead passes over them, unlike normal events. This means they can be placed anywhere in the level. Instead, the tags must be run with a separate event.
> **Note: When scrubbing, tagged VFX events are currently bugged and will be played when the playhead passes over them . Playing the level from bar 1 does not have this issue.**
## Running a tag
> **Note: Do not have an event call its own tag at any point. Upon scrubbing at any point other than bar 1, the game will crash.**
Tagged events can be run in two ways:
### 1. The Tag Action event

The Tag Action event can be found near the bottom of the VFX list. Select the `Run Tag` or `Run All Tags Containing Text` action from the dropdown, and provide the tag's name. The tag will be executed as soon as the playhead passes over the Tag Action event, *unless* the Tag Action event itself is tagged (see the section on layering tags below).
### 2. The RunTag() custom method (or its alias, RunEventsWithTag())

This requires a Call Custom Method event (near the bottom of the VFX list). Both `RunTag()` and `RunEventsWithTag()` do the same thing, and need to be provided the tag name prepended with `str:`.
## Enabling and Disabling Tags
The Tag Action event supports enabling and disabling specific tags, as well as all tags containing a specified text.
The corresponding custom methods are listed below: (replace `tagName` with your tag's name)
```javascript
EnableTag(str:tagName) // currently not working
DisableTag(str:tagName)
EnableTagsContaining(str:tagName)
DisableTagsContaining(str:tagName)
```
While the effect can be replicated using conditionals, these events can come in handy when combined with certain special tags.
## Special Tags
Special tags are prepended onto your tag name, like shown below. These tags will be automatically run every time their condition is met, without needing to be run manually with an event.

| 태그 | 조건문 |
| ----------------------- | ------------------------------------------ |
| `[onHit]` | 박자를 맞힐 때마다 항상 |
| `[onMiss]` | 박자를 놓칠 때마다 항상 |
| `[onHeldPressHit]` | Every time a held beat's press is hit |
| `[onHeldReleaseHit]` | Every time a held beat's release is hit |
| `[onHeldPressMiss]` | Every time a held beat's hit is missed |
| `[onHeldReleaseMiss]` | Every time a held beat's release is missed |
| `[rowX]` (X is a number)| Modifies the tag to only apply to one row |
For the `[rowX]` event, X is a 0-indexed number. For example, the tag `[onHit][row0]` will run every time a beat on row 1 is hit. If the row does not exist, it will apply to all rows (i.e. the tag will be ignored).
These special tags can also be the target of Enable/Disable Tag events. Because they are executed so frequently, it is much simpler to enable/disable the tag than to manage conditionals around them.
## Layering Tags
For more complex groupings, you may want to consider running a tag from another tag (known as *layering*). Since the Tag Action and Call Custom Method events can both be tagged, you can have one tag execute multiple tags in this fashion.

----
# Variables
There are two types of variables: **read-only** and **editable**. The value of read-only variables cannot be changed manually, while they can be changed in editable variables.
## Editable Variables
There are currently 3 types of editable variables: **integers** (i), **floats** (f), and **booleans** (b). 10 of each variable are currently accessible. The names of variables cannot be changed, only their values.
- Integers are named i0, i1, ... i9.
- Can take any integer value from -2,147,483,648 to 2,147,483,647.
- Floats are named f0, f1, ... f9.
- Booleans are named b0, b1, ... b9.
- Either `true` or `false`.
The variable `buttonPressCount` acts like an integer (and can be modified accordingly), but is additionally incremented whenever the player presses.
## Read-only variables
These are special variables that provide some information about the current level or state of the game. The value of these variables cannot be modified, they can only be read.
| Variable Name | Definition |
| ----------------------- | ------------------------------------------ |
| `bpm` | The currently set bpm |
| `barNumber` | The current bar number |
| `numEarlyHits` | The current number of early hits |
| `numLateHits` | The current number of late hits |
| `numPerfectHits` | The current number of perfect hits |
| `numMisses` | The current number of misses (without mistake weighting) |
| `numMistakes` | The current number of mistakes (with mistake weighting) |
| `XPress` (X is a key) | `true` immediately when X is pressed, `false` otherwise |
| `XRelease` | `true` immediately when X is released, `false` otherwise |
| `XIsPressed` | `true` while X is being held down, `false` otherwise |
List of allowed keys: `p1`, `p2`, `anyPlayer`, `up`, `down`, `left`, `right`.
## Using variables
Variables can be used in 3 locations:
- Call Custom Method, in an expression
- Floating Text/Dialogue/Status Sign
- Conditionals
### Call Custom Method
Variables can be read or modified in the Custom Method Name field. This can be combined with tags and conditionals to allow programmatic usage of variables.
This supports the operators `++`, `--`, and `=`.
Examples: `i1++`, `i2 = 4`
### 떠 있는 텍스트 / 대화 상황 Sign
Variables can be displayed in these events using interpolation. Simply surround the expression with braces.
Examples: `I have {i1} apples`, `We have {i1 + i2} pears`
### Conditionals
Variables can be read in the Expression field of a condition. These can be combined with operators `==`, `!=`, `>`, `<`.
Examples: `i1 == 1`, `i2 > i3`
## Operators
In addition to the comparison operators, there are also the mathematical operators `+`, `-`, `*`, `/`, and `%` (modulo).
# Reference
Overall description for the thingy
## 변수
Read-only variables
## 모드
Variables that can be set to change different parts about the game. (Are mods just variables?)
## 커스텀(사용자 지정) 방법
## Comment Commands
## 기타 등등 (수술/Enums?)