# SRS I kicks. the single consistent rule.

Thread in 'Discussion' started by Zaphod77, 12 Jul 2009.

1. ### Zaphod77Resident Misinformer

It turns out there is one.

take any initial orientation, and any final orientation, and apply the simple rule i am about to discuss, and you will get the correct kick table.

i'll give an example here.

we rotate clockwise from first position.
Code:
0-3
....
....
..I.
iiIi
..I.
..I.
....

the lowercase i is initial position, and uppercase is final.

For first kick, we slide the piece two in the direction that allows this and still has the initial and final piece overlap. EIther left or right.

Code:
....
....
I...
Iiii
I...
I...
....

Second kick is one space in the opposite direction

Code:
....
....
...I
iiiI
...I
...I
....

Now we get into vertical kicks. we go back to 2 in the original direction, and then kick 1 in the vertical direction that causes ends to overlap.

Code:
....
....
....
Iiii
I...
I...
I...

then one in the opposite horizontal direction, and 2 in the opposite vertical direction, to create an end pivot again.

Code:
...I
...I
...I
iiiI
....
....
....

This rule generates the correct kick table for all games that properly implement SRS. This does not include TGM ACE or TGM3:TI.

Lockjaw does not follow this rule, but instead swaps the third and 4th kicks if the third one is higher than the 4th. This makes it less consistent than the original SRS rule.

2. ### Edoa.k.a. FSY

This is not correct; in Tetris Worlds (which according to the wiki, features the most accurate implementation of SRS), if you rotate anti-clockwise from spawn orientation, the I tetromino kicks 1 left (-1) in preference to 2 right (+2).

I've converted nightmareci's "offset" data to more familiar kick tables relative to basic rotation. I've also tabulated both jago's and koryan's analyses in the same format:

Note: when rotating to a horizontal state, (0 or 2), because it is impossible for basic rotation (kick 1) to be blocked, yet both kick 2 and kick 3 to be available; it is not possible to test the order of kick 2 and kick 3. Therefore, the asterisks indicate where the original research was edited in light of this, to achieve consistency with Tetris Worlds.
EDIT: I've added in my own independent analysis of Tetris Splash.
Code:
         (0) ........
[][][][]
........
........
(L) ..[]....          ....[].. (R)
..[]....          ....[]..
..[]....          ....[]..
..[]....          ....[]..
........
........
[][][][]
........ (2)

0->R
( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2) Worlds, nightmareci
( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2) Splash, edo
( 0, 0):(-2, 0):(+1, 0):(+1,+2):(-2,-1) ACE, jago
( 0, 0):(-2, 0):(+1, 0):(+1,+2):(-2,-1) Ti, koryan

R->0
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) Worlds, nightmareci
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) Splash, edo
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) ACE, jago
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) Ti, koryan

R->2
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) Worlds, nightmareci
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) Splash, edo
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) ACE, jago
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) Ti, koryan*

2->R
( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1) Worlds, nightmareci
( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1) Splash, edo
( 0, 0):(-2, 0):(+1, 0):(-2,+1):(+1,-1) ACE, jago
( 0, 0):(-2, 0):(+1, 0):(-2,+1):(+1,-1) Ti, koryan

2->L
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) Worlds, nightmareci
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2) Splash, edo
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-1) ACE, jago
( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-1) Ti, koryan

L->2
( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2) Worlds, nightmareci
( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2) Splash, edo
( 0, 0):(-2, 0):(+1, 0):(+1,+2):(-2,-1) ACE, jago*
( 0, 0):(-2, 0):(+1, 0):(+1,+2):(-2,-1) Ti, koryan

L->0
( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1) Worlds, nightmareci
( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1) Splash, edo
( 0, 0):(+1, 0):(-2, 0):(-2,+1):(+1,-2) ACE, jago*
( 0, 0):(+1, 0):(-2, 0):(-2,+1):(+1,-2) Ti, koryan*

0->L
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) Worlds, nightmareci
( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1) Splash, edo
( 0, 0):(+2, 0):(-1, 0):(-1,+2):(+2,-1) ACE, jago
( 0, 0):(+2, 0):(-1, 0):(-1,+2):(+2,-1) Ti, mufunyo

Interestingly, jago's and koryan's analyses are in complete agreement except for the last kick (0->L). I would frankly be surprised if Arika hadn't re-used the code from Ti in ACE, so I suspect that either jago or koryan has made an error in their analysis. Would anyone care to test this?
EDIT: muf has confirmed this for me.

Also, would anyone be willing to research the behaviour of TDS?

Last edited: 12 Jul 2009
3. ### colour_thief

Hmm, perhaps nightmareci could comment on this? His is so wildly different than the others that I'd expect either his interpretation is mistaken or your conversion to wallkick offsets is.

4. ### Edoa.k.a. FSY

There's no mistake in nightmareci's "offset" values, as he took them straight from the PC version's .tws script files. I don't think I made any error converting them into (x,y) wallkick translations either. I've just finished my own independent research into Tetris Splash, and have edited it into my previous post. Note that the Worlds and Splash I rotations are identical.

