Posts for xy2_


Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Link to video Input Lua This is the first WIP of Shaman King 2, but done much better than my previous attempts. Although you may say the rerecord count is low, it is like this because I have perfect knowledge of the early game at this point. Quite a lot is going on, but I'll save the detailed commentary for later and point out some important things. I pick up Magnescope. Like in SK1, it is available very early on and breaks most of the game, because it's OP as shit. In this game, any soul activation will cancel the vast majority of states Yoh can be in (excluding backdashing, and being in a soul; as in, you can't activate a soul while attacking with a soul already). Magnescope is very useful for this because it costs 2 furyoku (=mana), and can be activated for a very short amount of time (1 frame). This is how I do the attack cancels on bosses. But boss fights are a bit deeper than just "cancel with Magnescope and attack as fast as possible". Take, for example, the first boss fight, Mikihisa (at 1:37.) At the end of a boss fight, both Yoh's health and furyoku bars are filled up, wasting 1 frame for each wasted mana/furyoku (the game refills both at the same time). So, to avoid wasting furyoku, I only do cancels every third strike, since the invicibility time from normal attacks is 16 frames, and the three-strike combo attacks more frequently than 16 frames. Another thing to pay attention to is boss death. When a boss dies, he is sent up high in the air (the knockback is the same as when Yoh takes large knockback.) However, the game only goes on once the boss hits the ground. As such, it is needed to optimise the boss position so that he falls to the ground as fast as possible. Here, I manipulated Mikihisa to teleport to the red structure again, so that the kill would make him land directly behind (this was the fastest option.) Once I get the leap, I do a movement technique unique to SK2: leap-chaining. The leap is surprsingly fast, and its speed is supposed to be negated by slowing you down significantly. However, once Yoh hits the ground, it's simply possible to cancel with a Magnescope, and initiate another leap. At 2:55, in the factory segement, I make a significant skip. This level is another "backtrack" level that you can only use once you have the soul of the boss: the wall is too high to just reach with a normal jump, and jumping from the platform to the right does not reach. But with a well-placed damage boost on the jumping enemies, Yoh gains just enough height and speed to land on the platform. The jumping ennemies' movement are fixed, so I just play around. This skips a very long boss and some level, saving around ~2 minutes. You might wonder why I didn't chain leaps at the second phase of Eliza (6:05). The first thing to catch is when I leap against Eliza, I actually hit twice! For some reason, the leap has three states: the initial leap, then a 1-frame phase (that I call "brandish") and then another phase. I assume the brandish state is used to determine whether Yoh should stop or not when leaping (Yoh's speed goes to 0 if he encounters an enemy while leaping.) But, if you hit while in this state, then the enemy takes damage without the 8 frame flash! Normally, chaining leaps would be slower, because even if it deals more damage, the flashes make it slower in realtime. But with this trick, leaps become faster. So then, why didn't I chain these brandish hits+leap hits? The reason is that after each leap, I need to return to a specific position to be able to hit the brandish leap. It turned out I didn't have enough time to return to the position without the invicibility of Eliza not wearing off (which means I could have hit her in the time I get back to position. So, instead of doing brandish, leap, then walk back and return, I first do a brandish hit, leap hit, then when landing, jump and do a double slash while the jump carries me back to a position to do a brandish hit. There are a lot more things, of course, but this post is already long. I also made some improvements to the Lua (most notably RNG viewer, and something allowing me to view when a soul activation will trigger a cutoff/splash), but I'm lazy to screenshot it.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
When trying to download a file from a code tag via an user's profile, the file will get truncated to whatever the post preview shows. Example: go on my profile, and try to download the script in this post; Download test.sh
Language: shell

When trying to download a file from a code tag via an user's profile, the file will get truncated to whatever the post preview shows. Example: [url=http://tasvideos.org/forum/realsearch.php?search_author=xy2_]go on my profile[/url], and try to download the script in this post; When trying to download a file from a code tag via an user's profile, the file will get truncated to whatever the post preview shows. Example: [url=http://tasvideos.org/forum/realsearch.php?search_author=xy2_]go on my profile[/url], and try to download the script in this post; When trying to download a file from a code tag via an user's profile, the file will get truncated to whatever the post preview shows. Example: [url=http://tasvideos.org/forum/realsearch.php?search_author=xy2_]go on my profile[/url], and try to download the script in this post; When trying to download a file from a code tag via an user's profile, the file will get truncated to whatever the post preview shows. Example: [url=http://tasvideos.org/forum/realsearch.php?search_author=xy2_]go on my profile[/url], and try to download the script in this post;
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
In this post I will describe how I found the RNG and implemented it in Lua on a game I was working on. This post is written in this way, and not in an authoritarian tone because first of all, this is the first time I did this and I don't pretend to dictate others with what little knowledge I have, and second because this is hardly the sort of thing where you can follow a manual and have it work out with streamlined instructions. Also, please note that this does not really require intense programming skills: I had no actual experience with programming before I started this, and I only started writing Lua when working on the script for my game. I think the only things that would be required for this is a strong sense of intution (as in, to be able to figure things out easily), good willpower and some familiarity with concepts of how a computer works. Shoutouts to people who helped me along this two-day endeavor: Masterjun, Warepire, ThunderAxe31, feos, Scum, Scepheo, etc. Also, I want to give a link to the Reverse Engineering page here, which is quite helpful for an introduction to a few concepts. Part I: Figuring out the RNG's adress So I was working on a GBA game, Shaman King 2, and I was kind of in a rut; I was in the third boss fight, but, unlike the first two that I had manipulated perfectly, this one required much more precise manipulation. Then I thought: Why not try to figure out the RNG? This way, I would be able to predict it, and as such, predict and manipulate boss attacks. The first thing is figuring out where the RNG is actually predicted. To do this, I used cross-branch RAM search, using BizHawk. How does it actually work? First, find an action that will seem to change the outcome of what happens next (thus manipulating the RNG): in my case, it was attacking. Then, make two branches using TAStudio, that are the exact same in movement, etc, except for one branch where you insert the action that advances RNG and one branch where you don't. Now, set your two branches at the same frame (after the action that advances RNG), open RAM search, set the search to "not equal to" and "previous value", then switch between the two branches. Now, you should have a list of adresses that differ between the two branches of the same frame. Finally, select all those adresses, then click Search > Add to RAM watch. You should have quite a few adresses now: we will do a bisect to find the correct one(s). What you want to do is switch to a branch, then freeze half the adresses in RAM watch. Switch to the other branch. If the game behaves the same way as it did on the other branch (eg. boss behaves the same way) then you've frozen the RNG adress(es) and can delete the other half. If not, delete the half you've frozen. Repeat until you find the adresses. Using this method, I was able to find the good adress: 0x16C0. But, how does it actually work? Time to disassemble! Part II: Disassembly of the game Sounds scary? Well, it kind of is; we're basically going to the "lowest level" just above machine language: assembly language (which I'll abbreviate as asm for the rest of the post). Assembly is, from my understanding, basically a glorified macro language. To do this, you will need an emulator that supports disassembly: I used no$gba. (Note: you can do all of this in a much easier way, in the case of the GBA, simply by switching to the vba-next core in Bizhawk and using the provided debugger and trace logger.) Because the platform of the game is GBA, these instructions are gonna be biased towards it. In any case, you will need a lot of information about your platform. The main ones I used for this part were gbatek, along with the ARM reference center whenever I needed more info about an instruction. Now, I already had my adress, so in no$gba's disassembler I put a breakpoint at that adress: first rightclick the bottom window, go to break/watch window, then Define Breakpoint and set the breakpoint. A breakpoint will halt execution whenever the condition is reached: here I set a breakpoint whenever the adress 0x16C0 was written to in IWRAM, so: "[030016C0]!" will trigger on write. You might be saying that my adress was 0x16C0, so why was the value I specified 0x030016C0? That's because the IWRAM section starts at 0x03000000 in memory:
  00000000-00003FFF   BIOS - System ROM         (16 KBytes)
  00004000-01FFFFFF   Not used
  02000000-0203FFFF   WRAM - On-board Work RAM  (256 KBytes) 2 Wait
  02040000-02FFFFFF   Not used
  03000000-03007FFF   WRAM - On-chip Work RAM   (32 KBytes)  
  03008000-03FFFFFF   Not used
  04000000-040003FE   I/O Registers
  04000400-04FFFFFF   Not used
Then after that, I made the RNG advance to trigger the breakpoint (by attacking, since that advanced RNG.) After some time, I found this subroutine (note that subroutine=function):
Language: armasm

ROM:0800F904 PUSH {LR} ; Link register is register 14 ROM:0800F906 MOV R1, R0 ROM:0800F908 LDR R3, =0x30016C0 ; IWRAM 0x16C0 into r3 (adress of RNG) ROM:0800F90A LDR R2, [R3] ; Loads the previous value of the RNG into R2 ROM:0800F90C LDR R0, =0x41C64E6D ; Multiply by 0x41C63E6D ROM:0800F90E MUL R0, R2 ; stores only the least significant bits; modulo 32 ROM:0800F910 LDR R2, =0x3039 ROM:0800F912 ADD R0, R0, R2 ; Add 0x3039 ROM:0800F914 STR R0, [R3] ; Store result into adress of r3, 0x16C0
I commented it a bit here, so it should be easy to understand, and it's a pretty simple RNG. In english, what this subroutine does is that it first reads the previous value of the RNG, multiplies it by 0x41C64E6D and only keeps the least 32 significant bits; modulo 32 (if the value after multiplying was 0x273219DA6F3, then the value of r0 would be 0x219DA6F3), then adds 0x3039 to it, and writes it to the RNG adress. If it sounds familiar, that's because it is a linear congruential generator. (Bonus: this is actually the most common RNG in history! Try converting 0x41C64E6D to decimal..) If you want to check that your analysis of the RNG is correct, then, open up your emulator with RAM watch on the RNG adress, then try predicting the next RNG value (using a hex calculator.) If your result matches up with the next RNG value, then you've grasped it. Note that even if it doens't match, the RNG can advance multiple times per frame! So, at some times your first calculation may not match up with the actual RNG value. This is why it's convenient to have an RNG table of values, so that we can check how much the RNG advances per frame, and also to get the next RNG values. Part III: Lua implementation Since we now understand how the RNG works, we can reimplement it in a simpler programming language. Lua is the standard scripting language for the entirety of TAS emulators, including BizHawk. Since you can interact with the emulator with it, we'ill be using it in order to reimplement this subroutine in Lua. Unfortunately, I ran into a roadblock here, which was that Lua numbers in 5.1, the version in Bizhawk, are double precision floating point and can only represent numbers accurately up to 53 bits, after which they were rounded: see this post and the following. After solving this, I had a nice implementation:
Language: lua

-- SK2 rng re-implementation in Lua --############################################################################# local function RngLua(value) --############################################################################# local high = (value * 0x41C6) % 0x10000 local low = (value * 0x4E6D) % 0x100000000 return ((low + high * 0x10000) % 0x100000000) + 0x3039 end
This was a function that calculates the next RNG value based on the current one. Mission complete! The only thing left is to expose that to the TASer (me) in a friendly way, and so I wrote a function which would display the next RNG values, as well as a counter (to see how much the RNG changed per frame, if it changed) and a visual indicator (to see where was the position of the rng was in the table before)
Language: lua

-- Displays a table of the next X rng values, based on current RNG --############################################################################# local function RngPredict(x,y,number) --############################################################################# local RNG = memory.read_u32_le(0x16C0, "IWRAM") -- Display the number of steps the RNG has advanced, if it advanced pastRNG[2]= pastRNG[1] pastRNG[1]= RNG if pastRNG[2] ~= pastRNG[1] then for i=1,number do if RNG == rngResults[i] then gui.pixelText(x+33,y, i, 0xFFFFFFFF, color.trans[6]) gui.pixelText(x+33,y+i*7, "!", 0xFFFFFFFF, color.trans[2]) end end end gui.pixelText(x,y, string.format("%08X", RNG)) rngResults[1] = RngLua(RNG) for i=1,number do rngResults[i+1] = RngLua(rngResults[i]) gui.pixelText(x,y+i*7, string.format("%08X", rngResults[i])) end end
And what the result looked like, because this post is severely lacking in cool images - RNG predictor on the left: And that's it. I hope this can help anyone who is trying to find RNG in their games. Please point out if there is misinformation in this post (there probably is).
Post subject: Dealing with big numbers (base16 version)
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
I have disassembled an RNG subroutine and am trying to re-implement it in Lua. The hard part is this MUL instruction (I put the ones above for context, platform is GBA):
Language: asm

ROM:0800F908 LDR R3, =0x30016C0 ROM:0800F90A LDR R2, [R3] ROM:0800F90C LDR R0, =0x41C64E6D ROM:0800F90E MUL R0, R2
A small explaination: First it reads from the RNG adress, then multiplies it by 0x41C64E6D, and keeps the last 32 significant bits. So if the value after multiplying was 0x273219DA6F3, then the value of r0 would be 0x219DA6F3. I tried to re-implement this in Lua, but my problem is that the numbers in Lua don't have enough precision to deal with such large values. And I don't need to be able to only get the result of the multiplication, but also to be able to get the last 32 bits. So I tried with a library Masterjun recommended me, BigNum, and it somewhat works but it's old (when I renamed some function which was needed for it to run, it gave me a wrong result for multiplication) Would there be any way to implement this?
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Rename your file extension to a .zip, then try to open it. I'm going off intution here because this also happened to me, but only the greenzone is broken (and thus not your entire file.) However, even if this is broken, you can recover the other files, and thus rebuild a tasproj with the files from your archive: either remove the greenzone, or create a new zip with the intact other files from the tasproj, then rename the extension from a zip to tasproj.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
https://files.tasvideos.org/2095/DeSmuMe-Movie-Editor.7z To be used with desmume 0.9.9 or the upscaling builds. Originally made by Suuper, see http://tasvideos.org/forum/viewtopic.php?p=457373#457373 Not really what you are looking for, but the closest thing to it that exists.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
When downloading an Unix shell script from tasvideos which was created with the code tag and a .sh extension (eg code=shell.sh, once downloaded, the shell script is unusable because it uses Windows newlines (\r\n). Example below: Download test.sh
Language: shell

echo "TASVideos rocks!"
The blank line is on purpose. Output:
$ ./test.sh 
./test.sh: line 1: $'\r': command not found
TASVideos rocks! 
$
Using hexdump -c on the file we get:
0000000  \r  \n   e   c   h   o       "   T   A   S   V   i   d   e   o
0000010   s       r   o   c   k   s   !   "  \r  \n  
As mentioned in IRC you can do tr -d "\r" on the file to remove the carriage returns but this is not really the best solution.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
User movie #41143656436330001 This is the first 29 minutes of the game! (I'm not doing an encode for this WIP, will do on an next one.) So, the reason I picked SK1 in the first place was to ward off my anger at losing at bunch of progress on SK2, and also to improve my epic lua l33t skills. But, there's an issue with tasing SK1; it's that tasing the first half of it is incredibly repetitive and tenuous. The game has very serious pacing issues; we are about 30 minutes in, and Yoh is still walking around with very few souls, and has only beaten four bosses.. More specifically, the weakness of SK1's design is in backtracking. Once you complete an area, you can't just skip it when you come back to it; you have to redo the entire area again, but backwards. Here this backtracking segment is particulary bad, because to get the five souls we need we have to backtrack through 3/4 of the entire game so far, with nothing more than a few more subpixels of movement speed, and a sword that deals 20 damage instead of 10.. Probably I will come back to this again when I'm less tired of it, but I'm going to rework on SK2 again for a while now.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Post subject: On horses and loading screens
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
So I was like "Let's TAS some AC:AC today, it's been a while!" then I found a really dumb timesaver. Basically, in the loading zones where Altaïr walks on the minimap from one point to the other on a horse, guess what happens if you press A? Well, the transition goes away early! This saves 126 frames on the spot I tried it; it would probably save 14 seconds alone on the entire run if I applied this on loading zones where this happens. The downside is that this is AC:AC, the laggiest game of history, and given that this game desyncs very easily, I don't really want to redo the entire run for a second-scale save on not even gameplay but loading screens!! So I guess I'll finish the run, but this alone has taken a pretty significant toll on my morale, especially considering I will start doing the skip starting at the middle of the game, for no other apparent reason than "the TASer is lazy and doens't want to redo his run." But given this game, and how long it is, I think I just want to finish it at this point, not spend a shitton of time "resyncing" (redoing) it. And maybe put some flashy disclaimers at the top that it's totes unoptimised and all the run should go to shit for some loading screens…
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Also, to follow this idea, we need something like a Translation module, to show available languages for each page, as well as the language you are currently on. The way it is done now, the WelcomeToTasVideos page has a small header, in plaintext, linking to other languages; but this will get tedious to update if much more languages are added, since you will need to edit that header for every single page translation as well.
Post subject: High quality temp encode script, Linux ver.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Pokota's temp encode script was pretty helpful, so I made this linux version in about 15 minutes. Render the script executable; run [chmod +x "script name"] in your terminal, and run it to see the syntax. Requires only ffmpeg. (I made this because there is no real easy way to run AviSynth under linux, as far as my search went, and I didn't want to mess around with complicated stuff for temp encoding when you have ffmpeg..) Download encoding.sh
Language: shell

#!/bin/sh # Linux version by xy2_ # Original script by Pokota at http://tasvideos.org/forum/viewtopic.php?p=451051#451051 usage() { cat >&2 << EOF High-quality temp-encode script Usage: $0 -i input -s scale [-u subtitle] -o output -i | --input : Input filename. -o | --output : Output filename. -s | --scale : Upscaling factor (usually factor of 2) -u | --subtitle : Subtitle file (if required.) EOF exit } die() { echo "Encode failed!" exit 1 } [ "$#" -lt 6 ] \ && usage while [ "$#" -gt 1 ]; do case "$1" in -i|--input) INPUT=$2 ;; -o|--output) OUTPUT=$2 ;; -s|--scale) SCALE=$2 ;; -u|--subtitle) SUB=$2 ;; *) usage;; esac shift 2 done if [ -z "$SUB" ]; then ffmpeg -i "$INPUT" -sws_flags neighbor+full_chroma_inp -c:v libx264 -crf 20 -bf -1 -b_strategy 2 -force_key_frames 00:00:00.000 -pix_fmt yuv420p -c:a aac -b:a 192k -vf scale="$SCALE"*iw:-1 "$OUTPUT" || die else ffmpeg -i "$INPUT" -sws_flags neighbor+full_chroma_inp -c:v libx264 -crf 20 -bf -1 -b_strategy 2 -force_key_frames 00:00:00.000 -pix_fmt yuv420p -c:a aac -b:a 192k -vf subtitles="$SUB" -vf scale="$SCALE"%*iw:-1 "$OUTPUT" || die fi
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Progress is doing well, since my workflow is going a lot faster now that I have my lua script finely tuned, and things which used to take a lot of rerecords take a lot less. Even after making the script, I severly underestimated just how much faster it makes my work. (The downside is that it is pretty intensive, and I can't run it at full speed on my laptop.) Currently, I am 21 minutes into the game, I'd say about a third of the game is done; I was going to publish a WIP soon, but then I found this skip: https://youtu.be/Yo64condyP4 Looks trivial? Well, this saves 6 minutes (!!!!) because it skips an entire area. Here's a map for visualisation: A few seconds before this, I am on the orange spot circled on the map, and I want to reach Silva in area 5. Now, the intended order is to clear the whole zone (going through 2,3,4 before reaching area 5, marked with red.). But a quirk of this game is that it offers "shortcut" areas to avoid going back through the entire zone, after beating a boss. In this case, it's the area 6, marked here with a blue road. Now, these "shortcuts" areas are usually impossible to pass through until you complete the area, and this is ensured in various ways- missing soul (that you get by beating the boss of that area), or one-way passthrough. But, if it was possible to pass through these shortcuts areas, then we could skip the entire zone and get almost directly to the boss. In this skip, this is exactly what happens. The way this particular zone is blocked off is a combinaison of both. There's a jump here that's supposed to be impossible until you get Mic, which allows to make jumps with much higher speed. But if you take the area in the intended way (from left to right, as opposed to from right to left in the skip) you can also fall down and be unable to get back up, but have succesfully taken the shortcut; a one-way passage. But, what if I tried to do a normal jump, instead of the boosted jump that you're supposed to do? Well, it would turn out that I was off by a few hundred subpixels. So, as I said in IRC:
xy2_    it's a jump that's barely reachable by some subpixels, so I got some more subpixels and it worked
First, I needed to grind as much subpixels that I possibly could (without losing too much time.) Yoh's normal movement speed is 464 subpixels at this point in time (as I've gotten one movement soul.) Of course, that's a lot; hovewer, I could fine tune my movement using groundsliding; after I release input, Yoh keeps sliding for a few frames, gradually losing speed. Here it is very advantageous, as I could get to extremely low speeds in terms of subpixels. This is the movement you see at the start, when I move right, then left. I end up with the initial X position of 613509 subpixels (less is better) - the end of the platform is located at 613500, so to get this close without a ton of manipulation was surprising. The heavy lifter for getting the rest of the subpixels is the flipping glitch, that I explained earlier in the thread, but that I'll explain here again: When Yoh is in the air, as long as you hold the directional input that's the same in relation to his speed (eg. left if Yoh is going leftwards) then Yoh will maintain his speed as long as he's in the air. The cap of the jump's speed is 448; however, if I leave a blank input for one frame, then speed goes like this: 448 > 432 (-16) > 464 (+32) > hold.. Yoh actually gains an excess of acceleration on the first frame he starts to accelerate, and as such I get an extra 16 subpixel per frame on the jump. (This is used on almost every jump in the TAS, by the way.) This gave me enough subpixels to jump the jump, and it reaches so easily you'd almost think it's the intended route. And as such, I skip almost one entire zone (I have to go back a little bit later due to route woes, but it still saves a shitton of time because the levels here are absurdly long.)
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
So, since this WIP, I've catched a few errors and reworked this segment. SK is rather sync friendly, except for bosses which are very RNG dependant. We don't have many spots to manipulate RNG ahead of time, and manipulating during boss fight is easily the hardest thing in the entire game, so I'll be stuck on this for quite a while. Here is the current lua, and the current input, as well as a picture of what it looks like atm (still incomplete): In terms of actual route and discoveries, what changed? * I picked up Magnescope (soul), by far the biggest route improvement. I am ashamed of myself for missing this one; it allows to cancel effectively every state (except backdashing), which is extremely useful for combat. With Magnescope, you can pump enemies without even letting them one frame of non-invinicibilty in the best-case scenario. * I pick up Vodianoi later on, which allows unrestricted movement in water (instead of more than halving your speed, keeps it as-is). Useful for Area 2 backtracks and for the area just before Lee-Pai Long which is filled with water. * Strategies on the Rio fight: thanks to Magnescope, we can keep up a decent combo without getting hit: three slash > Magnescope > single slash > magnescope > crouch slash when Rio attacks. Crouching allows us to lower our hitbox enough, and attacking on the first frame we crouch brings us to the crouch slash state instantly, giving us greater flexibility. * Thanks to my hitbox script, I noticed that Rio hitbox will extend towards us a significant amount when he does his crouch attack. If we need to take damage to manipulate RNG, this is very useful (as hits from contact damage with Rio do 7 damage, instead of 9 from the sword.) Taking damage wastes a frame for every health lost, as there's a refill after each boss that takes an extra frame for every health point it has to refill. * I noticed that the 1-frame state lag affects everything in this game. This is easily the most important [glitch/bug] in the game. To explain it more clearly than my previous post, every slot in this game (enemy, Yoh himself, even objects) have a state which is changed depending on their actions. Getting on a floating platform will change its state, attacking will change Yoh's state, and so on. However; when states are changed, there is a one-frame lag during which the state will apply, but not the effects of that state. For example, if we are groundsliding with large speed, and then walk to 1 frame, we change to the walking state, but the effects itself of the walking state (changing our speed) are not applied. This applies to bosses as well (as well as every other thing which has a slot); if you interrupt them during this lag, then they will take different actions. There are a few new things I discovered about the mechanics of the game as well as in general, see the new numbers on the Lua script, but I'll keep these for once I have a WIP to show alongside it. (And once I get past Rio again..)
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
My weakest system, a really old laptop from 2006 running Debian 9; CPU: Single core Intel Atom N280 (-HT-) cache: 512 KB clock speeds: max: 1666 MHz
User Agent: Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Firefox/52.0
Vector	Block	Result	Duration
12	3	correct	354.78ms
13	3	correct	702.88ms
14	3	correct	1354.16ms
15	3	correct	2741.19ms
16	3	correct	5448.77ms
12	4	correct	719.14ms
13	4	correct	1438.84ms
14	4	correct	2881.11ms
15	4	correct	5877.41ms
16	4	correct	11915.87ms
12	5	correct	1481.03ms
13	5	correct	2968.53ms
14	5	correct	5985.45ms
15	5	correct	15314.50ms
16	5	correct	36933.29ms
Status: Done.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
CPU: Dual core Intel Core i5-2520M (-HT-MCP-) cache: 3072 KB clock speeds: max: 3200 MHz
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0
Vector	Block	Result	Duration
12	3	correct	211.55ms
13	3	correct	133.73ms
14	3	correct	262.43ms
15	3	correct	524.23ms
16	3	correct	1039.53ms
12	4	correct	136.36ms
13	4	correct	268.99ms
14	4	correct	536.66ms
15	4	correct	1077.26ms
16	4	correct	2100.95ms
12	5	correct	272.36ms
13	5	correct	542.21ms
14	5	correct	1083.77ms
15	5	correct	2383.23ms
16	5	correct	4611.97ms
Status: Done.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Well, I should probably wrap things up here before I turn this thread into my personal blog. I've changed quite a bit in the six months separating my last post and the one I'm writing now. The only thing I want to correct from my previous post is well, not that I've rediscovered "passion and joy" through TASing. Here's a different insight on that - rather than focusing on the big, heroic thing that "saved" me out of nowhere, I've taken into account the small things that, here and there, make your life something else entirely - random acts that stay surprisingly solid even when given the test of time. I don't feel any resentment for what has happened; mostly because I have no real reason to resent against what happened back. In my opinion, maybe the things I have gone through might be considered horrible, or sad, and an onlooker would "pity" me or arrive at some other moralizing conclusion; but there's no harm in forgiving for these things, and easy forgiveness rather than hate long after the facts only hurts you in the end. This is why I forgive rather easily; much like I don't consider that I'm building myself towards being a perfect human being, I see the mistakes I make, as well others make as well, and forgiveness comes rather easily. (Of course, this isn't a golden rule; each situation has its approach, and living according to stuck up morals is dumb in the first place; the world won't adjust itself to your ideals, or your globalising one-liners on how you've figured the whole world out.) Basically, kindness to others is the greatest gift one can make to another, given the circustances. We act in a capitalist world and its framework can, a lot of the time, encompass people and blind them; but just the opposite is true as well. Effectively, treat each human you come across as a person, not a commodity, and suddenly the world changes gracefully. Understanding, as I've come to appreciate, leads you a lot farther than hate, or going with the flow or what-have-you. In a more casual paragraph, I've started to take care of my body; right now I'm doing some 30-minute runs every two days with a friend. The thing I currently enjoy the most are visual novels, which are no doubt the greatest things humanity has blessed us with; I'm reading The Fruit of Grisaia at the moment. Other than that, I don't have much in the way of grand conclusions I've taken from my experiences. I've found some great friends, who will no doubt go the way of wine and get better as time passes, and I otherwise take my life lightly - not taking a lot of something big to purpose my life, or something dumb like "loyalty to the nation", or some other cause that causes you to close your field of vision to whatever suits your ideals and ideology the most; but opening them as much as I can.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
MUGG wrote:
http://filsh.net/ Is what I use to convert Youtube to mp3. But recently they require you to enter an email address where the download link is sent to, so I'd be open for alternatives.
To download from youtube (as well as a lot of other sites), get it straight from the source - not the 3 billion cheap websites): http://youtube-dl.org/ And one of the best programs ever, that acts as a fancy wrapper for youtube-dl - allows direct streaming from Youtube (not requiring download) with your prefered video player, downloading in any format, transcoding on the fly with ffmpeg (can be used to convert to MP3; my preferred choice is Opus at 96k bitrate); MPRIS2 support as well a bunch of other cool stuff: https://github.com/mps-youtube/mps-youtube
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Link to video User movie #40250628616763089 This is the first 8 minutes of the game! There's a lot to say about this, but I don't want to spring up a wall of text so I'll stick to the basics. We have four main methods of movement in the game (all values in subpixels, 1 pixel= 256 subpixels) - walking, 416 speed - jumping, 432 speed, (can be brought to 464 with flipping), 4 frames of startup (0 speed) - damage boosting, 512 speed - backdashing, averages ~512.3 speed; 1 frame of startup (0 speed) The reason movement is so interesting in this game is the idea of control A constant choice I have to make, is when to sacrifice speed for more control? Obviously, since we're TASing, I always want to go as fast as possible, but a lot of the time I will need precise position to execute some tricks - ledge backdashing, a precise jump, backdash-skipping and so on. This is where my abstract notion of control comes in; it allows me to precisely manipulate my position for these tricks. In general, the slower a form of movement is and the less distance you are forced to go over with it, the better it allows to control my position and as such get the result I want. Each form of movement, while faster than the last, also has less control over it than the last: - walking can be done anywhere at almost any time, making it ideal for crossing small distances - jumping gives the freedom to attack without slowing down, and is ideal for subpixel control (since you can slow down or speed up with a single input), however it is not fitted for small distances since even the smallest jump is pretty large - damage boosting gives invicibility, as well as a noticable height boost, but makes Yoh take damage - backdashing is the fastest, but you cannot do anything else during it, it lasts for 32 frames, and is uncontrollable unless Yoh goes in the air. There are other forms of movement here, but I don't describe them for the sake of brievety. Also, these existing movements can be modified as well for more precise subpixel positioning, etc. (This part is not very well explained, but I hope it gets the point across..) In terms of tricks, we have: Flipping - when jumping, we need these inputs: > - [blank] - >. If this is done on the first possible frame, the first right input can be ommited. The blank allows Yoh to slow down to 432 speed, then speed back up to 464 (?!) speed, even though the max when jumping is 432. This can also be done when at lower speeds. Attack-landing - For some reason, when landing on the ground while attacking, we regain control 2 frames earlier. (This is why you see me attack almost everywhere.) Backdash-skipping - the first 16 frames of a backdash have complete invicibility, and locked movement; even if you go in the air while backdashing in this state, Yoh keeps going forward as if he were on ground. This is useful for a variety of things, the most prominent being going through enemies, but it requires good position. Ledge-backdashing - when in the air, Yoh will keep the entirety of his speed as long as you hold the same direction than the one he is currently going in. On its first frame, the backdash has a very insane speed - 1024 - and if you go in the air on your first frame of backdash, then you can keep this speed. In general, when there's a "ledge" like this, I always want to get 1024, although there are some cames where it's not beneficial, for example when Yoh stays in the air for a short amount of time, because the control needed to set it up (eg. walking for a few frames) ends up slower than just backdashing again, even though Yoh falls off the ledge with less speed. Groundsliding - When there is no input, Yoh doens't stop instantly, but his speed slowly slows down. This principles applies everywhere when there is no input. But it is also useful when having much greater speeds than usual (eg. after ledge-backdashing) and hitting the ground. Indeed, instead of backdashing immediately after, we can wait a few frames with no input, since Yoh will slow down (his speed will go 1024 - 976 - 947, etc), then backdash again when it gets too small. 1-frame state lag - When transitioning from one state from another, there is a single frame lag in which movement is not affected. This is an important fact, as it allows us to eg. turn around when groundsliding (no input) without starting to walk again, and lays the groundwork for a few other tricks. Buffered backdash - to backdash, we need to input down twice. Pressing down will make Yoh crouch, stopping him and wasting a frame or two. But these two facts are separate. You can press down at anytime, without making Yoh crouch. So if we press down in the air, then press it again while on the ground, then Yoh will backdash instantly without crouching. Note that there is a 14 frame timer on this. This is useful at the start of levels, where we can press Down before the level loads and instantly backdash, but it also leads to the TBB - see below. Turnaround buffered backdash (TBB) - The first part of this trick is a simple buffered backdash.The second part of this trick is an application of the 1F state lag. Indeed, if we backdashed instantly while facing the direction our speed is going in, eg after a ledge-backdash, then Yoh would backdash in the wrong direction. However, because of the 1F state lag, we can turn around while groundsliding, which makes this fast backdash possible. An application of this, in input, looks like this, if the direction of our speed is to the right : V (before landing on ground) - .. - < (while groundsliding) - V, and we wil backdash instantly. This technique is used everywhere when possible and when we have the opportunity to buffer a backdash (for example, during the previous backdash, while jumping, while attacking..) Turnaround attack backdash (TAB) - So, what if we can't buffer a backdash? Well, we can stil backdash instantly, by buffering the backdash "on-the-fly". This is especially useful while doing an easily interruptable control action - eg. walking. Application in input where Yoh is walking and needs to backdash: > (walking) - [blank] - < (1F state lag) - B (attack) - V (buffer the backdash while Yoh is attacking, causing him to not slow down) - [blank] - V (actual backdash). This works, and is not any slower than a regular TBB because even while attacking, Yoh still keeps the speed from the groundslide. Generally this technique is only applied to when we absolutely can't buffer, because otherwhise doing a regular TAB is classier, and also does not produce noise. There are a few other things in this WIP, like the boss fight, but I've written too much on this one already, so just enjoy the WIP :)
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
I agree on the point that calling it "unoptimised garbage" is uncalled for. And a lot of the rest of my previous post is baseless attacks on you. That's what I get when I write posts at 2 AM without thinking about it; I apologise for the attacks and the rest of my rude behavior, which is especially uncalled given the context here. To answer the rewind point:
I still don't get why can't rewind be used effectively in TASes. It is literally the same thing as save states, but easier. If you have to return to a previous part, like a level, then yes, use regular save states. But for small segments in one level, for example, I don't see why rewind can't be used.
This is mostly a matter of workflow. First, not every BizHawk core has rewind, and other emulators do not have it all. But the main reason I push TASeditor/TAStudio is because it allows a much better workflow for TASing; you are not limited to 10 savestates - instead every frame is a savestate, and you can jump to it very easily, unlike in traditional TASing; when you go back to a frame, the rest of the movie is not truncated unlike with savestates where they do not store the input after the savestate; you have the capacity to undo; and you are not forced to TASing a small subset of the movie at a time, but can make modifcations anywhere at anytime by simply clicking on a frame, as well as seeing the complete input log-- this is far better than the small step back of a rewind, or the limited segment of traditional savestate TASing.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Right click > Truncate movie will do what you are looking for under Bizhawk 2 (or any version.) - deletes everything past your desired point.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
Not much, with the simple reason that I procrastinated almost a year on this (I got occupied with school, so I took on less consequent projects as a result.)
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
http://tasvideos.org/userfiles/info/40201120876893795 Saved 12 frames (I think) on 7-2. Use it as you will.
Editor, Experienced Forum User, Published Author, Experienced player (818)
Joined: 5/2/2015
Posts: 671
Location: France
lu9 wrote:
And I don't think "the dialogue skipping is shoddy" counts as criticism.
First off - how is it not a criticism of your run? Do you think hand-waving it as "it's not criticism" will suddently make it not true? To further my point, I looked at your TAS, and it's indeed true; the dialogue skipping is shoddy, probably because you TAS using rewind. Indeed, first off you don't skip dialogue at the first possible frame, and sometimes you even forget to skip it properly; instead of A > (blank) > A you do A > (b) > (b) > A. Your movement is bad; you don't cut corners, you pick up speed after talking with NPCs in an unoptimal way; there's even a point in the run where you bump into terrain for no reason and slowly have to pick up speed afterwards. And by the way, the splashes (with company name, etc) at the start of the game can be skipped, saving a bunch of frames. So is it a far stretch, not to tell of your run that "the dialogue skipping is shoddy", but rather "it's an unoptimised pile of garbage"? When you say in the submission text, "There is not much that can be saved TASing this game as it is mostly running around skipping dialog.", perhaps you ought to take a look at what you submit first before justifying yourself. See, I was almost ready to argue in good faith, but in particular these two parts of your post made clear that you have no intention to do so:
lu9 wrote:
Also is there really a need to sound aggressive like that?
This is just straight up baiting. We are being agressive here because you attack us instead of improving yourself.
lu9 wrote:
EDIT: Also just to note that I looked at Masterjun's criticism of my last SMA2 submission and already improved it, using a lua script, frame advance, rewind, save state, etc. I just didn't make an encode of it yet
Are you popular in Dungeons & Dragon circles? Because this sounds like a lot of roleplaying. You defend yourself with words, rather than actions.I would have almost believed you if you didn't include the "rewind" part, which easily points out you are lying, because no TASer uses rewind. Also, it takes time to make a lua script, and you casually crossed over my suggestion in my first post of using TAStudio mentioning frame advance and savestates. A bad attempt at saving face, really; nobody cares how you TAS. To summarise, please stop baiting people here, and trying so hard to defend yourself. Masterjun gave up a while ago on this thread, and I am doing so as well because you don't seem to want to change your attitude.