The Locked Web is out on Kindle – plus an easter egg
Last year, I was invited to join the Future Chronicles project as a contributing author. If you haven’t heard of it, the Future Chronicles is one of the best things to happen to independent science fiction in recent years – a huge project with dozens of contributors, publishing anthologies with crazy names such as The Robot Chronicles and CLONES: The Anthology. I was invited to write a story for the second alternate history title, Alt.history 102.
Alt.history 102 came out in January 2016 and immediately attracted great reviews. Part of the deal is that Future Chronicles authors are entitled to republish their stories independently after a period of three months. With life being what it is, the three-month threshold slipped by forgotten, and only at the end of June did I remember that I had not yet published The Locked Web independently.
It has been available for site members for some days already, but I’m pleased to announce that The Locked Web is now available to purchase on Amazon Kindle for 99p. You can find it here (UK) or here (US). If you enjoy reading it, please leave a 5* review; reviews are worth their figurative weight in gold for authors, and help make a title successful.
About The Locked Web
Eric just wants to have a place in society. But in a Britain where disabled people are ignored and sidelined, his only connection with people who share his interests is through the Academic Subnet – the last computer network free of government control. Until now.
Today, the Web is the cornerstone of our entire society. But what if the technology had failed to take off? What would the world of 2015 look like without the transformative power of the Information Age?
The Web is a potent tool of freedom that has gradually liberated power away from governments and placed it in the hands of ordinary people, but only because it is universal and unregulated, not controlled by governments or vested interests. It’s easy to take the Web for granted in the present day, but without it we would be less informed, less empowered, and less able to communicate with others. At a time when net neutrality is under threat, we must make it a priority to safeguard the freedom it has given us.
“Fantastic characters and a compelling plot in this story. Roddie did an amazing job of world-building in such a short amount of time. Well done, and a great way to end another top notch anthology.”
– Amazon reviewer
“Eric is a highly sympathetic character, an everyman, tired of the frustrations in his life and tries to do something about it.”
– Amazon reviewer
“This parallel present-day UK is still in the grip of the Cold War and computers have never evolved much beyond the early Eighties. The disabled protagonist and his family are very believable and engaging.”
– David Wailing, author and editor
“It’s hard to believe that in some places, censorship as shown in this story actually does exist today, making this story even more frightening, fueling the imagination with the thought of being locked up for daring to communicate thoughts and ideas.”
– Amazon reviewer
Easter Egg – Cobra Mist simulator source code!
While we’re talking cyberpunk and science fiction, I think it’s time I gave the geeks amongst you something to tinker with! Ten years ago, when I was studying computer science at university and learning how to code in Java, I wrote a simple program to simulate the Cobra Mist computer. This is the software that appears in my short story Cold Witness. I have listed the source code below; feel free to experiment! It will run directly in the terminal on any UNIX-like system, or in any Java IDE.
You can download your copy of Cobrasim.java here. This is open-source code so if you’d like to modify and improve it then knock yourself out.
/*
--------------------------------------------------------
/ / / C O B R A M I S T S I M U L A T O R \ \ \
--------------------------------------------------------
This is a simple Java program which acts as a simulator for the Cobra Mist
facility, with (fictional) modifications as described in the scifi short story
_Cold Witness_ by Alex Roddie. For historical background on System 441-A, see
this Wikipedia entry: https://en.wikipedia.org/wiki/Cobra_Mist
In _Cold Witness_, the original over-the-horizon radar set was modified to
operate as an anti-satellite energy weapon. A conspiracy theory states that the
system's potential as a weapon platform was discovered by accident, and that it
was gradually enhanced and upgraded over the years after it was ostensibly
decommissioned – at great cost. Whatever the truth of the matter, System 441-A
never functioned correctly and had severe reliability issues throughout its
lifespan.
This program emulates these reliability issues, as you will discover when you
compile and run the software!
To compile, copy this source code to a file named Cobrasim.java in your working
directory. On UNIX-like systems, open the terminal, navigate to the correct
directory using the cd command, and type the following command to compile the
program:
javac Cobrasim.java
This will produce a compiled class called Cobrasim.class. To run the software,
make sure you are in the correct working directory, and type the following
command:
java Cobrasim
This is meant to be a bit of fun for readers who liked my short story. For
authentic 1980s-style results, I recommend the retro-style OS X terminal
application Cathode. It works just fine in the standard OS X or Linux terminal,
though.
*/
import java.util.*;
import java.lang.Double;
import java.lang.*;
import java.io.*;
public class Cobrasim {
static boolean isRadarOnline;
static boolean isPowerOnline;
static boolean facilityIsDestroyed;
static boolean verbose;
static boolean matrixIsOnline;
static boolean amplifiersOnline;
static boolean stringsPhasing;
static boolean targetLocked;
static int targetAzimuth;
static int targetElevation;
static int targetMass;
static int targetRange;
static int frequency;
static double currentPower;
static double maxPower;
static double desiredPower;
static double destructionPower;
static boolean[] string = new boolean[19];
static boolean[] amplifier = new boolean[7];
static int[] activeStrings = new int[7];
public Cobrasim() {
}
public static void main(String[] args) throws IOException, Exception {
isRadarOnline = false;
isPowerOnline = false;
currentPower = 0;
maxPower = 10.00;
desiredPower = 0;
destructionPower = 21.00;
facilityIsDestroyed = false;
int i = 1;
while (i <= 18) {
string[i] = false;
i++;
}
i = 1;
while (i <= 6) {
amplifier[i] = true;
i++;
}
i = 1;
while (i <= 6 ) { activeStrings[i] = 0; i++; } frequency = 0; verbose = false; matrixIsOnline = false; amplifiersOnline = false; System.out.println("> 441-A SHELL VERSION v.8.2.2 (C) HARRY MORGAN 1979");
System.out.println("-------------------------------------------------");
System.out.println("> AUTO-FIRING SCRIPT v.1.0 NOW RUNNING....");
java.lang.Thread.sleep(1000);
activateTargetingRadar();
java.lang.Thread.sleep(1000);
activatePowerGrid();
java.lang.Thread.sleep(1000);
energiseAmplifiers(8.00);
java.lang.Thread.sleep(1000);
getTarget();
java.lang.Thread.sleep(1000);
activateBeamSwitchingMatrix();
java.lang.Thread.sleep(1000);
phaseStrings();
java.lang.Thread.sleep(1000);
shootTarget();
}
public static void activateTargetingRadar() throws Exception{
isRadarOnline = true;
System.out.println("--- T A R G E T I N G R A D A R A R R A Y S T A T U S ---");
System.out.println("> FETCHING DATA...");
java.lang.Thread.sleep(2000);
System.out.println("> TARGETING RADAR ONLINE");
java.lang.Thread.sleep(1000);
System.out.println("|| POWER\tFREQUENCY\tGAIN");
System.out.println("|| KW\tMHZ\t\tDB");
System.out.println("|| --------------------------------");
System.out.println("|| " + (int)((Math.random() * 20) + 80) + "\t" + (int)((Math.random() * 5) + 15) + "\t\t25");
System.out.println(">");
}
public static void getTarget() throws IOException, Exception {
try {
if (!facilityIsDestroyed) {
if (isRadarOnline) {
targetAzimuth = (int)((Math.random() * 91) + 19.5);
targetElevation = (int)((Math.random() * 175) + 5);
System.out.println("--- T A R G E T I N G I N T E R F A C E ---");
System.out.println("> SCANNING FOR TARGETS...");
java.lang.Thread.sleep(2000);
System.out.println("|| ID\tAZIMUTH\tELEVATION\tMASS\tRANGE");
System.out.println("|| \tDEG.\tDEG.\t\tKG\tNMI");
System.out.println("|| ---------------------------------------------------");
int j = 1;
int[] jtargets = new int[15];
int[] azimuths = new int[15];
int[] elevations = new int[15];
int[] masses = new int[15];
int[] ranges = new int[15];
while (j < (int)(Math.random() * 15)) { jtargets[j] = j; azimuths[j] = (int)((Math.random() * 72) + 19.5); elevations[j] = (int)((Math.random() * 175) + 5); masses[j] = (int)((Math.random() * 500) + 70); ranges[j] = (int)(Math.random() * 2000); System.out.println("|| " + j + " \t" + azimuths[j] + " \t" + elevations[j] + " \t\t" + masses[j] + " \t" + ranges[j]); j++; jtargets[j] = j; } System.out.println(">");
System.out.println("> SELECT TARGET TO LOCK - TYPE THE ID AND PRESS RETURN");
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("> ");
String inLine = inReader.readLine();
if (Integer.parseInt(inLine) > j) {
System.out.println("> INVALID TARGET ID");
inLine = inReader.readLine();
System.out.print(">");
} else {
targetAzimuth = azimuths[Integer.parseInt(inLine)];
targetElevation = elevations[Integer.parseInt(inLine)];
targetMass = masses[Integer.parseInt(inLine)];
targetRange = ranges[Integer.parseInt(inLine)];
System.out.println("> TARGET LOCKED");
System.out.println("|| AZIMUTH " + targetAzimuth + " DEGREES");
System.out.println("|| ELEVATION " + targetElevation + " DEGREES");
System.out.println("|| MASS " + targetMass + " KG");
System.out.println("|| RANGE " + targetRange + " NMI");
targetLocked = true;
}
} else {
System.out.println("--- E X C E P T I O N ---");
System.out.println("> TARGETING RADAR IS OFFLINE");
System.out.println(">");
}
} else {
System.out.println("! Simulation message: Unable to aquire target - Facility Destroyed");
}
} catch (IOException ioe) {
System.out.println("! Simulation message: IO Exception" + ioe.getMessage());
}
}
public static void activatePowerGrid() throws Exception {
if (!facilityIsDestroyed) {
isPowerOnline = true;
System.out.println("--- M A I N P O W E R S T A T U S ---");
System.out.println("> GENERATORS RESPONDING...");
java.lang.Thread.sleep(3000);
System.out.println("> MAIN POWER GRID ONLINE");
System.out.println("> CHECKING LINEAR-TRANSMITTER AMPLIFIERS...");
int i = 1;
while (i <= 6) { if (amplifier[i] == true) { java.lang.Thread.sleep(((int)Math.random() * 1000)); System.out.println("|| LINEAR AMPLIFIER " + i + " OKAY"); i++; } } System.out.println(">");
} else {
System.out.println("! Simulation message: Unable to activate power grid - Facility Destroyed");
}
}
public static void energiseAmplifiers(double desiredPower) {
if (isPowerOnline == true) {
amplifiersOnline = true;
System.out.println("--- L I N E A R A M P L I F I E R S T A T U S ---");
while(currentPower < desiredPower) { currentPower = currentPower + (Math.random() / 100); if (verbose) { System.out.println("|| " + currentPower + " MW"); } } double qualifier = Math.random(); if (Math.random() > 0.5) {
System.out.println("> POWER EXCEEDING PARAMETERS");
while(currentPower < maxPower) { currentPower = currentPower + Math.random(); if (verbose) { System.out.println("|| " + currentPower + " MW"); } } System.out.println("> POWER APPROACHING TOLERANCE LEVELS");
qualifier = Math.random();
} if (Math.random() < 0.5) { if (currentPower > maxPower) {
while(currentPower < destructionPower) { currentPower = currentPower + Math.random(); if (verbose) { System.out.println("|| " + currentPower + " MW"); } } System.out.println("> POWER EXCEEDING TOLERANCE LEVELS!");
System.out.println("|| " + currentPower + " MW");
qualifier = (Math.random() * 6);
if (qualifier < 6 && qualifier > 5) {
if (amplifier[1] == true) {
System.out.println("> LINEAR AMPLIFIER 1 FAILURE");
amplifier[1] = false;
}
} else if (qualifier < 5 && qualifier > 4) {
if (amplifier[2] == true) {
System.out.println("> LINEAR AMPLIFIER 2 FAILURE");
amplifier[2] = false;
}
} else if (qualifier < 4 && qualifier > 3) {
if (amplifier[3] == true) {
System.out.println("> LINEAR AMPLIFIER 3 FAILURE");
amplifier[3] = false;
}
} else if (qualifier < 3 && qualifier > 2) {
if (amplifier[4] == true) {
System.out.println("> LINEAR AMPLIFIER 4 FAILURE");
amplifier[4] = false;
}
} else if (qualifier < 2 && qualifier > 1) {
if (amplifier[5] == true) {
System.out.println("> LINEAR AMPLIFIER 5 FAILURE");
amplifier[5] = false;
}
} else if (qualifier < 1) { if (amplifier[6] == true) { System.out.println("> LINEAR AMPLIFIER 6 FAILURE");
amplifier[6] = false;
}
}
}
if (currentPower > destructionPower) {
facilityIsDestroyed = true;
System.out.println("! Simulation message: Facility Destroyed due to power overload"); }
}
if (!facilityIsDestroyed) {
System.out.println("> POWER STABILISED AT:");
System.out.println("|| " + currentPower + " MW");
}
} else {
System.out.println("> POWER IS OFFLINE - UNABLE TO COMPLY");
System.out.println(">");
}
}
public static void activateBeamSwitchingMatrix() {
if (!facilityIsDestroyed) {
if (isPowerOnline && amplifiersOnline) {
matrixIsOnline = true;
System.out.println("--- B E A M S W I T C H I N G M A T R I X S T A T U S ---");
System.out.println("> BEAM SWITCHING MATRIX ENERGISED AT " + (int)currentPower + " MW");
System.out.println(">");
} else {
System.out.println("> POWER IS OFFLINE - UNABLE TO COMPLY");
System.out.println(">");
}
} else {
System.out.println("! Simulation message: Unable to activate beam switching matrix - Facility Destroyed");
}
}
public static void phaseStrings() throws IOException {
if (!facilityIsDestroyed) {
if (isPowerOnline && amplifiersOnline && matrixIsOnline) {
int startingString;
int currentString;
int x = 95;
int y = 1;
int z;
while (y <= 18) {
x = x - 4;
if ((targetAzimuth <= x) && (targetAzimuth >= (x - 4))) {
startingString = y;
currentString = startingString;
z = 1;
if (currentString <= 13) {
while (z <= 6) {
activeStrings[z] = currentString;
currentString++;
z++;
}
}
else {
currentString = 13;
while (z <= 6) { activeStrings[z] = currentString; currentString++; z++; } } } y++; } int elev = 5; int freq = 41; int counter = 35; while (counter != 0) { if ((targetElevation >= elev) && (targetElevation <= (elev + 5))) { freq = freq - counter; } elev = elev + 5; counter--; } frequency = freq; System.out.println("--- L O G - P E R I O D I C A R R A Y S T A T U S ---"); System.out.println("> TARGET AZIMUTH = " + targetAzimuth + " DEGREES");
System.out.println("> REQUIRED STRING SET TO PAINT TARGET:");
System.out.println("|| " + activeStrings[1] + " TO " + activeStrings[6]);
System.out.println("> TARGET ELEVATION = " + targetElevation + " DEGREES");
System.out.println("> REQUIRED BEAM FREQUENCY:");
System.out.println("|| " + frequency + " MHZ");
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("> LOG-PERIODIC ARRAY ON STANDBY");
System.out.println("> PRESS ANY KEY TO BEGIN PHASING STRINGS "+ activeStrings[1] + " TO " + activeStrings[6]);
System.out.print("> ");
String inLine = inReader.readLine();
if (inLine != null) {
if (Math.random() < 0.7) { System.out.println("> STRINGS "+ activeStrings[1] + " TO " + activeStrings[6] + " NOW PHASING AT " + frequency + " MHZ AND " + (int)currentPower + " MW");
System.out.println("> ");
stringsPhasing = true;
}
else {
System.out.println("> SHOCKWAVE FRACTURES DETECTED IN STRING " + (activeStrings[1] + ((int)Math.random() * 6)));
System.out.println("> LOG-PERIODIC ARRAY OFFLINE");
facilityIsDestroyed = true;
}
}
} else {
System.out.println("> POWER IS OFFLINE - UNABLE TO COMPLY");
System.out.println(">");
}
} else {
System.out.println("! Simulation message: Unable to phase strings - Facility Destroyed");
}
}
public static void shootTarget() {
if (stringsPhasing == true) {
System.out.println("--- W E A P O N F I R I N G C O N T R O L ---");
System.out.println("> CURRENT STATUS:");
System.out.println("|| T A R G E T");
System.out.println("|| ATTRIBUTE\tVALUE\tUNIT");
System.out.println("|| ---------------------------------");
System.out.println("|| AZIMUTH\t" + targetAzimuth + "\tDEGREES");
System.out.println("|| ELEVATION\t" + targetElevation + "\tDEGREES");
System.out.println("|| MASS\t" + targetMass + "\tKG");
System.out.println("|| RANGE\t" + targetRange + "\tNMI");
System.out.println("|| POWER\t" + (int)currentPower + "\tMW");
System.out.println("|| ");
System.out.println("|| A C T I V E S T R I N G S");
System.out.println("|| ATTRIBUTE\tVALUE\tUNIT");
System.out.println("|| ---------------------------------");
int i = 1;
while (i <=6) {
System.out.println("|| " + activeStrings[i] + " " + frequency + "\tMHZ");
i++;
}
}
}
}
Alex Roddie Newsletter
Join the newsletter to receive the latest updates in your inbox.