The Fool on the Hill: Sweet as Sugar

The Fool on the Hill: Sweet as Sugar

By: Simon Brooke :: 8 July 2023

SugarScape, running in AppletViewer

This week I listened to a podcast in which Manda Scott interviewed Gaya Herrington about her work building on the famous Club of Rome Limits to Growth report of fifty years ago, and the five insights she's drawn from it; and while all of it was fascinating, one minor point snagged my ear.

Herrington referred to a computer simulation called 'SugarScape', described in a paper by Joshua Epstein and Robert Axtell, and published by the Brookings Institution. And, surprise, surprise, this model found that gross disparities of wealth emerged naturally from the carefully chosen set of rules that they'd used.

Well, yes. You can set up a computer model to 'demonstrate' — or at least model — anything you want. If you start with assumptions about greed, you'll demonstrate greed.

As regular readers will know, I have done a fair bit of modelling with finite state automata. Finite state automata are really simple to set up and can — to a degree — model all sorts of things. And as soon as I heard the description of SugarScape I thought, that sounds like a finite state automaton. And sure enough, it is: you can download the source code, and it turns out to include the statement

/**
 * Built-on the original code from
 * --------------------------------
 * Game of Life v1.3
 * Copyright 1996-2001 Edwin Martin <edwin@bitstorm.nl>
 * version 1.0 online since July 3 1996

In other words, it's a modified version of an implementation in the Java language of Conway's original Game of Life, a highly theoretical two dimensional cellular automaton which started the whole fashion in computer science for such things.

It's always easy to criticise other people's code, and I shall not do that; it is of its time. It's a bit hard to get it to run these days, because it's written as a Java applet. But it does run, and you can play with it.

It's more than just a cellular automaton; in fact, it seems that the cellular automaton is essentially just providing a shifting field of resources. Above this it has a superstructure of agents called 'Citizens', who have a number of core properties:

class Citizen
{	int id;				//unique identiifer for each citizen
	int homeCol, homeRow;
	int vision;			//Vision Limit in cells in all directions
	int metabSugar;		//Amount of Sugar required to survive each round
	float sugar;			//Amount of Sugar currently left with citizen
	float inheritSugar;	//Initial sugar inherited/assigned at birth
	int metabSpice;		//Amount of Sugar required to survive each round
	float spice;			//Amount of Sugar currently left with citizen
	float inheritSpice;	//Initial sugar inherited/assigned at birth
	int lifeSpan;		//Age at which citizen is expected to die
	int sex;			//Gender of citizen
	int persona;		//Character - conservative or aggressive 
	int father;			//Father of citizen
	int mother;			//Mother of citizen
	java.util.List childList;	//List of children

'Spice,' above, seems to be a different foodstuff from 'Sugar', although the inline documentation conflates them and all the discussion of the program I've seen online mentions only sugar.

	/**
	 * Subtracts one consumption unit (spice metabolism) from the spice stockpile.
	 * 
	 */
	public synchronized  boolean eatSpice()
	{	//Consume spice
		this.spice -= this.metabSpice;
		//If not enough spice available then return false
		if(this.spice >= 0f)	{	return true;	}
		else					{	return false;	}
	}

Citizens inherit values for some of these from their parents, both attributes:

	private synchronized void setInheritAttributes(Citizen citizen, Citizen mate)
	{	if( (int)(Math.random()*2) == 1 )
			this.vision = citizen.vision;
		else this.vision = mate.vision;

		if( (int)(Math.random()*2) == 1 )
			this.metabSugar = citizen.metabSugar;
		else this.metabSugar = mate.metabSugar;

		if( (int)(Math.random()*2) == 1 )
			this.metabSpice = citizen.metabSpice;
		else this.metabSpice = mate.metabSpice;
	}

and wealth:

