Introduction

This movie improves 905 frames (15 seconds) off award-winning [3943] NES Arkanoid "warpless" by Chef Stef in 11:11.18

Software + Hardware

Rom Information

Rom: Arkanoid (U) [!]
  • SHA1: 230FC31D2C2EB20E78711C82574F29F28117EBA3
  • MD5: 0CCC1A2FE5214354C3FD75A6C81550CC

Emulator

  • EmuHawk 2.9.0 (Core: NESHawk)

Routing Bot

  • Bot: JaffarPlus
  • Routing Core: QuickNES
  • Platform: 'The Jaffanator' - AMD Ryzen Threadripper 3990X (64 cores, 128 threads) + 256Gb RAM (Average Exploration Performance: 1.2M States/s)

Comparison Movie & Timing


               Old           New          Diff
   Round     Initial Total Initial Total  Stage  Total
    Boot          0    566      0    566      0      0
     1          566    989    566    975    -14    -14
 Transition    1555    296   1541    296      0      0
     2         1851    826   1837    822     -4     -4
 Transition    2677    296   2659    296      0      0
     3         2973    605   2955    591    -14    -14
 Transition    3578    296   3546    296      0      0
     4         3874    759   3842    720    -39    -39
 Transition    4633    296   4562    296      0      0
     5         4929   1027   4858    956    -71    -71
 Transition    5956    296   5814    296      0      0
     6         6252    489   6110    489      0      0
 Transition    6741    296   6599    296      0      0
     7         7037    622   6895    605    -17    -17
 Transition    7659    296   7500    296      0      0
     8         7955    249   7796    266     17     17
 Transition    8204    296   8062    296      0      0
     9         8500    508   8358    508      0      0
 Transition    9008    296   8866    296      0      0
     10        9304    697   9162    697      0      0
 Transition   10001    296   9859    296      0      0
     11       10297   1478  10155   1463    -15    -15
 Transition   11775    296  11618    296      0      0
     12       12071    625  11914    625      0      0
 Transition   12696    296  12539    296      0      0
     13       12992    475  12835    461    -14    -14
 Transition   13467    296  13296    296      0      0
     14       13763    747  13592    747      0      0
 Transition   14510    296  14339    296      0      0
     15       14806   1353  14635   1223   -130   -130
 Transition   16159    296  15858    296      0      0
     16       16455    579  16154    551    -28    -28
 Transition   17034    296  16705    296      0      0
     17       17330    694  17001    657    -37    -37
 Transition   18024    296  17658    296      0      0
     18       18320    626  17954    545    -81    -81
 Transition   18946    296  18499    296      0      0
     19       19242    671  18795    624    -47    -47
 Transition   19913    296  19419    296      0      0
     20       20209    521  19715    521      0      0
 Transition   20730    296  20236    296      0      0
     21       21026    444  20532    444      0      0
 Transition   21470    296  20976    296      0      0
     22       21766    536  21272    536      0      0
 Transition   22302    296  21808    296      0      0
     23       22598   1266  22104   1292     26     26
 Transition   23864    296  23396    296      0      0
     24       24160    892  23692    883     -9     -9
 Transition   25052    296  24575    296      0      0
     25       25348   1181  24871   1104    -77    -77
 Transition   26529    296  25975    296      0      0
     26       26825    732  26271    732      0      0
 Transition   27557    296  27003    296      0      0
     27       27853   1457  27299   1404    -53    -53
 Transition   29310    296  28703    296      0      0
     28       29606    772  28999    726    -46    -46
 Transition   30378    296  29725    296      0      0
     29       30674   1448  30021   1268   -180   -180
 Transition   32122    296  31289    296      0      0
     30       32418   1259  31585   1221    -38    -38
 Transition   33677    296  32806    296      0      0
     31       33973   1013  33102   1013      0      0
 Transition   34986    296  34115    296      0      0
     32       35282    764  34411    748    -16    -16
 Transition   36046    296  35159    296      0      0
     33       36342   1113  35455   1113      0      0
 Transition   37455    296  36568    296      0      0
     34       37751    703  36864    703      0      0
 Transition   38454    296  37567    296      0      0
     35       38750    612  37863    604     -8     -8
 Transition   39362    296  38467    296      0      0
     36       39658    678  38763    668    -10    -10
 Last Input   40336     85  39431     76     -9   -905
 Boss Dies    40421         39507                 -914

