theonlydude / RandomMetroidSolver

VARIA Randomizer, Solver and Tracker for Super Metroid
http://randommetroidsolver.pythonanywhere.com
MIT License
45 stars 27 forks source link

Some Issues and Questions regarding the CLI-Randomizer #93

Closed EctoOne closed 2 years ago

EctoOne commented 2 years ago

Hi, I just found this project and I am really liking it, but I've stumbled upon some issues and have one or to questions.

The first thing is that the the help argument doesn't works for me. I'm using it on a Raspberry Pi 4 with Debian Buster and everything else works fine. So it's not that bad. Here is the output:

./randomizer.py -h
Traceback (most recent call last):
  File "./randomizer.py", line 302, in <module>
    args = parser.parse_args()
  File "/usr/lib/python3.7/argparse.py", line 1758, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python3.7/argparse.py", line 1790, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python3.7/argparse.py", line 1996, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/usr/lib/python3.7/argparse.py", line 1936, in consume_optional
    take_action(action, args, option_string)
  File "/usr/lib/python3.7/argparse.py", line 1864, in take_action
    action(self, namespace, argument_values, option_string)
  File "/usr/lib/python3.7/argparse.py", line 1046, in __call__
    parser.print_help()
  File "/usr/lib/python3.7/argparse.py", line 2483, in print_help
    self._print_message(self.format_help(), file)
  File "/usr/lib/python3.7/argparse.py", line 2467, in format_help
    return formatter.format_help()
  File "/usr/lib/python3.7/argparse.py", line 293, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python3.7/argparse.py", line 224, in format_help
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.7/argparse.py", line 224, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.7/argparse.py", line 224, in format_help
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.7/argparse.py", line 224, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.7/argparse.py", line 534, in _format_action
    help_text = self._expand_help(action)
  File "/usr/lib/python3.7/argparse.py", line 623, in _expand_help
    return self._get_help_string(action) % params
ValueError: unsupported format character ',' (0x2c) at index 24

Next, I'm not a pro when it comes to writing scripts, so I'm probably just stupid but I can't figure out how handle arguments that contain SPACES in a bash script. For example, the following script will give me the error: "--startLocation Landing" unknown. So it cuts off the Site part, using --startLocation random works fine. And I think I've tried every combination of single and/or double quotes trying to fix this, but I can't. Any help would appreciated. I actually wish all those SPACES in some of the options were not there in the first place. I probably should mention that I want to use variables because I want make a simple GUI using dialog.

#!/bin/bash

APPDIR="${HOME}/RandomMetroidSolver"

INROM="--rom ${HOME}/RandomMetroidSolver.sfc"
OUTDIR="--dir ${APPDIR}"

LOCATION='--startLocation Landing Site'
CHARGE='--nerfedCharge'

cd $APPDIR
python3.7 ./randomizer.py $INROM $OUTDIR $LOCATION $CHARGE

And finally just a few questions. What is the purpose of the patch elevators_doors_speed.ips? Because whenever I added it by using --patch the game crashed when loading the Landing Site. The screen slided from left to right to the ship and then froze. I had some other patches active so there probably was a conflict but I didn't spend much time finding the other possible culprit. I just stopped using elevators_doors_speed.ips.

What does the argument --jm do? I've seen it in the Usage text but have no idea what it is about.

How does --controls work? I assume that it is to remap the buttons so that it doesn't need to be in game. Which I would really like to do, but I don't know the format to use it.

That's it, at least for now. Thanks in advance for any response and of course the continued development of this project.

theonlydude commented 2 years ago

Hello,

there's indeed an issue with -h, it's now fixed, thanks for the report.

to call randomizer.py it's easier to use a rando preset as explained in the README.

elevators_doors_speed patch is used to accelerate doors transitions and elevators. it now has been split in two: fast_doors.ips elevators_speed.ips

--jm is used for automated tests (see tools/test_jm.sh)

for --controls check how we use it in web/backend/randomizer.py

EctoOne commented 2 years ago

Thanks for pointing me where to look for --jm and --controls and the explanation of elevators_doors_speed.ips.

And I know how to call randomizer.py. I could use one or more simple scripts with fix settings but I want to be able to create a menu to select different settings.

I found a workaround for arguments which only require one parameter like --startLocation.

Not working:

LOCATION='--startLocation Landing Site'
./randomizer.py $LOCATION

Working:

LOCATION='Landing Site'
./randomizer.py --startLocation "$LOCATION"