I don't think that the Guideline SRS is "wildly different" from Arika's SRS; in almost all cases, it's merely a swapping of the test order of kicks 2 and 3, or kicks 4 and 5. The only other difference is that Arika doesn't allow a downward's kick of 2 spaces, whereas the Guideline does.

5. ### lee n

I've always had this gut feeling that there were differences between SRS implementations in different games. But this is... interesting.

6. ### Zircean

I wonder why all the SRS implementations have some kicks swapped or something like that. I'd think it's documented well enough in the guideline that these things aren't supposed to happen...

7. ### Zaphod77Resident Misinformer

when rotation from L to 0, the downward kick is preferred. i've tested this many many times in DS. According to the wiki, tetris worlds should have the same behavior.

Either Tetris Worlds is wrong too, or the analysis is mistaken.

For the rules to make sense, that also means i must be correct on the order of the kicks.

yes, offet 2 and 3 cannot have their order tested in certain circumstances, but offset 4 and 5, which always have the SAME x offset as 2 and 3, CAN always be tested.

Last edited: 12 Jul 2009
8. ### Edoa.k.a. FSY

Yes, Tetris Worlds does behave in this way when rotating L->0; no one's disputing this; the kick order -- as tabulated above -- is:

Code:
( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1)
describing this in plain English:

1. basic rotation
2. 1 right
3. 2 left
4. 1 right and 2 down
5. 2 left and 1 up

Who ever said that the Guideline SRS has to make sense?

9. ### Zaphod77Resident Misinformer

Okay... sigh. corrected rule.

When rotating to or from 1 ccw, prefer the shift by 1 to the shift by 2.

When rotating to or from 1 cw, prefer the shift by 2 to the shift by 1.

GOd, i hate SRS. but at least i can now produce the correct kick table on demand.

Last edited: 13 Jul 2009
10. ### Edoa.k.a. FSY

It's now been confirmed that I kicks in Ti and ACE are identical to one another, as are the I kicks in Tetris Worlds and Splash.

I think I may have an explanation for why Arika's kicks differ from the "official Guideline". Recalling my previous comment on how it's not possible to test the order of kicks 2 and 3 when rotating to a horizontal position, it is clear that the order of these two kicks can be arbitrarily changed without making any difference. Doing so reveals that there is a logic to how Arika's I kicks behave:

When rotating from or to a horizontal state, wallkicks are symmetric about the y-axis. For example, starting with spawn orientation, the first kick tested is 2 left when rotating clockwise, and 2 right when rotating anti-clockwise; the second kick tested is 1 right when rotating clockwise, and 1 left when rotating anti-clockwise; and so on.

The "logic" behind the guideline kicks is that the (x,y) translation values are negated when rotating back and forth between two orientation states. Presumably, the designers of the system thought that this would mean that rotating back and forth between two orientation states would also result in the tetromino switching back and forth between two playfield positions. This seems like quite a reasonable and useful thing to do; you rotate one way and the tetromino kicks from A to B, you rotate the other way and you should get back to position A again. Sadly, if this really was the designers' intent, they got it wrong.

Here's the wallkick data again, rearranged to make it easier to see the logic:
Code:
         (0) ........
[][][][]
........
........
(L) ..[]....          ....[].. (R)
..[]....          ....[]..
..[]....          ....[]..
..[]....          ....[]..
........
........
[][][][]
........ (2)

Arika
symmetric about the y-axis when rotating from or to
a horizontal state.

0->R  ( 0, 0):(-2, 0):(+1, 0):(+1,+2):(-2,-1)
0->L  ( 0, 0):(+2, 0):(-1, 0):(-1,+2):(+2,-1)

2->R  ( 0, 0):(-2, 0):(+1, 0):(-2,+1):(+1,-1)
2->L  ( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-1)

R->0  ( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2)
L->0  ( 0, 0):(-2, 0):(+1, 0):(-2,+1):(+1,-2)

R->2  ( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1)
L->2  ( 0, 0):(+1, 0):(-2, 0):(+1,+2):(-2,-1)

Guideline
(x,y) translation values are negated when rotating
back and forth between two states.

0->R  ( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2)
R->0  ( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2)

R->2  ( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1)
2->R  ( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1)

2->L  ( 0, 0):(+2, 0):(-1, 0):(+2,+1):(-1,-2)
L->2  ( 0, 0):(-2, 0):(+1, 0):(-2,-1):(+1,+2)

L->0  ( 0, 0):(+1, 0):(-2, 0):(+1,-2):(-2,+1)
0->L  ( 0, 0):(-1, 0):(+2, 0):(-1,+2):(+2,-1)

11. ### nightmareci

My interpretation is based on repeatedly trying different offset lists in a Tetris Worlds Script (TWS) until I could finally realize how it worked. My intention is to reveal the concepts that Blue Planet Software came up with when creating SRS. These concepts are fundamentally different than what we've thought of ourselves, because it was probably all independently invented specifically for Tetris Worlds, not based on prior documentation.

