ADOFAI but Cursed

Curse mechanism

In the following content, midspins will be considered as 0° angle.

What is curse?

Curse is a type of object that can be applied on ADOFAI Levels which performs the corrsponding transform action for parts that meets certain conditions.


A curse is usually binded with a certain ADOFAI level, and use the (slightly modified) ID of the level as the ID of the curse.
Curse effects that don't binds to levels also exists, for example, Color Curse Series by 小绿君.

To describe a curse: But statement

A brief introduction to describe a curse effect is called a but statement.
The actual effect might be a little different between what the but statement describes.


But statements are usually written after the title of the level that the curse effect belongs to, for example:

1-X? A Dance of Fire and Ice but the music is cursed
2-X? Offbeats but it's a little longer

This website recommends using the following level title format:

{level ID} {level title} but {curse effect introduction}

To describe a cursed level: Curse hints

The curses the player experiences, including the current and the next, could be tipped by using text decorations on the bottom of the interface called curse hints or curse prompts.

Current curse: 8-X?
Next curse: 10-X?

The tips shouldn't move or rotate with the camera, or they will not have a prompt effect.
Although it's already not understandable for most of the viewers...

Countdown

Countdown is the most commonly used method to inform players when the curse effect will be changed.


The countdown starts with 3, decreases by 1 in equal interval time.
The curse effects will be updated at the exact same time when the number should be counted down to -1.

Each number should poduce a noticable hitsound without ambiguity, usually the same sound for paused beat countdowns.


The countdowns are usually located at the end of the line before the colon, surrounded by brackets, with a extra space before the left bracket only:

Current curse: 8-X?
Next curse (3): 10-X?

Current curse: 8-X?
Next curse (2): 10-X?

Current curse: 8-X?
Next curse (1): 10-X?

Current curse: 8-X?
Next curse (0): 10-X?

Current curse: 10-X?
Next curse: XC-X?
Notes that the time order of curse effects IS NOT the affect order of curse effects, and there's no direct relationship between them.

Functions like functions

Function:

  • get a number
  • modify that number
  • return a modified number

Curse:

  • get a level
  • curse that level
  • return a cursed level

They are just so alike, that it's actually possible to treat curses like functions, for example:

is equivalent to:

Current level: 1-X? ( B-X )

However, this cannot explain that some curses may return different results, even if the inputs are the same.


For example, 2-X? could also repeats the near-ending section of B-X? Please Stop Playing My Levels by 2 more times, instead of just 1 more time that we have.

This results in:

Current level: 2-X? ( B-X )

is NOT equal to:

Current level: 2-X? ( B-X )

To solve this problem, one way is to change the output of curses, from a single level, to a set of levels:

2-X? ( B-X ) → { B-X extended by 1 more times, B-X extended by 2 more times, B-X extended by 3 more times, etc. }

And the cursed level that we have is one of them inside.


This also solves some other problems below:

Some curses weren't well-defined, so there's thousands of results in thousands of cursed ones' perspective
sadly there's no thousands of cursed ones for now :(
All of them are in the output set. You are free to ignore results you don't agree.
Some curses weren't well-defined, so they just cannot produce any valid results for certain situations
The output should be the empty set .


We'll also change the input to a set of levels via a few definitions:

Cursing a single level is the same as cursing a set which only contains that level.
For example, 2-X? ( B-X ) is equal to 2-X? ( { B-X } ) .

Not to be confused with KirbyCreep's curses, which is noted as {N-X} due to my mistake.

Cursing a set which contains multiple levels is the same as cursing each level individually then merge the results into one set.
For example:

5-X? ( { 5-X, 11-X, XC-X } )

is equal to

5-X? ( 5-X ) ∪ 5-X? ( 11-X ) ∪ 5-X? ( XC-X )

Or in other words, curse evaluation distributes over union operation (except for empty set) .

This isn't only for consistency, but also because that it would be really helpful to define concepts, for example:

Applying multiple curses at once

The notation method that use plus signs + to represent that multiple curses takes effect in order from left to right has been DEPRECATED!

Multiplication signs * are used to present that multiple curses takes effect in order from left to right.
Function composition signs are used to present that multiple curses takes effect in order from right to left.