private synchronized void transferWealth(Citizen citizen, Citizen mate)
	{
		int cSugar, mSugar, cSpice, mSpice;
		//int cSugar = citizen.sugar;
		//int mSugar = mate.sugar;
		if( GoLconst.INHERIT_INITIAL_WEALTH )
		{	cSugar = (int)(citizen.inheritSugar / 2);	//child inherits 1/2
			mSugar = (int)(mate.inheritSugar / 2);		//inheritance of parents
			cSpice = (int)(citizen.inheritSpice / 2);
			mSpice = (int)(mate.inheritSpice / 2);
		} else
		{	cSugar = (int)(citizen.sugar / 2);	//child inherits 1/2 of
			mSugar = (int)(mate.sugar / 2);		//all wealth of each parent
			cSpice = (int)(citizen.spice / 2);
			mSpice = (int)(mate.spice / 2);
		}
		this.inheritSugar = cSugar + mSugar;
		this.inheritSpice = cSpice + mSpice;
		citizen.sugar	-= cSugar;
		citizen.spice	-= cSpice;
		mate.sugar		-= mSugar;
		mate.spice		-= mSpice;
	}

But others, however, notably persona — the propensity of the citizen to 'take risks' — are not inherited; instead, they're set randomly:

	public synchronized  int setPersona()
	{	if( GoLconst.PERSONALITY_RATIO > (float)Math.random() )
			return 1;	//gambler
		else return 0;	//cautious or risk averse
	}

But wait! Poor citizens are always cautious:

	/**
	 * Returns true, if the personality type for the citizen is risk-averse 
	 * 	OR
	 * below the poverty level as defined by GoLconst.SUGAR_LEVEL_POOR and
	 * GoLconst.SPICE_LEVEL_POOR 
	 */
	public boolean isCautious()
	{	return ( (persona==0) || isPoor() );	}
	
	/**
	 * Returns true if sugar or spice consumption units are less than or equal to 
	 * wealth levels specified in the global constants (GoLconst.java) file.
	 */
	public boolean isPoor()
	{	return ( (spice <= GoLconst.SPICE_LEVEL_POOR) || 
				 (sugar <= GoLconst.SUGAR_LEVEL_POOR) );
	}