Tetris Zone uses an identical system internally for rotation calculation as that of Tetris Worlds, and I've just now verified that it uses the same offset lists that Tetris Worlds uses, by converting part of the semi-binary, decrypted .bpr files into the equivalent text used in Tetris Worlds for rotations, and comparing all their offset lists. I'm quite a ways off from converting the entire contents of the decrypted .bpr files into human readable/editable script files like Tetris Worlds TWS, however, but I may work towards that.

I can understand the rationale for Edo creating a more "familiar" description of SRS, because the concepts Blue Planet Software came up with are just so foreign to us.

12. ### Edoa.k.a. FSY

I've converted nightmareci's "offsets" for L,J,S,T,Z to the more familiar translations relative to basic rotation. They are in complete agreement with jago's analysis of ACE. I have no reason to doubt that Tetris Splash, etc, are identical as well:
Code:
J,L,S,T,Z Kick Data

(x,y) translation values are negated when rotating
back and forth between two states.

0->R  ( 0, 0):(-1, 0):(-1,+1):( 0,-2):(-1,-2)
R->0  ( 0, 0):(+1, 0):(+1,-1):( 0,+2):(+1,+2)

R->2  ( 0, 0):(+1, 0):(+1,-1):( 0,+2):(+1,+2)
2->R  ( 0, 0):(-1, 0):(-1,+1):( 0,-2):(-1,-2)

2->L  ( 0, 0):(+1, 0):(+1,+1):( 0,-2):(+1,-2)
L->2  ( 0, 0):(-1, 0):(-1,-1):( 0,+2):(-1,+2)

L->0  ( 0, 0):(-1, 0):(-1,-1):( 0,+2):(-1,+2)
0->L  ( 0, 0):(+1, 0):(+1,+1):( 0,-2):(+1,-2)

They're not that foreign; here's my attempt at a description:

The player can rotate 2 ways from each of the 4 orientations. That's 8 possible different rotations in total. A designer can assign values to the 8 rotations, and interpret these values directly as the kick translations; this is a concept that we are relatively familiar with.

Alternatively -- and this is what TTC chose to do -- a designer can assign values to the 4 orientations themselves, and derive the kick translations by taking the difference between these. For example, when rotating from A to B, subtracting B's values from A's will give the kick translation for the rotation one way; and subtracting A's values from B's will give the kick translation for rotating back the other way.

As an aside, it is clear that TTC's approach is less flexible: with their engine, it's impossible to implement independent kick translations for the forward and reverse rotations because they are inextricably linked; one is the negative of the other.

There is another complexity to TTC's implementation: the translations are defined relative to a different datum. We are more used to defining the kick translations relative to "basic rotation", but TTC uses what nightmareci has named "true rotation". "True rotation" is a pure rotation (in a mathematical sense) about the centre of an arbitrarily defined central block. The rotation centre must be at the centre of a block; it cannot be at the intersection of gridlines. This means that for "true rotation", the rotation centre for the O piece is not at the geometric centre, so the piece will have a "wobble" when rotated. The first kick translation has to be used to correct for this wobble.

13. ### nightmareci

Edo, I think a revised SRS wiki page should be based on your posts in this thread, as they are much easier to understand than my initial attempt. They are every bit as accurate as my description, but an implementation could support BPS, Arika and other SRS versions using your description as reference.

I may include my description as part of an explanation of Tetris Worlds TPF (That's the real script format name, .TWS is just used for TPF scripts in Tetris Worlds.) and Tetris Zone TPF2. (They updated the format somehow; I'm unsure in what ways.)

15. ### Muf

Fine by me. It looks really well written

16. ### colour_thief

It looks great! Well done Edo and nightmareci.

Here is the basic rotation of I:
Code:
 ..   .I   ..   I.
IIII ..I. .... .I..
.... ..I. IIII .I..
..   .I   ..   I.

After it fails, it tests the next rotation. Notice how the vertical position remains the same, but the horizontal position is aligned to the X block.
Code:
   .       X       .       I
XIII    I...    ....    I...
....    ...I    IIIX    ...I
.       I       .       X

The next rotation instead anchors to the opposite block.
Code:
   .       I       .       X
IIIX    ...I    ....    ...I
....    I...    XIII    I...
.       X       .       I

After the rotations so far fail, it will now align both the horizontal and vertical position to the block.
Code:
   .       .       .       I
.       .       .       I
.       .       .       I
...XIII ...X... IIIX... ...X...
.       I       .       .
.       I       .       .
.       I       .       .

And then it will try the opposite block.
Code:
   .       I       .       .
.       I       .       .
.       I       .       .
IIIX... ...X... ...XIII ...X...
.       .       .       I
.       .       .       I
.       .       .       I

When a beginner SRS player figures out the rotation rules of I, they will be able to contrive I-spins based on the rotations. Experienced players use I-spins as necessary, taking advantage of the dominant endpoint to build the right setup.

Last edited: 25 Aug 2021