Oh, ok. Well, good luck!
One more, thing, since ARMOURs don't randomly appear, wouldn't it be faster in the longer run to fight MAN every 10 steps then to reload the room every 2 fights?
Thank you!
It is a nightmare to manipulate every encounter step number to be a small one (10-15) AFAIK. The game seems to incline to "balance" encounters by rolling out more great numbers (70-74) after you have got several small numbers in a row. Does it reset this behavior if you exit and reenter the same room? I haven't tested this. Anyway, I planned to spread the encounters to many areas to relieve the stress of luck manipulation as well as the audience's feeling of repetition.
EDIT: The Lua script that I used (and revised for presentation :p):
-- Sweet Home TAS GUI --
-- updated in April, 2011 --
-- by klmz --
-- Note: This is a whole mess. Don't use it as a demonstration of Lua scripting! --
--require("auxlib");
-- please ignore this thing and use the built-in alternative instead
local function IPairs(t)
local i = 0;
local n = table.getn(t);
return function ()
i = i + 1;
if i <= n then
return i, t[i];
end
end
end
local function PosToString(pos)
return string.format("%02x%02x.%02x", pos.high, pos.mid, pos.low);
end
local function ReadI8(byte_address)
return memory.readbytesigned(byte_address);
end
local function ReadI16(low_byte_address)
return memory.readbyteunsigned(low_byte_address) + memory.readbytesigned(low_byte_address + 5) * 256;
end
local function ReadPosHML(high_byte_address)
local pos = {};
pos.high = memory.readbyteunsigned(high_byte_address);
pos.mid = memory.readbyteunsigned(high_byte_address + 0x001B);
pos.low = memory.readbyteunsigned(high_byte_address + 0x0036);
return pos;
end
local function ReadPosIF(high_byte_address)
local high = memory.readbyteunsigned(high_byte_address);
local mid = memory.readbyteunsigned(high_byte_address + 0x001B);
local low = memory.readbyteunsigned(high_byte_address + 0x0036);
return { I = high * 256 + mid, F = low };
end
local emu = FCEU;
local keys = {};
local last_keys = {};
local function KeyPressed(key)
return keys[key] and not last_keys[key];
end
local text_color = "white"
local info_color = "yellow"
local warn_color = "#FF3F3F"
local fg_color = "white";
local bg_color = "black";
local osd_inventory_on = false;
local osd_details_on = false;
local offsets = {0, 3, 4};
local team = {{}, {}, {}};
local details = {{}, {}, {}};
local pos = {{}, {}, {}};
local inventory = {{}, {}, {}};
local colors = {"#DFDF3F", "#4F4FFF", "#FF3F3F"};
local directions = {
"-", "L", "D", "U", "R"
};
local stati = {
"normal", "poisoned", "deadly poisoned", "cursed", "paralyzed", "scared"
};
local item_list = {
-- special items
"----", "Camera", "Vaccum", "Key", "Medicine", "Lighter",
-- replacements
"Polaroid", "Broom", "Wire", "Cookies", "Matches",
-- 0x0B
"Shabby Board", "Sturdy Board", "Rope", "Torch", "Light",
-- 0x10, 4 in each row from now on
"Hammer", "Safety Footwear", "Bowgun", "Bucket",
"Pickaxe", "Log", "Iron Bar", "Shovel",
"Crystal Ball", "Jade Ring", "Two Keys", "Golden Key",
"Basement Key", "Knife", "Magnet", "Pulley",
"Empty Box", "Clay Figurine", "Iron Key", "Spear From Armor",
"Slide", "Gasoline", "Candle", "Rope Ladder",
"Diary Key", "Gloves", "Axe", "Child's Coffin",
"Extinguisher", "Photo", "Keepsake Dress", "Blue Light",
"Ruby Ring", "Blue Candle", "Potion Bottle", "Diary",
-- 0x34, weapons
-- knives
"Fruit Knife", "Flick Knife", "Shiny Knife", "Silver Knife",
-- spears
"Spear", "Worn Spear", "Shining pear", "Amulet Spear",
-- axes
"Amulet Axe", "Heavy Axe", "Shiny Axe", "Silver Axe",
-- swords
"Sword", "Long Sword", "Silver Sword", "Holy Sword",
-- other weapons
"Wooden Sword", "Club", "Fork", "Trident"
};
local enemy_list = {
"Spiritual", "Cursed Doll", "Bats", "Grubs",
"Skull Snakes", "Mudman", "Half-Body Man", "Mirror",
"Wall Face", "Mad Dog", "Man", "Copper Armor",
"Machete Man", "Zombie", "Reaper", "Inverted Zombie",
"Skeleton", "Man Turned Around", "Fiery Ball", "Skull Ghost",
"Decomposed Corpse", "Wolf", "Silver Armor", "Maniac",
"Kazuo's Doppelganger", "Akiko's Doppelganger",
"Taguchi's Doppelganger", "Asuka's Doppelganger",
"Emi's Doppelganger", "Madam Mamiya", "Madam Mamiya 2nd Form",
"Ultimate Glitch Monster"
};
gui.transparency(1);
local function Everything()
keys = input.read();
if KeyPressed("I") then
osd_inventory_on = not osd_inventory_on;
end
if KeyPressed("U") then
osd_details_on = not osd_details_on;
end
for i, u in IPairs(offsets) do
pos[i].X = ReadPosIF(0x0C51 + u);
pos[i].Y = ReadPosIF(0x0CA2 + u);
pos[i].FACE = ReadI8(0x0C55 + u);
team[i].HP = ReadI16(0x6194 + u) + 1;
team[i].PP = ReadI16(0x61C6 + u) + 1;
team[i].EXP = ReadI16(0x61DA + u);
if osd_inventory_on then
inventory[i].ITEM_S = ReadI8(0x6255 + u);
inventory[i].ITEM_1 = ReadI8(0x625A + u);
inventory[i].ITEM_2 = ReadI8(0x625F + u);
inventory[i].WEAPON = ReadI8(0x6264 + u);
inventory[i].USED_S = ReadI8(0x6269 + u);
inventory[i].USED_1 = ReadI8(0x626E + u);
inventory[i].USED_2 = ReadI8(0x6273 + u);
end
if osd_details_on then
details[i].LV = ReadI8(0x61A8 + u) + 1;
details[i].UP_EXP = ReadI16(0x61D0 + u);
--details[i].ATK = ReadI16(0x61BC + u) + 1;
--details[i].MAX_HP = ReadI16(0x619E + u) + 1;
--details[i].MAX_PP = ReadI16(0x61B2 + u) + 1;
details[i].STATUS = ReadI8(0x6180 + u);
details[i].WHERE = ReadI8(0x61FD + u);
--details[i].IN_PIT = ReadI8(0x6296 + u);
end
end
for i, v in IPairs(team) do
local last_len = 0;
local gui_string = string.format("X: %03X.%02X", pos[i].X.I, pos[i].X.F);
gui.text(last_len, (i - 1) * 7, gui_string, colors[i], bg_color);
last_len = last_len + string.len(gui_string) * 6;
gui_string = string.format("Y: %03X.%02X", pos[i].Y.I, pos[i].Y.F);
gui.text(last_len, (i - 1) * 7, gui_string, colors[i], bg_color);
last_len = last_len + string.len(gui_string) * 6;
for j, w in pairs(v) do
gui_string = string.format("%s: %3d", j, w);
gui.text(last_len, (i - 1) * 7, gui_string, colors[i], bg_color);
last_len = last_len + string.len(gui_string) * 6 + 4;
end
end
timer = memory.readbyteunsigned(0x000A);
gui.text(200, 201, string.format("timer: %d", timer), text_color, bg_color);
stage = memory.readbytesigned(0x617A);
battle_screen = memory.readbytesigned(0x030F);
-- details
if osd_details_on then
for i = 1, 3 do
local lv = details[i].LV;
local up_exp = details[i].UP_EXP;
local status = details[i].STATUS + 1;
local where = details[i].WHERE;
gui.text(i * 84 - 72, 32, string.format("LV: %2d", lv), colors[i], bg_color);
gui.text(i * 84 - 72, 40, string.format("UP EXP: %4d", up_exp), colors[i], bg_color);
gui.text(i * 84 - 72, 48, stati[status], colors[i], bg_color);
gui.text(i * 84 - 72, 56, string.format("Room: %2d", where), colors[i], bg_color);
end
end
-- inventory
if osd_inventory_on then
for i = 1, 3 do
local item_s = inventory[i].ITEM_S + 1;
local item_1 = inventory[i].ITEM_1 + 1;
local item_2 = inventory[i].ITEM_2 + 1;
local weapon = inventory[i].WEAPON + 1;
gui.text(i * 84 - 72, 120, item_list[item_s], colors[i], bg_color);
gui.text(i * 84 - 72, 128, item_list[item_1], colors[i], bg_color);
gui.text(i * 84 - 72, 136, item_list[item_2], colors[i], bg_color);
gui.text(i * 84 - 72, 144, item_list[weapon], colors[i], bg_color);
end
end
-- battle info
if battle_screen == 1 then
local enemy_id = memory.readbyteunsigned(0x624E) + 1;
local enemy_name = enemy_list[enemy_id];
if (stage == 11 or stage == 6 or stage == 7) then
gui.text(130 - string.len(enemy_name) * 2.6, 48, enemy_name, info_color, bg_color);
foe_hp = memory.readbytesigned(0x6250) * 256 + memory.readbyteunsigned(0x6252) + 1;
gui.text(110, 60, string.format("HP: %3d", foe_hp), text_color, bg_color);
else
gui.text(107, 72, "WARNING!", warn_color, bg_color);
gui.text(130 - string.len(enemy_name) * 2.6, 80, enemy_name, warn_color, bg_color);
end
end
battle_members = memory.readbyteunsigned(0x622A);
if battle_members > 0 and (stage == 11 or stage == 6 or stage == 7) then
call_timer = memory.readbytesigned(0x0EE3) * 256 + memory.readbyteunsigned(0x0EE2);
if call_timer > 0 then
gui.text(200, 209, string.format("call: %d", call_timer), warn_color, bg_color);
else
gui.text(222, 209, "fight!", warn_color, bg_color);
end
else
if battle_screen == 0 then
steps = memory.readbytesigned(0x617D);
gui.text(200, 209, string.format("steps: %d", steps), info_color, bg_color);
end
end
last_keys = keys;
end
while true do
gui.register(Everything);
emu.frameadvance();
end
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
I saved a whole 32 seconds from my old WIP!
Note: According to my strategy, Asuka will be the final team leader who reaches Level 16 first, hence she has to receive EXP from every single battle (except when everyone escapes). Emi and Kazuo may have less EXP.
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
Thanks. I would probably use the CALL command twice later in the game to avoid unnecessay fights. The great thing about it is that the free control given by it is limited by time (630 frames) rather than steps, meaning that with Pulley activated I can slip through quite a few rooms.
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
I got a question. Why did you pick up the pickaxe, then without using it, swapped it with the FireX (Fire extinguisher)? Otherwise, great run. Your "grind" sure seemed way less boring than mine. =D
That was to place the Hammer there for later repicking it up and cracking down a wall in the long corridor with many bounders in it to reveal a secret passage. I didn't see you take it in your test run. Maybe you were unaware of it. Do you remember when you got next to the second bounder in that room, a "mysterious" dialog showed up? That was a hint by the game.
And I think it was overall faster this way than to grind more before Lake and then use the escape-fight-and-row-back-as-single-man strategy.
Also note that I reserved >25 PP for Kazou to perform a Pray attack against Machete Man right before entering the Basement Area. I would have Asuka use the Potion/Tonic during the fight (much faster than to use it in the overworld).
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
Basement done:
http://dehacked.2y.net/microstorage.php/info/795780881/sweethome-klmz-wip5.fm2
Unfortunately, I didn't realize until now that about 1 second should have been be saved if I had taken the Board in the main room on the second floor, and swapped the Blue (Flash-)Light with the Board in the dining room so that I could repick the BFL after the flying-away by Mistress Mamiya cutting off the detour at the beginning of the run in order to erase the Shadow on the first floor. Should I start this over again?
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
Well, I can relate to that. There are times that I made simple mistakes that set me back by alot if I had to fix them, but I still went back to fix it. I suggest that you do, but its your choice.
It's not worth doing, as 1 second would be about 1/2700 of the length of the whole complete run.
EDIT: Still, I think I should finish the current WIP first.
<klmz> it reminds me of that people used to keep quoting adelikat's IRC statements in the old good days
<adelikat> no doubt
<adelikat> klmz, they still do
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
A big new glitch in Sweet Home allows for sequence breaks to be performed.
Link to video
The effect of performing this glitch is that you can create a party where the two party members are not adjacent to each other.
Normally the party members just follow in your steps and thus don't check collision.
However now your party members are far away from you. You can move them remotely to pass through solid props (gates, rocks, etc) and NPCs and then take control of them for real after the sequence break has occurred.
It also looks really funny!
If anyone is interested in TASing this game again (the existing TAS is http://tasvideos.org/forum/viewtopic.php?t=13905 ), this will for sure save tons of time.
Joined: 11/13/2006
Posts: 2822
Location: Northern California
I hardly know anything about the game, but this glitch is so interesting that I've recently been looking into it (and the game itself). Unfortunately, there are a couple problems I see that prevent it from saving as much time as it possibly could:
*The glitched character is still considered in the hole until they're roped out, and thus they lose HP with every step, meaning you're on a bit of a strict timer every time you do this glitch. It's nothing major, but it does limit the usefulness of the glitch early on in the game.
*You apparently still need to level up to defeat Mamiya: According to the Sweet Home shrine, she needs to be hit with 80 Pray Points at the end of the battle, which is only possible starting at level 15.
That said, even with those limitations it's still a powerful glitch. If you can skip the 3 statues puzzle, then that's a decent chunk of grinding removed: You can just get to level 14 and use the party member battles in the final area to get up to 15. Even if you can't skip the 3 statues, there's still a lot of time to save, since you could conceivably just skip around the map to pick up weapons and items and start grinding in the later areas for faster EXP earlier on.
I'd be interested in seeing what a glitched run would look like and I may even be interested in doing it myself in the future, though I'd need either a lot of time to study the game or a couple knowledgeable partners to team up with in order to actually know what I'm doing.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Link to video
Quick video on the glitch with annotated instructions and a more detailed tutorial in the description, for anyone who's interested.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
RTA WR from about a year ago, 12 minutes faster than the published TAS:
Link to video
I've spent the last couple days looking into this and it's turned into a real deep rabbit hole of things that don't make sense. I'll try and give a proper writeup of the things I'm finding out, but it may take me a while to even come close to beginning to understand anything that's happening here.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Link to video
Almost exactly 5 minutes ahead of the above RTA run using the same route. Keeping in mind that I need to save a little over 8 minutes over RTA (it starts timing at gameplay, about 15 seconds later than the TAS) to have a sub-20:00 TAS time, the fact that I only have about 3 minutes left to save with more than half the run to go is pretty reassuring.
I'm not even sure if this is going to be the final run, yet. There's still a ton of things I need to test and figure out. I've been working under the brutal assumption that all the weird little things the RTA run does are necessary, mostly because that assumption has turned out to be true in about 100% of the times I've tried. That's not a joke about me having only tried one thing, by the way, as there have been somewhere around 15-20 ideas I've had that turned out to be either slower, useless, or completely broken. I'm not even sure the stuff I have found is legit. Anything I've changed so far has the potential to break something else later on down the road, and I won't know until I've gotten there.
Either way, this should be a good preview of what the new TAS will look like from a "what the hell is happening" perspective.
EDIT: Pretend I grabbed the key after the Monument puzzle. Also, unrelated note, never TAS while half-asleep.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Now-cancelled submission of mine: #8122: Samsara's NES Sweet Home in 18:10.55
I'm estimating there's at least a minute of known improvements, and still a lot of potential, but I also estimated that run wouldn't even be sub-20 so what do I know about accuracy?
I had a running list of ideas in the submission thread, I'll crosspost it here and update it with a bunch of new things and ideas. Starting with the known improvements:
Skipping the Asuka clone fight looks like it saves about 8-10 seconds, assuming the Mamiya fight doesn't need to be changed.
I found a small reroute in the Courtyard. The red path is the one taken in the submission, the black path is the reroute. The reroute takes you directly to the fountain room, and you can move glitch past the statue to be able to push it into the fountain. This does force a battle with a Mirror, but the current path takes a battle as well so that part evens out. This path can also be taken on the way back from the Lake, since the Bowgun isn't necessary to cross the ice room. On paper, this is maybe 20 seconds of timesave. In practice, it may be less because of battle shenanigans.
It is in fact possible to skip the first Tonic and still have the move glitch work, which is a 7-8 second save right at the very beginning. I have no idea why it didn't work for me any other time I tried it, I just tried it again out of the blue and it worked first try.
One small movement optimization I found on accident is that Emi can usually be move glitched into a wall or obstacle and survive as long as she moves onto a safe tile on the first possible frame she can. At the very least, this cuts out a handful of steps at the Lake, as I'm able to move glitch directly onto the Monument and move off of it rather than needing to walk around and move glitch up from the boat dock. This also slightly optimizes movement with Taguchi, as he doesn't need to move as much.
Speaking of Taguchi's movement, something I want to do is find the best place for him to start his move glitching "route". If I can find a place that doesn't require him to be reset at any point in the run, nearly every QTE can be skipped with minimal time loss, saving a few seconds each.
Here's the stuff that didn't work:
I tried move glitching past the Mamiya encounter to see if I could get the Gold Key early, which would remove the need to take Kazuo and Akiko into that room, but it's triggered on pretty much every tile past the point where it normally happens. Even move glitching into walls will trigger it.
I tried skipping the third Silver Sword before going into the Inner Sanctuary. The plan was to put the first two swords on Kazuo and Akiko and then not have Emi equipped until she picks up the Pitchfork in the Dungeon, but battle order prioritizes Emi, meaning most battles were taking longer to finish by default.
And here are some potential ideas that I have yet to test or account for:
Battles. Like, just in general. Better step counter manipulation, getting better battles in general, manipulating better damage values to possibly save turns, there's probably a lot of wiggle room here. I'm also considering the possibility of using Taguchi way more liberally to truly minimize step count. Battles in the late game can end up being 15-20 seconds or so, spending a handful of extra frames as Taguchi could mean a time save from skipping a battle that would have otherwise been fought.
I'm also wondering if it's worth taking a little bit of extra time to EXP glitch off of higher EXP enemies. In the submission, Akiko glitches off of Worms (6 EXP) and a Hound (30 EXP) and Kazuo glitches off of MAN (35 EXP), and by the Mamiya fight they both end up at level 19, one away from max. Level 20 would give them both a decent damage boost in that fight, which may cut down on turns in the second phase where damage actually plays a part. Higher EXP helps Emi as well, since she needs to be level 7 before the Monument puzzle, and any extra levels she gets before the final fight could also help cut down on turns on Mamiya.
I need to experiment more with routing and the move glitch. It is possible to move glitch entirely OoB, but I wrote it off as useless since it didn't seem like you could move at all. Further investigation may yield some interesting results, but I get the feeling I'll just be moving this point into the stuff that didn't work section.
One more thing I think is definitely worth mentioning:
I was messing around with the corrupted party member (a glitch I specifically avoided because it makes it impossible to switch characters) and found that there's a lot more to it than I originally thought. The main thing that interests me is that it completely disables the ability to get into battles. The step counter just depletes and overflows over and over. Being captured by spirits is also disabled in this state. I wasn't able to test this further, mostly because I was working from a new game and didn't have access to most of the map, but also because I discovered something a little more... Well...
SOUND AND FLASHING LIGHT WARNINGLink to video
I probably shouldn't have gotten my copy at a garage sale from that man with the thousand yard stare, to be fair.
I want to play around with this a bit more, maybe have some people with better technical knowledge look into it in ways that my idiot ass can only dream of, but for now I'm going to focus on the things I can actually do.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
What the hell is even happening
Link to video
EDIT: I'm theorizing that the glitched attack at 0:17 did something like negative 20000 damage, since the enemy HP values go wild on it.
I've been working on trying to find a way to efficiently and accurately produce the glitched party member state. I can't seem to get the "creepypasta" effect to work again (may my AFD idea rest in peace), but I've found a lot of weird effects like the above video in the process.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Hi, been a while. Things may have been happening with this game over the last month.
Recently, I was alerted to a new RTA record using a couple new glitches. The run had been submitted to SRC, but took a couple weeks for it to be verified: https://www.speedrun.com/sweet_home/run/m3lpvoqm
As it turns out, kill_me has been actively but quietly glitch hunting the game, with results that are... Staggering, to say the least. In short, board glitch corrupts memory a lot harder than I originally thought. I've learned a lot about the game by watching their runs and glitch videos, but as a result, TASing it got a whole lot more complex because of the sheer potential of the recent discoveries.
kill_me's current record actually stands at 21:14, which I don't believe has been submitted to SRC, but it's the run I've been using as a guide for the current version of the TAS. I believe optimizing that route as much as possible would lead to a time around 11 minutes, but I feel like further exploration and rerouting could push the time down further, maybe even to sub-10...
What I'm saying is that it could be a while before a new submission from me, but good lord is it gonna be a good one if it comes. I've elected in advance to co-author kill_me on it. Hold me to that.
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family.
Now infrequently posting on Bluesky