Textureless: Retro Pixel Nostalgia is a lightweight, yet far-reaching gameplay retexturing for Factorio 2.0 and the Space Age expansion. It aims to visually downscale all non-UI graphics to 1/8th size with a per-sprite 256-color palette.
This is a content replacement mod only. And the gods might be crazy, but I think it speeds up initial load times. I made it because while I absolutely love the graphics for Factorio, the high-resolution sprites overwhelm me. I wanted a simpler look, so I could focus on gameplay elements and the UI without becoming overstimulated.
You could say it's an 8-bit total graphical conversion. I still plan to modify the music as well, but for now I wanted to share the updated version that is compatible with 2.0.72 with optional dependencies for the stock base, quality, elevated-rails, and space-age datapacks.
There will be bugs and awkard stuff while I still test and try to fix it up. Thanks! The old trailer from around the 2.0 release. For the technically curious, here's a snippet of the script I wrote to filter every texture in the game while retaining compatibility:
#!/bin/bash
PATHSFILE=personal-paths.txt
INITIAL_PX=8
if [ ! -f $PATHSFILE ]; then
# prompts you to create paths file if not exist
echo "example: [your path...]/steamapps/common/Factorio/data"
read -p "game data dir: " $GAMEDATADIR
echo "example: ~/.factorio/mods/textureless"
read -p "named mod dir: " $MODDIR
echo $GAMEDATADIR\n$MODDIR > $PATHSFILE
else
# will read the paths file if it existed
{
read -r GAMEDATADIR
read -r MODDIR
} < <(cat $PATHSFILE)
fi
# in case there are issues. check it
echo "source data directory: $GAMEDATADIR"
echo "scratch mod directory: $MODDIR"
read -p "that look ok? (ctrl+c to cancel out)" $YESNO
# create a list of textures we're gonna mess with
PALETTEDIR=volatile-palettes
WORKINGDIR=volatile-working-data
[ ! -d "$WORKINGDIR" ] && mkdir -p "$WORKINGDIR"
[ ! -d "$PALETTEDIR" ] && mkdir "$PALETTEDIR"
SOURCEIMGLIST=source-image-list.txt
BASENAME_INCLUSIONS='victory|upload-chartbundle|splash-screen-image|splash-screen-image-space-age|background-image|background-image-logo'
CROSSPATH_EXCLUSIONS='\/snow\/snow|\/campaigns\/|\/core\/|\/icons\/|\/item-group\/|\/technology\/|\/arrows\/|\/lut\/|\/color_luts\/|minimap|collision|icon|visualization|visualisation|mask|fluid-background'
REGEXFILTER="^((.*)?($BASENAME_INCLUSIONS(\.jpg|\.png)$))|(^((?!$CROSSPATH_EXCLUSIONS).)*(\.jpg|\.png)$)"
find $GAMEDATADIR | grep --color=never -P $REGEXFILTER > $SOURCEIMGLIST
function filter_source_image ()
{
GAMEDATADIR=$1
WORKINGDIR=$2
PALETTEDIR=$3
INITIAL_PX=$4
FILE=$5
# some textures are fully transparent; filtering them would make them solid white
# so we use a null output run of ffmpeg to determine if this texture even has a single opaque pixel
HASPIXELS=$(ffmpeg -v info -i $FILE -frames:v 1 -filter_complex "format=rgba,blackdetect=alpha=true,metadata=print:key=lavfi.black_start" -f null - |& grep -o 'black_start=0')
test -z $HASPIXELS && echo 1 || echo 0
if [[ "$HASPIXELS" == "0" ]]; then
echo "EMPTY texture, skipping ..."
return
fi
# i need to rewrite this part, there is some texel density issues (see changelog)
IMAGEWIDTH=$(echo $(ffprobe -v error -show_entries stream=width -of default=noprint_wrappers=1 $FILE) | grep -o '=[0-9]*' | sed 's/=//')
IMAGEHEIGHT=$(echo $(ffprobe -v error -show_entries stream=height -of default=noprint_wrappers=1 $FILE) | grep -o '=[0-9]*' | sed 's/=//')
PX=$INITIAL_PX
MINDIMEN=$((IMAGEWIDTH<IMAGEHEIGHT ? IMAGEWIDTH : IMAGEHEIGHT))
PX=$((MINDIMEN<PX ? MINDIMEN : PX))
BBX=$((PX<INITIAL_PX ? 1 : PX / 4))
LMX=$((PX<INITIAL_PX ? 3 : 7))
ADJUST="format=rgba,hue=s=0.9,boxblur=lr=$BBX:lp=1.5:ap=0.0,unsharp=lx=$LMX:ly=$LMX:chroma_amount=5.0:alpha_amount=0.0:luma_amount=5.0"
# finally, filter and output the texture
FILENEW="$WORKINGDIR${FILE#$GAMEDATADIR}"
mkdir -p $(dirname $FILENEW)
PALETTE="$PALETTEDIR/$(basename $FILE)-palette.png"
echo "fakescaling $(basename $FILE)"
ffmpeg -y -loglevel error -i $FILE -frames:v 1 -vf "$ADJUST,palettegen=max_colors=256:transparency_color=black" $PALETTE
ffmpeg -y -loglevel error -i $FILE -i $PALETTE -frames:v 1 -filter_complex "$ADJUST,pixelize=w=$PX:h=$PX,paletteuse=dither=none:alpha_threshold=127" $FILENEW
echo -e '\t'"saved $FILENEW"
}
export -f filter_source_image
# read the file list and do the work
mapfile -t IMGPATHS < <(grep -v '^$' "$SOURCEIMGLIST")
(
# interrupt guard to exit entire loop if interrupted
trap 'echo "cancel"; exit 130' INT
parallel filter_source_image $GAMEDATADIR $WORKINGDIR $PALETTEDIR $INITIAL_PX {} ::: "${IMGPATHS[@]}"
)
echo "OUTPUT to $WORKINGDIR finished"
Nothing artificial. Pure logic, reason, and a niche love for pixellated crunch. Enjoy
Seeking work, over a decade of tech art and visual art as well as engine coding and gameplay but I have injuries and I'm grumpy so yea.