So I can create a menu to set $LOCATION. But that method doesn't work for something like --objectives which can have multiple parameters. Because each parameter also needs --objectives. And since it is random how many objectives I want to choose, I can't just set a fixed amount in the command line. If there weren't any cases of parameters with spaces, I could just do something like this:

OPTIONS='--startLocation Landing Site ' 
OPTIONS+='--objectives kill botwoon '
./randomizer.py $OPTIONS

So, I would like to see iif those whitespaces get removed or replaced with underscores or whatever.

theonlydude commented 2 years ago

there's not only official rando presets, you can generate your json with the parameters you want and call randomizer.py with it (that's actually how we call the randomizer from the web backend). it's far easier to handle values with spaces or list of values.

EctoOne commented 2 years ago

I don't want to sound rude but that's kinda funny. Because I'm not that good at writing scripts and just passing on the arguments is easier for me since I'm used to bash scripts. And this is the first time I'm having issues with whitespaces. I have no idea how python or the web frontend works, so it might be easier for those.

I guess I could create a json with a bash script but IMO that would require more work on my end. I guess at this point, I simply won't add an option to set objectives. Which is sad but I can live with it.

Anyway, I found another problem with the cli randomizer. Aren't presets not meant to be just a template and that changing any setting would overwrite the default setting from the preset? That is at least what the website does. For example when I select the default preset and change the starting location to Gauntlet Top. That works fine on the website but not when using the cli randomizer.

./randomizer.py --rom VanillaRom.sfc --randoPreset rando_presets/default.json --startLocation "Gauntlet Top" With this line, I will still start at the Landing Site.

theonlydude commented 2 years ago

here's a sample bash script to use a json:

#!/bin/bash
# use jq and sponge to manipulate json, to install them on linux:
#  sudo apt-get install moreutils jq

rom=$1
python=python3.8
varia=~/RandomMetroidSolver

default="${varia}/rando_presets/default.json"
skill_preset_name="regular"
skill_preset="${varia}/standard_presets/${skill_preset_name}.json"
seed=${RANDOM}${RANDOM}${RANDOM}

# use default rando preset as base
rando_preset=$(mktemp)
cp ${default} ${rando_preset}

# update parameters
startLocation="Gauntlet Top"
jq --arg startLocation "${startLocation}" '.startLocation = $startLocation' ${rando_preset} | sponge ${rando_preset}

# random parameter with the list of possible values to choose from
majorsSplit="random"
jq --arg majorsSplit "${majorsSplit}" '.majorsSplit = $majorsSplit' ${rando_preset} | sponge ${rando_preset}

majorsSplitMultiSelect="FullWithHUD, Chozo"
jq --arg majorsSplitMultiSelect "${majorsSplitMultiSelect}" '.majorsSplitMultiSelect = ( $majorsSplitMultiSelect | split(", ") )' ${rando_preset} | sponge ${rando_preset}

# add custom objectives
objective="kill botwoon, collect 25% items, clear kraid's lair, kill shaktool"
jq --arg objective "${objective}" '.objective = ( $objective | split(", ") )' ${rando_preset} | sponge ${rando_preset}

# controls are not in the rando preset
moonwalk="--moonwalk"
controls="--controls Y,B,R,X,A,L,Select"

cat ${rando_preset} | jq

# call rando
${python} ${varia}/randomizer.py -r ${rom} --param ${skill_preset} --seed ${seed} --randoPreset ${rando_preset} ${moonwalk} ${controls}
if [ $? -eq 0 ]; then
    out=$(ls VARIA_*${seed}_${skill_preset_name}*.sfc)
    echo "Seed successfully generated: $(pwd)/${out}"
fi
rm -f ${rando_preset}
EctoOne commented 2 years ago

Thanks for the example script, I might consider expanding this someday when I really want to try different objectives. Again I don't want to sound rude, but to me it seems weird that I need to create a json for a command line tool which only has a few "broken" parameters which require quotes to work. Seems very unusual to me.

Can you still give me an answer about the "bug" that arguments different from a preset don't have a higher priority? See at the end of my last comment.

Thanks again for the support. I really appreciate it.

theonlydude commented 2 years ago

in early versions of the randomizer we used individuals parameters but we switched to using the randoPreset parameter instead. the old individuals parameters are still there, we sometimes use them for quick testing (and test_jm.sh, but we'll update it to use rando presets too to remove the ugly conversions from space to underscore). the only supported way to use randomizer.py is with randoPresets.

we might remove individuals parameters in the future to avoid confusion and "bug" like the one you encountered.

EctoOne commented 2 years ago

Almost sounds like that the cli version does need some sort of GUI whenever more parameters get removed. :)

Thanks again for the informations.