How we make GIFs for Twitter

Creating gameplay gifs that look decent on Twitter can be a bit of a challenge, so we thought we would share a few things we learned while making them for our own game.

So first a quick note on the process of creating a gif:

  • You record footage from your game, say a 5 minute video.
  • You extract a 10 second clip to show.
  • You convert this clip into a gif.
  • You upload this gif to twitter.

At each stage in this process, you want to ensure not to lose any quality in the footage.  This is very important, as Twitter will heavily compress your gif on upload, and any loss of quality that already exists will be amplified.

Sample gif we created using this process - see it on twitter

Recording

For recording footage of your game, there are many options but we like Kazam - its simple and works really well.  Check out this article for some tips on how to install and use it.

Setup Kazam to record as Lossless JPEG so no quality is lost, and with at least 30 frames per second (any lower and gameplay may appear choppy).

Extracting

To extract a clip from gameplay footage we use ffmpeg.

ffmpeg -i gameplay.avi -ss 30 -t 10 -codec copy -y gameplay-cut.avi

This basically says input the gameplay.avi video, then start the clip at 30s and cut out a 10s segment, and save that segment as gameplay-cut.avi.  It is important to use the -codec copy option, as this ensures no conversion or changes are made to the actual video, and its quality is kept intact.

Creating the GIF

To create a gif from our extracted clip we again use ffmpeg.  As gifs are limited to 256 colors, and we want to use colors from our footage, we need to first create a color palette from our clip.

ffmpeg -i gameplay-cut.avi -vf "fps=30,palettegen=stats_mode=diff" -y /tmp/palette.png

An important setting here is palettegen=stats_mode=diff - this tells ffmpeg to give priority to the moving parts of the gif (which will be your player, enemies, etc.) and less priority to static elements (such as backgrounds).

Now we can use this palette to generate the actual gif:

ffmpeg -i gameplay-cut.avi -i /tmp/palette.png -lavfi "fps=30 [x]; [x][1:v] paletteuse=dither=none" -y gameplay.gif

Another important setting here is paletteuse=dither=none - since a gif can only have 256 colors, by default it will try to use dithering to fake more colors.  This can ruin pixelart, so we tell it not to do that.  If your game is not pixelart you can change this to simply paletteuse.

One final step we will take is to optimize the gif using gifsicle:

gifsicle -O3 gameplay.gif -o gameplay-opt.gif

This reduces the size of the gif usually by about 20%.

Using a Bash Script

To simplify this process, we made a bash script so you can do:

./make_gif.sh 00005 30 10

Kazam saves its files as kazam__00005.avi, so we just use the id of the video (00005), then provide a start time (30) and length (10).

Here's the full script:

#!/bin/bash

# bash script to create gif from avi
# usage:
#   ./make_gif.sh filename start_time length

id=$1
file=kazam__$1
start=$2
length=$3
palette="/tmp/palette.png"
filters="fps=30"

# echo params to terminal
echo "$file $start $length"

# cut avi to segment we want
ffmpeg -ss $start -i $file.avi -t $length -codec copy -y $file-cut.avi

# make palette for gif
ffmpeg -i $file-cut.avi -vf "$filters,palettegen=stats_mode=diff" -y $palette

# create gif from cut segment
ffmpeg -i $file-cut.avi -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=none" -y $id-s$start-t$length-raw.gif

# optimize gif
gifsicle -O3 $id-s$start-t$length-raw.gif -o $id-s$start-t$length-opt.gif

# delete work files
rm $file-cut.avi

If you have any feedback or questions let us know in the comments below, or chat with us on twitter @abitawake or discord.  Hope you found this helpful =)