Textureless: Retro Pixel Nostalgia

by kikiala

Downscales non-UI graphics to 1/8th size. This mod was made by hand in a flickering terminal using ffmpeg and bash, mostly.

Overhaul
4 hours ago
2.0
244
Owner:
kikiala
Source:
N/A
Homepage:
N/A
License:
MIT
Created:
1 year, 1 month ago
Latest Version:
0.3.5 (4 hours ago)
Factorio version:
2.0
Downloaded by:
244 users

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.