diff --git a/frontend/src/js/fight_scene.ts b/frontend/src/js/fight_scene.ts
index 67c0c67ad64daba3002bb36f822c5410a8ed0335..e16f7164d71809e4c47b3013b6a743b139950d4c 100644
--- a/frontend/src/js/fight_scene.ts
+++ b/frontend/src/js/fight_scene.ts
@@ -18,6 +18,8 @@ interface InputStatus {
   ended_at: string;
   typed: string;
   final: string;
+  began_at_gmtm: number;
+  ended_at_gmtm: number;
 }
 
 export default class FightScene extends Phaser.Scene {
@@ -30,6 +32,7 @@ export default class FightScene extends Phaser.Scene {
   score: number;
   health: number;
   hud: HUD;
+  gameTime: Phaser.Time.TimerEvent;
 
   constructor() {
     super("fight");
@@ -83,6 +86,11 @@ export default class FightScene extends Phaser.Scene {
   }
 
   async create() {
+    this.gameTime = this.time.addEvent({
+      delay: Number.MAX_SAFE_INTEGER,
+      paused: true,
+    });
+
     this.initCluesGroup();
 
     this.createAnimations();
@@ -123,6 +131,7 @@ export default class FightScene extends Phaser.Scene {
     await this.initBeDevice();
     await this.initBeGame();
 
+    this.gameTime.paused = false;
     this.spawnFoes();
   }
 
@@ -140,6 +149,7 @@ export default class FightScene extends Phaser.Scene {
     this.beGame = (
       await backend.createGame(this.beDevice.id, {
         began_at: new Date().toISOString(),
+        began_at_gmtm: this.getGameTime(),
       })
     ).data;
   }
@@ -212,11 +222,7 @@ export default class FightScene extends Phaser.Scene {
   }
 
   update(time: number, delta: number): void {
-    // TODO: please do not parse a date every few milliseconds
-    if (this.beGame?.began_at)
-      this.hud.setClock(
-        new Date().getTime() - Date.parse(this.beGame.began_at),
-      );
+    this.hud.setClock(this.getGameTime());
   }
 
   checkAlive() {
@@ -228,6 +234,7 @@ export default class FightScene extends Phaser.Scene {
     this.beGame = (
       await backend.updateGame(this.beGame.id, {
         ended_at: new Date().toISOString(),
+        ended_at_gmtm: this.getGameTime(),
       })
     ).data;
     this.foes.forEach((foe) => foe.destroy());
@@ -315,6 +322,7 @@ export default class FightScene extends Phaser.Scene {
     } else {
       backend.updateClue(match.beClue.id, {
         ended_at: new Date().toISOString(),
+        ended_at_gmtm: this.getGameTime(),
       });
       this.updateScore(+10);
       this.popFoe(match);
@@ -334,9 +342,12 @@ export default class FightScene extends Phaser.Scene {
       this.typewriter.setHidden(false);
       this.typewriter.setShiftModeOneShot();
     }
+    this.typewriter.getGameTime = this.getGameTime.bind(this);
     this.typewriter.onSubmit = async (inputStatus) => {
       if (inputStatus.began_at === null) return;
       if (inputStatus.ended_at === null) return;
+      if (inputStatus.began_at_gmtm === null) return;
+      if (inputStatus.ended_at_gmtm === null) return;
       if (inputStatus.final === "") return;
       this.hud.setInput("");
       this.submitTranscription({
@@ -344,6 +355,8 @@ export default class FightScene extends Phaser.Scene {
         ended_at: inputStatus.ended_at.toISOString(),
         typed: inputStatus.typed,
         final: inputStatus.final,
+        began_at_gmtm: inputStatus.began_at_gmtm,
+        ended_at_gmtm: inputStatus.ended_at_gmtm,
       });
     };
     this.typewriter.onChange = (inputStatus) => {
@@ -356,8 +369,9 @@ export default class FightScene extends Phaser.Scene {
     // TODO: think of a progression which makes sense
     const delay = Math.max(
       2000,
-      (8 * 1000 * (60 * 1000 - this.time.now)) / 60 / 1000 + 2 * 1000,
+      (8 * 1000 * (60 * 1000 - this.getGameTime())) / 60 / 1000 + 2 * 1000,
     );
+    // TODO: it should be ok calling this on time instead of gameTime, but... is it?
     this.time.delayedCall(delay, this.spawnFoes.bind(this));
   }
 
@@ -372,4 +386,10 @@ export default class FightScene extends Phaser.Scene {
   uncoverClues() {
     this.foes.forEach((foe) => foe.clue.uncover());
   }
+
+  getGameTime() {
+    // NOTE: we don't need sub-ms precision.
+    // NOTE: pretty please, don't access the timer directly.
+    return Math.round(this.gameTime.getElapsed());
+  }
 }
diff --git a/frontend/src/js/foe.ts b/frontend/src/js/foe.ts
index cc0624efb7bc1da2ee962b68a7d9337b01a96134..9b1599b63d6973f69988f4dc148c0cdfad944365 100644
--- a/frontend/src/js/foe.ts
+++ b/frontend/src/js/foe.ts
@@ -28,6 +28,7 @@ class Foe {
       await backend.createClue(this.scene.beGame.id, {
         word_id: this.beWord.id,
         began_at: new Date().toISOString(),
+        began_at_gmtm: this.scene.getGameTime(),
       })
     ).data;
 
diff --git a/frontend/src/js/typewriter.ts b/frontend/src/js/typewriter.ts
index 45eb1460104371929f85706113e4ceabf218c9b0..dcfad09974b7a879768cf730022bbf11f0bfc13b 100644
--- a/frontend/src/js/typewriter.ts
+++ b/frontend/src/js/typewriter.ts
@@ -6,6 +6,8 @@ interface InputStatus {
   ended_at: Date | null;
   typed: string;
   final: string;
+  began_at_gmtm: number | null;
+  ended_at_gmtm: number | null;
 }
 
 enum Key {
@@ -114,6 +116,7 @@ class Typewriter {
 
   onChange: (inputStatus: InputStatus) => unknown;
   onSubmit: (inputStatus: InputStatus) => unknown;
+  getGameTime: () => number; // NOTE: sigh.
 
   constructor() {
     this.onChange = () => {};
@@ -124,6 +127,8 @@ class Typewriter {
       ended_at: null,
       typed: "",
       final: "",
+      began_at_gmtm: null,
+      ended_at_gmtm: null,
     };
 
     this.keyboard = new Keyboard({
@@ -181,11 +186,15 @@ class Typewriter {
     event: KeyboardEvent | PointerEvent | MouseEvent | TouchEvent,
   ) {
     const key = this.extractKeyfromEvent(event);
-    if (!this.inputStatus.began_at) this.inputStatus.began_at = new Date();
+    if (this.inputStatus.began_at === null)
+      this.inputStatus.began_at = new Date();
+    if (this.inputStatus.began_at_gmtm === null)
+      this.inputStatus.began_at_gmtm = this.getGameTime();
     if (key === Key.Enter) {
       this.keyboard.clearInput();
       this.inputStatus.typed += "\n";
       this.inputStatus.ended_at = new Date();
+      this.inputStatus.ended_at_gmtm = this.getGameTime();
       this.onSubmit(this.inputStatus);
       this.resetInputStatus();
     } else if (key === Key.Backspace) {
@@ -210,6 +219,8 @@ class Typewriter {
       ended_at: null,
       typed: "",
       final: "",
+      began_at_gmtm: null,
+      ended_at_gmtm: null,
     };
   }