Here's an example that shows the importance of the curse order:

Current curse: 11-X? * XC-X?
Next curse: 11-X?XC-X?

11-X? * XC-X? will first add twirls onto every tile, then remove all the twirls,
so the result is that all the twirls are missing;

11-X?XC-X? will first remove all the twirls, then add twirls onto every tile,
so the result is that there's a twirl on every tile.


Nesting curse functions is another way to specify the curse order:

Current level: XC-X?( 11-X?( 5-X ) )
Next level: 11-X?( XC-X?( 5-X ) )

However, abusing nesting would cause a lot of brackets to stack, therefore the hints would be even harder to parse.

Keywords

None

The identity curse, or in other words, None(x) = x.

Current curse: None
...

Usually lonely appears at next curse to represent "please wait".

Next curse: ...

Sometimes could alsos be used as "need more info":
If some part of the curse hint wouldn't change in a while, while the other part changes frequently, Ellipsis could be used to represent that "other" part which could be noted at somewhere else.

Current curse: 5-X? * 10-X?
Next curse: 5-X? * ... * 10-X?

Also known as Ellipsis.

StopIteration

The curse effect won't change before level ends, so the player can now finally ignore the hint and fully focuses on the chart.

Next curse: StopIteration

Multiple instances of the same curse effect

Applying a curse is actually applying an instance of the curse.
Subscripts are used to explicitly indicate that if multiple curses are the same instance or not.

Current curse: 12-X?1
Next curse: 12-X?2
Current curse: 12-X?_1
Next curse: 12-X?_2

(Thanks Regularly for the format method!)

Curse instance are initialized at its first appearance.
Curse instance are still able to be reused after its first disappearance, however the default behavior is that, if a curse instance without subscript stops appearing inside current curse, the next curse wouldn't use that instance of that curse.

Next curse: 12-X? # instance a
Next curse: 12-X? * XR-X? # instance a * instance x
Next curse: XR-X? # instance x
Next curse: 12-X? # instance b
Next curse: 12-X?1 # instance 1
Next curse: 12-X? # instance c
Next curse: 12-X?1 * 12-X? # instance 1 * instance c
Next curse: 12-X? * 12-X? # instance c * instance d

Some curse may have needs to store some temporary data used for calculations, for example, 12-X? store all unique loop has been played since the effect starts.
Temporary data are stored inside each curse instance seperately.

Inversed curses

This concept was named as revert / invert / negate / anti .

The inverse for curses is similar yet different to the inverse for functions.


For each curse C,
its inverse C-1 exists,
that for each level L and LC,
LC ∈ C ( L ) is equivalent to L ∈ C-1 ( LC ).

The difference between this above and inverse for functions is that this uses instead of =.


Inverse-cursing a level which is impossible to get inside all the outputs of the corresponding curse would produce the empty set .

To avoid these situations in actual cursed level making progress, you can overwrite the output using the input, like the curse didn't do anything.
( Thanks PyrotechnicTriforce for the idea! )
( TODO: there's a way to define it but it requires concepts woould introduce inside the metacurse article )


Using an inversed curse often produces massive amount of possible results
( O(2n), O(n!), even O(∞) theoredically ) .


Inversed curses can be represented changing the - sign to the + sign in the ID of the corresponding curse, if possible:

Current curse: XC-X?
Next curse: XC+X?

In the deprecated sequential format, Inversed curses could also be represented by inserting the - sign at the beginning of the ID:

Current curse: - XC-X?
Next curse: XC-X? - XC-X?

Here's a way to abbreviate 2 opposite curses which are next to each other that's not deprecated since it's indeed convenient:

Current curse: XC-X? * XC-X?-1
Current curse: XC-X? - XC-X?
Current curse: ± XC-X?
Current curse: XC-X?-1 * XC-X?
Current curse: - XC-X? + XC-X?
Current curse: XC-X?

( Thanks DragonFire28 for the suggestion of the color! )

Inversed curses can also be represented via the power operation of functions:

Current curse: XH-X?-1
Current curse: XH-X? ^ -1
Current curse: XH-X?-1 * XH-X?-1 * XH-X?-1
Current curse: XH-X?-3

Metacurse

In specific situations, the curse-applied object could be a non-level being. (TBC)