ProcGen Fun 8: Fun with flags

26 May 2026

Procedurally generating realistic country flags

[List of posts | playground | source code for this post]

So far in this series we've mostly focussed on mazes. So I thought I'd try something completely different: flags!

Vexillilogy (the study of flags) is full of patterns, which lends itself beautifully to procedural generation. So I've created a flag generator which randomly generates realistic-looking flags, including the flags shown above. Why not have a go yourself? You can even download and share your favourites.

In this article I'll give a brief overview of the building blocks which make up my flag generator.

Colours

First off, I needed a colour palette. Flags tend towards bright colours and away from pastels, so I've picked a range of bright colours similar to those you'd find on country flags.

White
#FFFFFF
Red
#C8102E
Dark Blue
#0033A0
Royal Blue
#0666DB
Light Blue
#6CCFF6
Dark Green
#006638
Light Green
#00991C
Yellow
#FCD116
Black
#000000
Orange
#FF8200
Maroon
#7A263A
Purple
#660099

The generator selects randomly from these twelve colours, with two particular caveats.

  1. Certain colour combinations are not so easy on the eyes (e.g. dark blue and dark green), so I've implemented restrictions on which colours can be placed next to each other.
  2. Certain colours (your reds, your whites, your blues) are much more common than others (looking at you, purple), so I've weighted them to keep the flags looking realistic.

Patterns

Next, how should the colours be arranged? There are a number of common patterns; here are the twelve I have chosen to use.

Solid
Vertical Bisection
Horizontal Bisection
Vertical Triband
Horizontal Triband
Diagonal Bisection
Diagonal Band
Cross
Saltire
Quadrisection
Horizontal Striped
Pall

Some patterns have additional variations. For example, diagonals can go either way, there can be varying numbers of stripes, and bisections and trisections can be uneven.

Decorations

Some flag patterns lend themselves nicely to additional decoration. A particular favourite of mine is fimbriation: a thin stripe which emphasises the border between two colours.

Another concept seen in real country flags is to add extra blocks of colour to the hoist (that is, the side nearest the flagpole).

Charges

A charge is an emblem added on top of the basic pattern of a flag; I've chosen six simple variations.

Circle
Star
Star Band
Plus
Crescent
Crescent and Star

The size and placement of any charges depend on the pattern underneath. For example, if your base pattern is a vertical bisection then it makes most sense for a charge to be placed in either the left or right half of the flag. A solid flag is most likely to have an extra-large charge right in the centre.

Technical details

If you're not a programmer, feel free to skip this bit!

Much of the implementation of my flag generator follows similar principles to the previous posts in this series, such as composition of distributions. However I'd like to particularly highlight the concept of a discriminated union, which was super helpful here.

A discriminated union is a type whose values can take any one of a fixed set of types. If you're familiar with C# this might sound like an enumeration, but a discriminated union allows you to assign additional properties to the individual values. For example, each flag pattern has a different set of additional properties: a solid flag just needs a single colour defined, whereas a triband flag needs three. This makes a discriminated union an ideal data type to represent a flag pattern.

[Union]
public partial record FlagPattern
{
    public partial record Solid(FlagColour Field);
    public partial record VerticalBisection(FlagColour Left, FlagColour Right);
    public partial record HorizontalBisection(FlagColour Top, FlagColour Bottom, HorizontalBisectionDecoration Decoration);
    public partial record VerticalTriband(FlagColour Left, FlagColour Middle, FlagColour Right);
    public partial record HorizontalTriband(FlagColour Top, FlagColour Middle, FlagColour Bottom, HorizontalTribandSizing Sizing, FlagColour? Fimbriation);
    public partial record DiagonalBisection(FlagColour Left, FlagColour Right, Diagonal Diagonal, DiagonalBisectionDecoration Decoration);
    public partial record DiagonalBand(FlagColour Field, FlagColour Band, Diagonal Diagonal, FlagColour? Fimbriation);
    public partial record Cross(FlagColour Field, FlagColour Foreground, CrossType CrossType);
    public partial record Saltire(FlagColour NorthSouthField, FlagColour EastWestField, FlagColour Foreground, FlagColour? Fimbriation);
    public partial record Quadrisection(FlagColour TopLeft, FlagColour TopRight, FlagColour BottomRight, FlagColour BottomLeft);
    public partial record HorizontalStriped(FlagColour Colour1, FlagColour Colour2, int StripeCount);
    public partial record Pall(FlagColour Field, FlagColour Foreground, FlagColour? Fimbriation);
}

Support for discriminated unions has been considered for C# for many years, and it’s finally coming in C# 15 later this year. In the meantime, I’ve used a package called Dunet to implement the discriminated unions I need. It’s particularly helpful in that the compiler will warn you if you have failed to consider one of the allowed values.

Conclusion

Of all the articles in this series, this has probably been my favourite to write! The variety of flags I've been able to generate from a handful of simple rules has been incredible. Sometimes I simply open up the flag generator and share my favourite designs with friends and family.

I've probably taken this as far as I want to for now, but some of my ideas for future expansion include:

And just for fun, here's six more of my favourites!

Further reading

I found the following Wikipedia articles very helpful while researching flag designs!