An Old Memory of War
Sara He
instructor: Andy Garcia
Conception & Design
theme and form
My project revolves around the theme of war, attempting to immerse users in the chaotic scenes of battle through an interactive game where they take on the role of commanders who can shape the destinies of individuals. Aiming for a stronger sense of immersion and aesthetics in this game, I envision it to be reminiscent of an old movie.
The reason behind the theme of war was the increasing frequency of wars in recent years and the intensifying international situation. In this era of globalization, our connections span across diverse corners of the globe, rendering each country no longer an isolated island. But simultaneously, more connections mean that what’s happening in some distant nations today may happen to us in the future. So I wanted to create something to prompt people to think about wars.
Originally, my idea was to make an interactive device with the setting of a ruined city where a bell would be placed at the center, and also included the use of wearable devices allowing users to receive slight electric shocks. The original name of it was For Whom the Bell Tolls, which is the name of a poem.
(original draft of my idea)
After the individual meeting with my instructor, I changed my idea and decided to make my project a movie-like game. My instructor Andy told me a history story of a commander who refused to launch a nuclear attack and saved the world from nuclear war. I got inspired from this story and combine it with my another idea, which was to make a short video.
(Draft and flow chart: second version)
Basically, the project tells a story about three commanders jointly deciding the next step of military action in face of potential dangers caused by the enemy state. The choices would become increasingly hard to make and users may also communicate with other commanders which brings the interaction from simply human and computer to human and other humans. The message I want to convey is that the real world is not only black and white but a million shades of gray, which makes us inevitably pay the price for the decisions we make. And when it comes to war, the cost will be more painful.
(Flow chart:final version)
User experience
During the user test, users offered me several suggestions:
- Change the background so that the users can see the subtitles more clearly.
- Add options on subtitles. (eg. Attack-yes Retreat-no)
- In the original design, users did not need a stamp when selecting one of the options. They only needed to wait for the corresponding time and the program would run to the next scenario. But user suggested me to change wait to stamp on another option.
- Reduce the length of reading and increase the time available for making decisions.
I deemed that these suggestions were all very helpful for improving my project so I made adjustments based on them.
(Notes I took during the User Testing Session)
Fabrication & Production
Prototyping
(Draft:final version)
The serial communication of my work is from Arduino to Processing, which is mainly presented through the computer screen, so the prototype is relatively simple.
The stamp was made by 3D printing and here is the simple 3D modeling I made on Tinkercad.
I used copper tape on the phone and the stamp and use “digitalRead” to measure different situations. For the phone, I need to play phone recording when the user pick up the phone. Thus, I think using copper tape would be a good choice. At first, I wanted to stamp on pressure sensor and I tested it. However, I found that the bottom of my stamp was so flat and smooth that the sensor couldn’t detect the pressure accurately. Thus, I gave up using this sensor and turned to copper tape.
As for the switches, I use three slide pots.
In the end, I made a wooden box on cutter.xyz and put Arduino Uno and the breadboard into it.
(details)
Coding
The coding aspect is a noteworthy portion of the entire creative process for my project. Given the diverse range of scenes in my work, it is important to rely on program execution to support the narrative development. At the same time, coding, in comparison to physical interactions, poses the most challenging aspect for me. I am particularly grateful for the assistance provided by my professor, Andy, and learning assistant, Rachel.
The day before Thanksgiving, Rachel dedicated her time to help me refine my code. This effort left a lasting impression on me. My code incorporates numerous if statements, especially when considering various elements such as time, sound, images, and text. This complexity makes the coding process exceptionally challenging and took me a long time to continuously refine it. (It’s hard to conclude what specific failure I met because there were always mistakes in my code and I failed so many times…)
I put the full code in the appendix.
(Some interesting moments)
Conclusions
Goal of the project
Any decision comes with a price. When it comes to war, you’re never going to make a perfect decision. In the context of war, you can never make a perfect choice and it’s always like a trolley problem. It boils down to sacrificing the lives of these people or those, sacrificing this city or that. And the real world is not only black and white but a million shades of gray, which means that it’s impossible to always be the hero who saves the whole world and we inevitably pay the price for the decisions we make. Through interaction, I want audience to rethink about the decisions they’ve made and to some extend, realize the cruelty of reality, especially war.
Audience’s response
I am delighted to observe that during my presentation of the work, three users had differing opinions on the final question of whether to launch the missile. One of them opted not to launch, refraining from toggling the switch to the topmost position. Witnessing different choices among users and the ensuing exchange was interesting, as it extended human-computer interaction to the realm of communication among people.
Things I would do if I have more time
1. Expand the plot to make it more complex. Enhance the connectivity between choices and introduce divergent plot lines for different options.
2. Improve my prototype to make it look better.
Disassembly
Appendix
Full code
Arduino:
int SENSOR_PIN = 2; //paper
int sensorValue0; //phone
int sensorValue1; //stamp1
int sensorValue2; //stamp2
int SENSOR_PIN1 = A1; //slide pot1
int SENSOR_PIN2 = A2; //slide pot2
int SENSOR_PIN3 = A3; //slide pot3
int sensorValue3;
int sensorValue4;
int sensorValue5;
void setup() {
Serial.begin(9600); // initialize serial communication at 9600 bits per second:
pinMode(2, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(13, OUTPUT);
}
void loop() {
sensorValue0 = digitalRead(2); // phone
sensorValue1 = digitalRead(8); // stamp1
sensorValue2 = digitalRead(12); // stamp1
sensorValue3 = analogRead(A1);
sensorValue4 = analogRead(A2);
sensorValue5 = analogRead(A3);
Serial.print(sensorValue0); //send arduino_values[0]
Serial.print(",");
Serial.print(sensorValue1); //send arduino_values[1]
Serial.print(",");
Serial.print(sensorValue2); //send arduino_values[2]
Serial.print(",");
Serial.print(sensorValue3);
Serial.print(",");
Serial.print(sensorValue4);
Serial.print(",");
Serial.print(sensorValue5);
Serial.println();
delay(20);
}
import processing.serial.*;
import processing.sound.*;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 6; /* CHANGE THIS ACCORDING TO YOUR PROJECT */
float stage;
/* This array stores values from Arduino */
int arduino_values[]=new int[NUM_OF_VALUES_FROM_ARDUINO];
boolean stamped = false;
boolean all = false;
// declare a SoundFile object
SoundFile sound;
SoundFile sound1;
SoundFile sound2;
long time;
int timeleft;
PImage photo0;
PImage photo1;
PImage photo2;
PImage photo3;
PFont myFont;
boolean ringing = false;
boolean stage1 = false;
void setup() {
fullScreen();
//size(1200, 800);
background(0);
printArray(Serial.list());
serialPort = new Serial(this, "COM5", 9600);
sound = new SoundFile(this, "Telephone ringtone.mp3");
// sound.loop();
sound1 = new SoundFile(this, "phoneee.mp3");
sound2 = new SoundFile(this, "sadmoviesound.mp3");
stage = 0;
photo0=loadImage("Telephone-1.jpg");
photo1=loadImage("Europe.jpg");
photo2=loadImage("old1.jpg");
photo3=loadImage("raven1.jpg");
String[] fontList = PFont.list();
printArray(fontList);
myFont = createFont("Times New Roman Bold Italic", 30);
textFont(myFont);
}
void draw() {
getSerialData();
print(stage);
print(timeleft);
if (stage == 0) {
if (arduino_values[0] == 1) {
if (sound.isPlaying() == false) {
sound.loop();
}
}
if (arduino_values[0] == 0) {
ringing = true;
}
if (ringing == true) {
sound.stop();
image(photo0, 0, 0, width, height);
filter(BLUR, 4);
if (sound1.isPlaying() == false) {
sound1.play();
}
if (sound1.percent()> 90) {
time = millis();
stage = 1;
}
}
}
if (stage == 1) {
image(photo0, 0, 0, width, height);
filter(BLUR, 4);
timeleft = int(10 - (millis()-time)/1000);
textSize(40);
fill(0);
//fill(0, 408, 612);
text("yes: deploy", 100, 150);
text("no: not deploy", 100, 200);
textSize(32);
text(timeleft, 100, 100);
if (millis() - time <= 10000) {
if (arduino_values[1] == 1 && arduino_values[2] == 0) {
stage = 1.1; // stamp yes - deploy
time = millis();
} else if (arduino_values[2] == 1 && arduino_values[1] == 0 ) {
stage = 1.2; // stamp no - not deploy
time = millis();
}
}
}
if (stage == 1.1) {
if (millis() - time <= 10000) {
image(photo1, 0, 0, width, height);
filter(BLUR, 4);
fill(0);
textSize(36);
text("You deployed additional troops to help the city.", 80, 150);
} else {
stage1 = true;
stage = 2;
time = millis();
}
}
if (stage == 1.2) {
if (millis() - time <= 10000) {
image(photo1, 0, 0, width, height);
filter(BLUR, 4);
fill(0);
textSize(36);
text("Without your help, the city suffered great loss.", 80, 150);
text("Two days later, you had no choice but to lend a helping hand.", 80, 200);
} else {
stage1 = true;
stage = 2;
time = millis();
}
}
if (stage1 == true) {
if (sound2.isPlaying() == false) {
sound2.play();
}
}
if (stage == 2) {
if ( millis() - time <= 30000) {
image(photo1, 0, 0, width, height);
filter(BLUR, 4);
fill(0);
textSize(36);
timeleft = int(30 - (millis()-time)/1000);
text("City A is in danger, and you now have two choices: ", 80, 150);
text("Attack—stamp on yes ", 80, 200);
text("or Retreat—stamp on no", 80, 250);
text("Make a decision within 30 seconds. ", 80, 300);
fill(255);
textSize(32);
text(timeleft, 100, 100);
//time=millis();
if (arduino_values[1] == 1 && arduino_values[2] == 0) {
stage = 2.1; // stamp 1 - deploy
time = millis();
} else if (arduino_values[2] == 1 && arduino_values[1] == 0 ) {
stage = 2.2; // no stamp - no deploy
time = millis();
}
}
}
if (stage == 2.1) {
if (millis() - time <= 13000) {
image(photo1, 0, 0, width, height);
filter(BLUR, 4);
filter(GRAY);
fill(0);
textSize(32);
text("You saved the city,", 80, 150);
text("However, 10,000 soldiers were injured or lost their lives,", 80, 200);
text("and the military paid a grievous cost.", 80, 250);
} else {
stage = 3;
time = millis();
}
}
if (stage == 2.2) {
if (millis() - time <= 13000) {
image(photo1, 0, 0, width, height);
filter(BLUR, 4);
filter(GRAY);
fill(0);
textSize(32);
text("You chose to retreat, preserving our forces.", 80, 150);
text("However,without support,the civilians there lost their homes and became prisoners", 80, 200);
} else {
stage = 3;
time = millis();
}
}
if (stage == 3) {
if ( millis() - time <= 60000) {
timeleft = int(60 - (millis()-time)/1000);
image(photo3, 0, 0, width, height);
filter(BLUR, 4);
fill(255);
textSize(30);
text("The enemies are planning to launch a missile towards our capital city. ", 80, 150);
text("The only way to protect the capital is to launch a missile to a small town B, ", 80, 190);
text("The explosion of our missile will destroy theirs.", 80, 230);
text("Please discuss with each other and choose between launching or not", 80, 270);
text("Each of you can control a switch on the office desk", 80, 310);
text("The missile will only be launched when all the three switches are pushed to top.", 80, 350);
textSize(36);
fill(255, 0, 0);
text("Each of your decision matters.", 80, 390);
fill(255);
textSize(26);
text("You have 60 seconds to decide", 80, 430);
textSize(26);
text(timeleft, 100, 100);
} else if (arduino_values[3] == 0 && arduino_values[4] == 0 && arduino_values[5]==0) {
stage = 3.1; //
time = millis();
} else {
stage = 3.2; //
time=millis();
}
}
if (stage == 3.1) {
if (millis() - time <= 15000) {
image(photo3, 0, 0, width, height);
filter(GRAY);
fill(255);
textSize(32);
text("You defended the capital,the economic and political center.", 80, 150);
text("The innocent town B, was leveled to the ground.", 80, 200);
text("This inconspicuous small town made a mark in history simply because", 80, 250);
text("it became a sacrificial lamb to prevent the capital from being bombed.", 80, 300);
} else {
stage = 4;
}
}
if (stage == 3.2) {
if (millis() - time <= 15000) {
image(photo3, 0, 0, width, height);
filter(GRAY);
fill(255);
textSize(32);
text("Out of sympathy for this innocent town, you gave up launching the missile,", 80, 150);
text("As a result,the capital dissipated as a heavy price...", 80, 200);
text("The former glory of this place has been reduced to ruins.", 80, 250);
} else {
stage = 4;
}
}
if (stage == 4) {
image(photo3, 0, 0, width, height);
filter(GRAY);
fill(255);
textSize(32);
text("The people on this land endure the pain of war; ", 80, 150);
text("some struggle to survive, while others continue to become casualties.", 80, 190);
text("Every choice carries a corresponding cost.", 80, 230);
text("Faced with war, people make different decisions,", 80, 270);
text("awaiting the day when peace will come...", 80, 310);
} else {
}
}
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII
if (in != null) {
print("From Arduino: " + in);
String[] serialInArray = split(trim(in), ",");
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}
References
Telephone ringtone
image-telephone
image-background1
image-background2
sound-background music
template of box