Explanation

I have a lot of respect for the incredible work that both Chef Stef (and Baxter) did in the previous movies. We all took very different routes and improved on each other. Not much can be added to their detailed explanations, except to talk about what I did differently.
Although I use a bot, I take different approach than Chef Stef:
  • They built a C-based reverse engineered version of the game, yielding enourmous speedups compared to a using a lua on top of bizhawk. My approach, simply compiling my bot against quickNES (C++) is a bit less sophisticated, but by no means slow. The fact that it took them a year of execution on a 6-core machine but took me a month to do this one on a 64-core machine gives an idea of the relative performances.
  • They built a decision tree based on the 8 possible angles a ball can take, I went full brute, allowing any x position for the paddle when a ball is in the 'hittable' layer. To compensate for the impossibly large exploration space, I pruned the action space to either pressing "L" or "R" -- standing still was not an option. This paid off pretty nicely, I must say.
The main difficulty during making this movie was the bonus score screen. After finishing some levels, you get 'punished' with extra score -- I believe this has to do with the amount of enemies you killed, but so far haven't been able to decode it (nor did I spend much time to research it either).

Future Work

Before starting this project I tried to get in contact with Chef Stef via DM (and Discord). I had no luck, but also didn't try any further. This is the thing: their approach to this game and mine are not entirely mutually exclusive; if we were to join forces in the future, we could even be talking about optimality here.
So here it is: Chef Stef, if you are reading this, HMU and let's kill this game once and for all.

Re-Record Count

The re-record (load state, change input, advance state) count of this movie is: 2,529,914,332,046. I'd like to ask for this value be properly represented in the publication. I'll keep the execution logs for a while if someone wants to check them out.

nymx: Claiming for judging.

nymx: I am simply amazed! I really thought Chef_Stef ended this game. 15 seconds is a HUGE deal and I congratulate you on this outstanding work!
It was also nice to see how you took a different approach. You are truly one of the great BOTers of this community.
I'm following suit, as with the past submission, by accepting this version to "Stars" for publication!
fsvgm777: Processing.
feos: Cleared rerecords so they show up as unknown looks like the new site doesn't have this logic that we got used to on the old site...


TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15629
Location: 127.0.0.1
This topic is for the purpose of discussing #8315: eien86's NES Arkanoid "warpless" in 10:56.12
Editor, Active player (459)
Joined: 2/11/2018
Posts: 240
Wow, awesome. Jaffar can't be stopped.
This is the thing: their approach to this game and mine are not entirely mutually exclusive; if we were to join forces in the future, we could even be talking about optimality here.
Would that be using a brute forcer on the simulated version of the game?
eien86
He/Him
Judge, Skilled player (1881)
Joined: 3/21/2021
Posts: 262
Location: Switzerland
Randomno wrote:
Would that be using a brute forcer on the simulated version of the game?
Exactly, but also using some of their optimizations as well.
XYZ
Former player
Joined: 12/9/2006
Posts: 168
Location: 2bastuz
Problem of three bodies solved. Yes vote.
PLANET
He/Him
Joined: 1/3/2018
Posts: 74
Very wholesome TAS, if one can call them like that. Yes vote : )
Post subject: Incomplete simulation in 3943M?
Sand
He/Him
Player (143)
Joined: 6/26/2018
Posts: 175
Great work. I am a big fan of this kind of TAS optimization. I appreciate the comparison video.
eien86 wrote:
They built a decision tree based on the 8 possible angles a ball can take, I went full brute, allowing any x position for the paddle when a ball is in the 'hittable' layer.
It's not clear to me why these two approaches should produce different output—unless the simulation in [3943] NES Arkanoid "warpless" by Chef Stef in 11:11.18 made an unjustified assumption somewhere and was not completely representative. Do you have a feeling for what the difference might be? For example, is it true that there are exactly 8 possible angles, or did JaffarPlus find a possibility that the simulator in 3943M did not? I suppose the best explanation would come from re-running the simulator from 3943M on a round where the strategies differ, find the point at which the simulator considered (a prefix of) the particular strategy used in this submission, and then figure out why that strategy was rejected. Or, if the simulator never considered the strategy used in this submission, find out what prevented it from exploring that part of the input space. Or does it come down to different scores resulting in different RNG outputs? Round 24 is a good example. As far as I can tell, the ball launch and ball movement are identical, up until this submission collects the multiball powerup 1 or 2 frames earlier. But according to #6347: Chef_Stef's NES Arkanoid "warpless" in 11:11.18, variable delay before collecting a powerup was one of the things considered by the simulator. ("There's a 10-frame window where the powerup is collect-able. Collecting it on different frames lets us manipulate when the single ball turns into a multiball, which affects how each ball can be bounced after that.") So why did the earlier simulator not find the faster solution found here? In Round 32, this submission loses a ball, while 3943M pruned any path that lost a ball. That's one concrete difference that could affect optimization, but it doesn't come into play in every round.
eien86 wrote:
The main difficulty during making this movie was the bonus score screen. After finishing some levels, you get 'punished' with extra score -- I believe this has to do with the amount of enemies you killed, but so far haven't been able to decode it (nor did I spend much time to research it either).
It took me a while to realize that the score tally is what makes Round 23 slower. This submission clears all the blocks more than a second faster than 3943M, but the score tally makes it slightly slower overall. The old 3943M actually earns more points than this submission does (77220 versus 77020, because of 1 additional enemy kill I believe). My impression is that this round is score-limited rather than block-limited: 3943M breaks a few more blocks early and then takes time to clean up the rest, but that extra time is mostly "free" because it has to wait for the score to catch up anyway; whereas this submission starts slower and then breaks a large burst at the end, so less of the score tally runs concurrently with gameplay.
nymx
He/Him
Editor, Judge, Expert player (2255)
Joined: 11/14/2014
Posts: 933
Location: South Pole, True Land Down Under
You blow me away. I thought that Stef Chef ended this for good. It is amazing to hear that it could go even further. I applaud you on this effort. Yes vote!
I recently discovered that if you haven't reached a level of frustration with TASing any game, then you haven't done your due diligence. ---- SOYZA: Are you playing a game? NYMX: I'm not playing a game, I'm TASing. SOYZA: Oh...so its not a game...Its for real? ---- Anybody got a Quantum computer I can borrow for 20 minutes? Nevermind...eien's 64 core machine will do. :) ---- BOTing will be the end of all games. --NYMX
Post subject: Score increment tally
Sand
He/Him
Player (143)
Joined: 6/26/2018
Posts: 175
Sand wrote:
My impression is that [Round 23] is score-limited rather than block-limited: 3943M breaks a few more blocks early and then takes time to clean up the rest, but that extra time is mostly "free" because it has to wait for the score to catch up anyway; whereas this submission starts slower and then breaks a large burst at the end, so less of the score tally runs concurrently with gameplay.
Here's a picture of what I mean. I wrote a Lua script to record, for each frame, the number of blocks remaining (called remainingBlocks in jaffarPlus, blue in the graph), as well as the 6-element array at 0x037c..0x0381 that represents the score increment; i.e., that points that are waiting to be tallied into the player's score (orange in the graph). Even though 3943M takes longer to break all the blocks, it is overall slightly faster. By breaking blocks at a slower, but more consistent rate, it keeps the score increment more under control. The maximum score increment in Round 23 in 3943M is 13010; here in 8315S it is 33040. The way scoring works is, when you earn points, they don't go directly into your score (the 6-element array at 0x0370..0x0375). Instead the points go into the score increment, and from there they move into your score, a little each frame. Here's an excerpt of the CSV log from 3943M to show how the transfer works:
frameroundremaining_blocksp1_scorescore_increment
2006263007820000470
2007263007830000460
2008263007840000450
2009263007850000440
2010263007860000430
2011263007870000420
2012263007880000410
2013263007890000400
2014263007990000300
2015263008090000200
2016263008190000100
2017263008290000000
The score increment counts down by tens as long as the tens digit is nonzero, then it counts down by hundreds until the whole thing is zero. So, for example, an increment of 1350 takes 13 + 5 = 18 frames to tally into the player's score. A side effect of this method is that sometimes earning points can decrease the amount of time it takes to tally the score increment. For example, an increment of 250 takes 7 frames to tally, whereas an increment of 300 takes only 3 frames. I don't know the internals of jaffarPlus, but would it make sense to add something like scoreIncrement/100 + scoreIncrement/10%10; into the reward in getStateReward, to make the bot take score increment tally delay into account?
eien86
He/Him
Judge, Skilled player (1881)
Joined: 3/21/2021
Posts: 262
Location: Switzerland
Sand wrote:
Sand wrote:
My impression is that [Round 23] is score-limited rather than block-limited: 3943M breaks a few more blocks early and then takes time to clean up the rest, but that extra time is mostly "free" because it has to wait for the score to catch up anyway; whereas this submission starts slower and then breaks a large burst at the end, so less of the score tally runs concurrently with gameplay.
Here's a picture of what I mean. I wrote a Lua script to record, for each frame, the number of blocks remaining (called remainingBlocks in jaffarPlus, blue in the graph), as well as the 6-element array at 0x037c..0x0381 that represents the score increment; i.e., that points that are waiting to be tallied into the player's score (orange in the graph). Even though 3943M takes longer to break all the blocks, it is overall slightly faster. By breaking blocks at a slower, but more consistent rate, it keeps the score increment more under control. The maximum score increment in Round 23 in 3943M is 13010; here in 8315S it is 33040. The way scoring works is, when you earn points, they don't go directly into your score (the 6-element array at 0x0370..0x0375). Instead the points go into the score increment, and from there they move into your score, a little each frame. Here's an excerpt of the CSV log from 3943M to show how the transfer works:
frameroundremaining_blocksp1_scorescore_increment
2006263007820000470
2007263007830000460
2008263007840000450
2009263007850000440
2010263007860000430
2011263007870000420
2012263007880000410
2013263007890000400
2014263007990000300
2015263008090000200
2016263008190000100
2017263008290000000
The score increment counts down by tens as long as the tens digit is nonzero, then it counts down by hundreds until the whole thing is zero. So, for example, an increment of 1350 takes 13 + 5 = 18 frames to tally into the player's score. A side effect of this method is that sometimes earning points can decrease the amount of time it takes to tally the score increment. For example, an increment of 250 takes 7 frames to tally, whereas an increment of 300 takes only 3 frames. I don't know the internals of jaffarPlus, but would it make sense to add something like scoreIncrement/100 + scoreIncrement/10%10; into the reward in getStateReward, to make the bot take score increment tally delay into account?
Wow, thanks so much for doing this research. I didn't know this tally mechanism existed and is what caused the delay at the end of the stage (and for some egregiously so). I'll try to factor this into the reward function next time. Hopefully that will push the bot to pursue solutions that, albeit slower in the destruction of blocks, leads to an earlier tally finish.
fsvgm777
She/Her
Senior Publisher, Player (226)
Joined: 5/28/2009
Posts: 1217
Location: Luxembourg
eien86 (submission notes) wrote:
The re-record (load state, change input, advance state) count of this movie is: 2,529,914,332,046. I'd like to ask for this value be properly represented in the publication. I'll keep the execution logs for a while if someone wants to check them out.
Typically, we don't include botted re-record counts and we just put "Unknown" as the re-record count in such cases. We also have an ongoing topic about tracking re-record counts, where no conclusion was reached thus far. Are you fine with me mentioning an unknown re-record count in this case as well?
Steam Community page - Bluesky profile Oh, I'm just a concerned observer.
eien86
He/Him
Judge, Skilled player (1881)
Joined: 3/21/2021
Posts: 262
Location: Switzerland
fsvgm777 wrote:
eien86 (submission notes) wrote:
The re-record (load state, change input, advance state) count of this movie is: 2,529,914,332,046. I'd like to ask for this value be properly represented in the publication. I'll keep the execution logs for a while if someone wants to check them out.
Typically, we don't include botted re-record counts and we just put "Unknown" as the re-record count in such cases. We also have an ongoing topic about tracking re-record counts, where no conclusion was reached thus far. Are you fine with me mentioning an unknown re-record count in this case as well?
Yes, that's ok. Perhaps it's better to continue the discussion in that thread than here.
Post subject: Movie published
TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15629
Location: 127.0.0.1
This movie has been published. The posts before this message apply to the submission, and posts after this message apply to the published movie. ---- [5327] NES Arkanoid "warpless" by eien86 in 10:56.12