...so all citizens who don't have all of

  1. a surplus of Sugar (even if they don't use it), and
  2. a surplus of Spice (even if they don't use it), and
  3. persona type 1

will always be cautious. Clear?

I mean, to be honest, I think that's a bug. I think that only citizens who have a high metabolic consumption of a foodstuff together with a low stock of that foodstuff should be considered poor. I also don't see why poor citizens should always be cautious; that isn't what we see in the real world. But it's a very convenient bug to leave in if you're trying to prove that greed is natural.

Citizens can move through the world, although, confusingly, the methods which allow this are not methods of the citizen but of the world. Two citizens can never occupy the same cell. When a citizen arrives in a cell, the citizen harvests any food that is there.

Citizens die when

  1. they reach old age; or
  2. they run out of food.

When they die, their wealth is distributed among their children:

			if( !citizen.isAlive() )	//citizen has reached lifespan
			{	if( GoLconst.DEBUG || GoLconst.DEBUG_CITIZEN_DEATH)
				{	showCitizenStats("Died! Old Age",citizen); }

				if( GoLconst.INITIATE_INHERITANCE )
					disburseInheritance(citizen);

				citizen.setCauseOfDeath("Old Age");
				deathList.add(citizen);
				cell[i][j].citizen = null;	//citizen killed
				population--;
				continue;
			}

			if( !( citizen.eatSugar() && citizen.eatSpice() ) )
			{	if( GoLconst.INITIATE_INHERITANCE )
					disburseInheritance(citizen);

				citizen.setCauseOfDeath("Starvation" + (citizen.getSugar() < 0 ? " sugar" : " spice") );
				if( GoLconst.DEBUG || GoLconst.DEBUG_CITIZEN_DEATH)
				{	showCitizenStats("Died! " + citizen.getCauseOfDeath(), citizen); }

				deathList.add(citizen);
				cell[i][j].citizen = null;	//citizen killed
				population--;
				continue;
			}

Citizens mate only when they have surplus, so poorer citizens get substantially fewer mating opportunities (this is fairly reasonably given that in most of the real world, wealth plays a significant part in being able to raise children to adulthood):

			// ** Go Forth & Multiply
			if( citizen.ofMatingAge() && citizen.hasSurplus()
							&& cellNMatesAvailable(citizen) )
			{	if( mateList.size() > 1 )
				{	shuffleMates();
					pickMate();
				}
				if( mate != null )
				{	bearChild(citizen, mate, destinationI, destinationJ);
					mateList.clear();
					mate = null;
				}
			}

As poorer citizens are also much more likely to die younger through starvation, the better breeding success of richer citizens is pretty much baked into the model.

Otherwise, they roam around aiming for the cell within their vision which has the greatest quantity of the particular foodstuff they need.

When a citizen encounters another citizen, they can barter — but only if the two of them prefer different food types (and each has surplus of the foodstuff the other wants). The personae of the citizens has some effect on their propensity to barter.

The price at which the foodstuffs are traded is based on the relative value to the two citizens of the 'Marginal Rate of Substitution' of the two commodities — in other words, how badly the citizen needs the commodity in order to survive.

	/**
	 * Calculates value. Represents the Marginal Rate of Substitution of spice for 
	 * each unit of sugar. Calculated by deriving the consumption units of spice (spUnits) 
	 * and sugar(suUnits).
	 * 	consumption unit = quantity / metabolism
	 * MRS is then derived by dividing spUnits by suUnits. MRS results less than 1 
	 * signify a preference for spice, results greater than 1 conversely indicate a 
	 * preference for sugar. 
	 * 
	 */
	public float setMRS()		
	{	MRS = (spice/metabSpice) / (sugar/metabSugar);
		return MRS;
	}

The code around trading is so convoluted that I cannot easily say whether the pricing algorithm gives a significant advantage to the trader with most surplus — as it would in the real world — but I think that it does not. But 'poor' (see above) citizens are always cautious and will consequently always trade less, even where it would be in their advantage to trade more.


I've gone through all that in detail, because I want to show you that the conclusions Epstein and Axtell derived from their study are just the assumptions they put into it. Citizens inherit not only wealth, but also their vision (which enables them to see food further away), and the rates at which they metabolise sugar and spice. It takes no intelligence at all to realise that, in this world, children of parents with excellent vision and low metabolic rate are going to have a significant advantage, and as in this world there is absolutely no model for either charity or mutual aid, successful citizens in this world will simply pile up more, and more, and more wealth — regardless of the fact that they can never use it — while those with poor vision and high metabolism will wander round in circles in barren zones and quickly starve.


In the podcast, Manda asked whether it would be possible to modify the model to add mutual aid, and see how that would change the outcome. The answer is that, yes, it would; but I think the codebase is in such a state that it will not be either productive or persuasive for me to do this.

Instead, what I'm thinking of doing is to take my own MicroWorld finite state automaton, add a layer to model flows, and then build three (or four) different rule sets:

  1. One which models owner-occupiers without mutual aid, i.e. each notional agent harvests as much food as is can from the cells adjacent to its home, and hoards any surplus. My expectation is that this will result in agents on good land doing well, while agents everywhere else will do poorly and ultimately starve.
  2. One which models a rentier class, where rentier agents tax the primary producer agents in their vicinity, and hoard the surplus. My expectation here is that either you will end up with a landscape of a few enormously wealthy rentiers and a starving peasantry, or else a total population crash.
  3. One which models mutual aid, in which each agent who has a surplus will donate part of that surplus to their poorest immediate neighbour. My expectation here is that this will tend to lead to the highest sustained populations of any of the models, and that the difference in wealth between the richest and the poorest will ultimately be very small.
  4. A fourth model, with a peasantry practicing mutual aid but with an aristocracy extracting rent as a superstructure, could also be explored. I would guess that would need very fine tuning to prevent population crashes.

The point here is not that this will 'prove' that mutual aid is better than rapacious greed. A best, what comes out of a model is only as good as the quality of the abstraction from reality you put into the model; and even if my experiment does show that mutual aid produces the highest stable population, those who believe in capitalism will cry foul, pointing out that I am, like Kropotkin, an anarcho-syndicalist.

Tags: Software Anarchism

« Riese und Müller Load 4 75: brief review | | Extreme poverty »

This site does not track you; it puts no cookies on your browser. Consequently you don't have to click through any annoying click-throughs, and your privacy rights are not affected.

Wouldn't it be nice if more sites were like this?

About Cookies