Scripts for level maintainers

Started by Simon, June 29, 2016, 06:13:39 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Simon

Are you on Linux? Make your life easy with scripts de luxe!

Windows users: If you're cmd-savvy, a Powershellist, or use Python, please share your Windows scripts, too.

Strip level from replays

You maintain replays for your awesome level pack. Replays may include a copy of their level. Lix has weird rules on whether to run the replay against the included level, or against the pointed-to level. To guarantee that Lix uses the pointed-to level at any time, strip the level from each replay file.

Both of the following solutions rely on how all levels' first lines begin with $BUILT<space>. The editor consistently saves like this, but it's not specced anywhere.
  • geoo's solution: The Python script is attached to this post. It creates new replay files without the levels.
  • Alternatively, the following Bash one-liner modifies replays in place. It doesn't keep backups. It recurses through subdirectories.
    find . -name \*.txt -exec sed -i '/\$BUILT /Q' {} \;
Sum initial lix

From all levels recursively found within the current directory, we extract the number of lix, then compute the sum.

find . -name '*.txt' -exec grep "\#INITIAL " {} \; | awk '{s+=$2}END{print s}'

Mass-verify replays

Verify all levels recursively found in the given directory replays/path/to/your/dir. Lix will check all replays against their pointed-to level, then output which replays solve, or don't solve.

This command is the same in any Windows or Linux shell:

lix --coverage replays/path/to/your/dir

-- Simon

Simon

#1
Delete all failing replays

You maintain a collection of replays in replays/path/to/your/dir. Over time, some are failing. You want to delete exactly the replays that point to a good level, yet don't solve that level.

This solution relies on the order of Lix's --verify output: The first comma-separated field contains (FAIL), and the second field contains the failing replay's filename.

Unix tools:
lix --verify replays/path/to/your/dir/ \
    | grep ^\(FAIL \
    | awk 'BEGIN { FS = "," }; { print $2; }' \
    | while read failingreplay; do rm "$failingreplay"; done


-- Simon

Simon

#2
lix2gif: Export Lix animation as animated gif

Requires ImageMagick's convert to cut the source bitmap into pieces, then gifsicle to compose the animation. It's probably possible to do it all with just convert, but I haven't researched further. gifsicle does the job perfectly, the only problem would be that it's an extra dependency.

bash script
#!/bin/bash

# Export the first row of a gridded Lix animation file as an animated gif
# with almost-black background. Run without arguments to see usage.

if [ \( $# -lt 3 \) -o \( $# -gt 4 \) ]; then
    echo Usage: lix2gif inputfile.png cellWidth cellHeight [numberOfCells]
    echo For example: lix2gif factory.T.png 48 64 7
    exit 1
fi

tmp="./tempfile-lix2gif-"

src="$1"
fXl="$2" # width ("x-length") of a single frame
fYl="$3" # height ("y-length") of a single frame
imgXl=$(convert "${src}" -ping -format %w info:) # width of entire image
imgYl=$(convert "${src}" -ping -format %h info:) # height of entire image

fNum=$(( (imgXl-1) / (fXl+1) )) # number of frames horizontally in the image
if [ $# -eq 4 ]; then
    fNum="$4";
fi

for ((frame = 0; frame < fNum; ++frame)); do
    area="${fXl}x${fYl}+$((1 + frame * ( fXl + 1) ))+1"
    out="${tmp}"$(printf "%03d" ${frame})
    convert "${src}" -crop "${area}" +repage \
        -fill "#010101" -opaque "#ff00ff" "${out}.gif"
done

gifsicle --delay=7 --loopcount=0 "${tmp}"*.gif > "${src}.gif"

rm "${tmp}"*



For example, the script produces the above animation from eater.T.png.

-- Simon

Simon

#3
Minimize PNG file size

Lix likes PNG images best. And Git repositories prefer small binary files over large binary files! Let's minimize our file sizes whenever we edit sprites or tiles. My workflow to minimize PNG files is:
  • In Gimp, select File -> Export ... to export as PNG.
  • In the PNG-specific dialog:
    • Uncheck all boxes. In particular, uncheck Exif metadata.
    • Choose compression level 9, the maximum.
    • Choose the automatic pixel format.
  • Exit Gimp.
  • optipng -o 7 myfile.png
  • exiftool -all= myfile.png
Somehow, it's both good to first re-save with Gimp and to then run optipng -o 7 on the same file. I conjecture that optipng compresses better than Gimp, but doesn't change some of the settings that Gimp offered you. If this conjecture is right, you can choose a lower compression level in Gimp to save time because you'll recompress anyway optipng -o 7.

In the above workflow, exiftool -all= should report that it didn't change your file because you had no strippable optional metadata. But if some optional metadata remained, it's now discarded, as you want. The optional metadata can easily be 4 KB, which is a lot when you version many images.

Small PNGs, happy Simon!

Further reading: Limitations of ExifTool when we ask it to discard all optional metadata.

-- Simon