vg-json-data / sm-json-data

JSON representations of Super Metroid Game Data
Other
26 stars 12 forks source link

Add timings to strats (e.g. for escape timings) #1462

Open blkerby opened 7 months ago

blkerby commented 7 months ago

Currently, escape timings in Map Rando are defined in a JSON file that mostly just gives one timing for each pair of doors in every room: https://github.com/blkerby/MapRandomizer/blob/main/rust/data/escape_timings.json. Recently there has been interest in supporting more refined escape timings, ones that don't assume all movement items are collected, and possibly taking into account cross-room strats (e.g. to shinespark through Croc Speedway in reverse). This is a much bigger undertaking than what we've done so far with escape timings, and I think it would make sense to be part of the sm-json-data. If this is done, a main benefit would be that in Desolate seeds it would no longer be needed for all movement items to be given for the escape, and escapes could require doing trickier strats. It would also allow us to support more options for "Escape start" seeds, where you would get only a subset of the items and again might have to do trickier strats.

Kyle and I were discussing a couple possible strategies:

  1. Include timing data on strats in sm-json-data; e.g. this could be a new strat property frames. Ideally every strat could have a timing, but incomplete coverage can also work; strats that don't have a timing just wouldn't be logically usable in the escape.
  2. Create a new project/repository specifically for escape timings. It would probably follow a similar structure to sm-json-data and share the same schemas, tech, and helper definitions but could have its own room data.

If possible, the first option seems most appealing, since having timing data on strats could have many applications, making it nice if it could stay integrated with the rest of the data. Examples of other things that could be done with it include finding optimized routes through a seed (minimizing total time) and supporting randomizer options that modify which rooms are heated.

There are a number of challenges:

The way I'm envisioning this, adding timings to strats would be a long-term project that could happen in phases, starting with the lowest difficulty strats and moving up from there. If we can cover the "Basic" strats (plus Hyper Beam gate shots and maybe a few other little things), that's already enough for it to be usable in randomizers; I think we would launch it in Map Rando at that point. Adding higher difficulty strats just allows for tighter escape timings, smaller sets of placed items, and spicier tricks potentially required in the escape.

kjbranch commented 7 months ago

In the short term, strats would only be useful for the escape, so some simplifications can happen to reduce the scale of the project:

Maybe someday this could be thorough enough to change which rooms are heated. Even if the only strats that had Frames were those in Hard or below, that could still change the game significantly and is something that has been requested from many players.

osse101 commented 7 months ago

I'd like frame counts on strats but I don't want them to be inaccurate, incomplete, inconsistent, or outdated. Unless inaccurate is what we want since its more manageable to model. Strat frame counts would slow down adding new strats too much -> placeholder unassigned value Strat branches -> Frame count of best case and add additionalExecutionFrames requirement. Probably no better than purely doing executionFrames.

I'd be more interested in separately doing door to door room timings with different loadouts. But I think that is the only difference. Strat times would ensure better coverage while being useful for other purposes.

Timing data is sm data so I think it has a place here.

blkerby commented 7 months ago

Yeah, thinking about this more and talking it over with Kyle, it does seem like we would need a frames logical requirement for this, in order to have enough flexibility to include it in or branches, and in that case there's probably no reason to also have a strat property for it. executionFrames is another option for what it could be named; the advantage of frames is just being shorter to type and read, since it is going to be so commonly used.

Another thing (suggestion from Kyle) is that heatFrames can implicitly include frames as well, so there wouldn't be a need to double them up in all the heated rooms. heatFrames is unique in that each strat will be either entirely heated or entirely unheated, so the existing heatFrames (where specified) should always align with the total frames. This is not the case with lavaFrames, acidFrames, etc., where in many cases only part of the time of the strat will be spent taking that damage; so frames would not be implicitly included in those. We will have to be careful with strats that require heatProof (possibly just in an or branch), since those will either need frames to be explicitly added or to be treated as "never".

For doing door-to-door timings with different loadouts, there are some cases where I imagine this could blow up to some extent. I'm thinking of Mt. Everest for example. There are so many ways of moving through the room, and it's not just determined by item loadout: tech and entrance conditions also play a role. It seems like there's some trade-off between doing door-to-door timings vs. using the junctions. Door-to-door timings are easier to measure in the Practice Hack, but it would be a lot of new strats with a lot of duplication and overlap with the existing strats, which could be messy. In this case I think there could be more of a benefit to using the junctions and adding timing data to (a subset of) the existing strats, though we would want to redefine the junctions slightly to become points in the room rather than areas.

I'm hoping that it won't be necessary to create separate "Enemies" vs. "No enemies" versions of strats in very many cases. I think in most cases the strats can just be written under the assumption that the enemies are there; and if it depends on the enemies being there, then it should have a canUseEnemies requirement. In rare cases we may want a way to add alternative strats that assume the enemy isn't there; we could introduce a new logical requirement for that. In most cases though it seems like there's not a lot of difference between having Hyper Beam to clear out enemies vs. the enemies not being there. I have wondered if we might want to have a version of canUseEnemies that specifies the enemy name, since for platform-like enemies such as Kamers and Trippers there could be room for different behaviors as far as whether they get cleared during the escape or not. Granted, the timing data could eventually be used for purposes other than escape, so we'll want to be careful to avoid hidden assumptions about having Hyper Beam for instance, but for prioritizing how to populate the timing data it makes sense to start with stuff that's relevant to the escape.

blkerby commented 7 months ago

For difficult strats, it's a good point that their effective difficulty can be changed by having a timer put on them. We could account for this on the randomizer side, e.g. maybe by applying a larger escape multiplier to high-difficulty strats. We might even consider entirely excluding strats with very high difficulty (e.g. Extreme or Insane); even if those strats had timing data I'm not sure if we would want the randomizer to require them during the escape.