Index: src/de/jacavi/appl/racelogic/RaceEngine.java
===================================================================
--- src/de/jacavi/appl/racelogic/RaceEngine.java	(revision 496)
+++ src/de/jacavi/appl/racelogic/RaceEngine.java	(working copy)
@@ -36,14 +36,12 @@
 
     private int raceTimerInterval = 0;
 
-    boolean isTimerRunning = false;
+    private boolean isTimerRunning = false;
 
     private Track track;
 
     private List<Player> players;
 
-    private RaceEngine() {}
-
     public void setPlayers(List<Player> players) {
         this.players = players;
     }
@@ -144,7 +142,7 @@
                 // get players hal connector
                 SlotCarSystemConnector slotCarSystemConnector = player.getSlotCarSystemConnector();
                 // get players controller signal
-                ControllerSignal controllerSignal = carController.poll();
+                ControllerSignal controllerSignal = carController.poll(player, players, track);
                 // get the tda
                 TrackDataApproximator tda = player.getTda();
 
Index: src/de/jacavi/appl/controller/device/impl/MouseDevice.java
===================================================================
--- src/de/jacavi/appl/controller/device/impl/MouseDevice.java	(revision 495)
+++ src/de/jacavi/appl/controller/device/impl/MouseDevice.java	(working copy)
@@ -1,5 +1,7 @@
 package de.jacavi.appl.controller.device.impl;
 
+import java.util.List;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
@@ -7,6 +9,8 @@
 
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.device.DeviceController;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 
 
 
@@ -58,7 +62,7 @@
     }
 
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         return currentControllerSignal;
     }
 
Index: src/de/jacavi/appl/controller/device/impl/GameControllerDevice.java
===================================================================
--- src/de/jacavi/appl/controller/device/impl/GameControllerDevice.java	(revision 495)
+++ src/de/jacavi/appl/controller/device/impl/GameControllerDevice.java	(working copy)
@@ -1,10 +1,14 @@
 package de.jacavi.appl.controller.device.impl;
 
+import java.util.List;
+
 import com.centralnexus.input.Joystick;
 
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.device.DeviceController;
 import de.jacavi.appl.controller.device.impl.GameControllerDeviceManager.GameControllerDescriptor;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 
 
 
@@ -21,7 +25,7 @@
     }
 
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         device.poll();
 
         int speed = normaliseSpeedSignal(device.getY());
Index: src/de/jacavi/appl/controller/device/impl/WiimoteDevice.java
===================================================================
--- src/de/jacavi/appl/controller/device/impl/WiimoteDevice.java	(revision 495)
+++ src/de/jacavi/appl/controller/device/impl/WiimoteDevice.java	(working copy)
@@ -1,5 +1,7 @@
 package de.jacavi.appl.controller.device.impl;
 
+import java.util.List;
+
 import org.apache.log4j.Logger;
 
 import wiiusej.Wiimote;
@@ -18,6 +20,8 @@
 import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent;
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.device.DeviceController;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 import de.jacavi.rcp.util.Check;
 
 
@@ -59,7 +63,7 @@
     }
 
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         return currentControllerSignal;
     }
 
Index: src/de/jacavi/appl/controller/device/impl/KeyboardDevice.java
===================================================================
--- src/de/jacavi/appl/controller/device/impl/KeyboardDevice.java	(revision 495)
+++ src/de/jacavi/appl/controller/device/impl/KeyboardDevice.java	(working copy)
@@ -1,5 +1,7 @@
 package de.jacavi.appl.controller.device.impl;
 
+import java.util.List;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
@@ -7,6 +9,8 @@
 
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.device.DeviceController;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 
 
 
@@ -50,7 +54,7 @@
     }
 
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         ControllerSignal retVal = currentControllerSignal;
         currentControllerSignal = new ControllerSignal(currentControllerSignal.getThrust(), currentControllerSignal
                 .isTrigger());
Index: src/de/jacavi/appl/controller/device/impl/MouseKeyboardDeviceAdapter.java
===================================================================
--- src/de/jacavi/appl/controller/device/impl/MouseKeyboardDeviceAdapter.java	(revision 495)
+++ src/de/jacavi/appl/controller/device/impl/MouseKeyboardDeviceAdapter.java	(working copy)
@@ -1,7 +1,11 @@
 package de.jacavi.appl.controller.device.impl;
 
+import java.util.List;
+
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.device.DeviceController;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 
 
 
@@ -35,9 +39,9 @@
     }
 
     @Override
-    public ControllerSignal poll() {
-        ControllerSignal mouse = mouseDevice.poll();
-        ControllerSignal keyboard = keyboardDevice.poll();
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
+        ControllerSignal mouse = mouseDevice.poll(you, others, track);
+        ControllerSignal keyboard = keyboardDevice.poll(you, others, track);
         return new ControllerSignal(mouse.getThrust(), mouse.isTrigger(), keyboard.isSwitchFrontLight(), keyboard
                 .isSwitchBackLight(), mouse.isReset());
     }
Index: src/de/jacavi/appl/controller/CarController.java
===================================================================
--- src/de/jacavi/appl/controller/CarController.java	(revision 495)
+++ src/de/jacavi/appl/controller/CarController.java	(working copy)
@@ -1,7 +1,11 @@
 package de.jacavi.appl.controller;
 
+import java.util.List;
 import java.util.UUID;
 
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
+
 
 
 public abstract class CarController implements Comparable<CarController> {
@@ -14,7 +18,7 @@
         this.name = name;
     }
 
-    abstract public ControllerSignal poll();
+    abstract public ControllerSignal poll(Player you, List<Player> others, Track track);
 
     public void cleanup() {
         deactivate();
@@ -54,11 +58,26 @@
     public void deactivate() {}
 
     /**
-     * Reset resets the state of a Controller without deactivating its listeners. Currently it is called in the RaceEngine
-     * if ControllerSignal.isReset() to make sure the Controller has the same state as a freshly activated one.
+     * Reset resets the state of a Controller without deactivating its listeners. Currently it is called in the
+     * RaceEngine if ControllerSignal.isReset() to make sure the Controller has the same state as a freshly activated
+     * one.
      * <p>
      * We need the reset because some Controllers save their thrust in state.
      */
     public void reset() {}
 
+    /**
+     * Returns the last signal that was poll()ed.
+     * <p>
+     * The difference to poll() is that this should not actually communicate in any way with the hardware. It's
+     * primarily used by the TrackWidget to draw the thrust gauges.
+     * <p>
+     * The default implementation just returns the result of poll() with null arguments. When in doubt, overwrite it!
+     * <p>
+     * IMPORTANT NOTE: This might actually be called *before* the first poll()!
+     */
+    public ControllerSignal getLastSignal() {
+        return poll(null, null, null);
+    }
+
 }
Index: src/de/jacavi/appl/controller/agent/DrivingAgent.java
===================================================================
--- src/de/jacavi/appl/controller/agent/DrivingAgent.java	(revision 495)
+++ src/de/jacavi/appl/controller/agent/DrivingAgent.java	(working copy)
@@ -1,9 +1,14 @@
 package de.jacavi.appl.controller.agent;
 
+import java.util.List;
+
 import de.jacavi.appl.controller.ControllerSignal;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.CarPosition;
+import de.jacavi.appl.track.Track;
 
 
 
 public interface DrivingAgent {
-    ControllerSignal poll(/*CarPosition you, CarPosition[] others, Track track*/);
+    ControllerSignal poll(CarPosition you, List<Player> others, Track track);
 }
Index: src/de/jacavi/appl/controller/agent/ScriptController.java
===================================================================
--- src/de/jacavi/appl/controller/agent/ScriptController.java	(revision 495)
+++ src/de/jacavi/appl/controller/agent/ScriptController.java	(working copy)
@@ -4,13 +4,17 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.util.List;
 
 import de.jacavi.appl.controller.ControllerSignal;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 import de.jacavi.rcp.util.ExceptionHandler;
 
 
 
 abstract public class ScriptController extends DrivingAgentController {
+
     @SuppressWarnings("serial")
     public class ScriptExecutionException extends Exception {
         public ScriptExecutionException(String message) {
@@ -22,6 +26,8 @@
 
     private DrivingAgent scriptObject;
 
+    private ControllerSignal lastSignal = new ControllerSignal();
+
     public ScriptController(String name, File agentFile) {
         super(name);
         this.agentFile = agentFile;
@@ -31,12 +37,31 @@
         return agentFile;
     }
 
+    // @SuppressWarnings("unchecked")
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         if(scriptObject == null)
             return null;
-        else
-            return scriptObject.poll(/*null, null, null*/);
+        else {
+            // determine the arguments to pass to the script
+            /*List<Player> players = (List<Player>) ContextLoader.getBean("playersBean");
+            Player you = null;
+            List<Player> others = new ArrayList<Player>();
+            for(Player p: players) {
+                if(p.getController() == this) {
+                    assert you == null: "Error: this controller was apparently assigned to multiple players";
+                    you = p;
+                } else
+                    others.add(p);
+            }*/
+            lastSignal = scriptObject.poll(you.getPosition(), others, track);
+            return lastSignal;
+        }
+    }
+
+    @Override
+    public ControllerSignal getLastSignal() {
+        return lastSignal;
     }
 
     @Override
@@ -61,7 +86,7 @@
 
     public ControllerSignal dryRun() throws ScriptExecutionException {
         try {
-            return parseScript().poll();
+            return parseScript().poll(null, null, null);
         } catch(Exception exc) {
             final Writer writer = new StringWriter();
             exc.printStackTrace(new PrintWriter(writer));
Index: src/de/jacavi/appl/controller/agent/impl/XmlRpcController.java
===================================================================
--- src/de/jacavi/appl/controller/agent/impl/XmlRpcController.java	(revision 495)
+++ src/de/jacavi/appl/controller/agent/impl/XmlRpcController.java	(working copy)
@@ -1,5 +1,7 @@
 package de.jacavi.appl.controller.agent.impl;
 
+import java.util.List;
+
 import org.apache.xmlrpc.XmlRpcException;
 import org.apache.xmlrpc.XmlRpcRequest;
 import org.apache.xmlrpc.server.PropertyHandlerMapping;
@@ -10,6 +12,8 @@
 
 import de.jacavi.appl.controller.ControllerSignal;
 import de.jacavi.appl.controller.agent.ExternalController;
+import de.jacavi.appl.racelogic.Player;
+import de.jacavi.appl.track.Track;
 import de.jacavi.rcp.util.ExceptionHandler;
 
 
@@ -149,7 +153,7 @@
     }
 
     @Override
-    public ControllerSignal poll() {
+    public ControllerSignal poll(Player you, List<Player> others, Track track) {
         return controllerSignal;
     }
 
Index: src/de/jacavi/rcp/dlg/InputDeviceSettingsDialog.java
===================================================================
--- src/de/jacavi/rcp/dlg/InputDeviceSettingsDialog.java	(revision 495)
+++ src/de/jacavi/rcp/dlg/InputDeviceSettingsDialog.java	(working copy)
@@ -93,7 +93,7 @@
                 @Override
                 public void run() {
                     if(!progressBar.isDisposed() && carControllerManager.isIdValid(deviceID)) {
-                        ControllerSignal signal = carControllerManager.getDevice(deviceID).poll();
+                        ControllerSignal signal = carControllerManager.getDevice(deviceID).poll(null, null, null);
                         progressBar.setSelection(signal.getThrust());
                         progressBar.setForeground(signal.isTrigger() ? Display.getDefault().getSystemColor(
                                 SWT.COLOR_DARK_MAGENTA) : null);
Index: src/de/jacavi/rcp/widgets/TrackWidget.java
===================================================================
--- src/de/jacavi/rcp/widgets/TrackWidget.java	(revision 495)
+++ src/de/jacavi/rcp/widgets/TrackWidget.java	(working copy)
@@ -1046,7 +1046,7 @@
             boolean isOnTrack = p.getPosition().isOnTrack;
             CarController dc = p.getController();
             String name = p.getName();
-            ControllerSignal signal = dc.poll();
+            ControllerSignal signal = dc.getLastSignal();
             if(signal != null) {
                 int thrust = isOnTrack ? signal.getThrust() : 100;
                 boolean isTriggered = isOnTrack ? signal.isTrigger() : false;
Index: agents/SampleAgent.groovy
===================================================================
--- agents/SampleAgent.groovy	(revision 495)
+++ agents/SampleAgent.groovy	(working copy)
@@ -1,10 +1,18 @@
+// SampleAgent:
+//   A very simple Groovy driving agent that alternates
+//   between a faster and a slower mode every 100 gameticks.
+
+
+import java.util.List
 import de.jacavi.appl.controller.agent.DrivingAgent
 import de.jacavi.appl.controller.ControllerSignal
+import de.jacavi.appl.track.CarPosition
+import de.jacavi.appl.track.Track
 
 public class SampleAgent implements DrivingAgent {
 	private int counter = 0
 
-    public ControllerSignal poll() {
+    public ControllerSignal poll(CarPosition you, List others, Track track) {
         counter++
         if(((counter / 100) as int) % 2 == 1) {
             return new ControllerSignal(35, true)
Index: agents/TrackAwareAgent.py
===================================================================
--- agents/TrackAwareAgent.py	(revision 0)
+++ agents/TrackAwareAgent.py	(revision 0)
@@ -0,0 +1,28 @@
+# TrackAwareAgent:
+#   A Jython driving agent that detects the tile he's
+#   currently on and goes 60% thrust on straight tiles
+#   and 30% thrust on curvy tiles.
+
+class MyAgent(DrivingAgent):
+    def __init__(self):
+        self.counter = 0
+
+    def poll(self, you, others, track):
+        if you and track: # during a race
+
+            # determine the section I'm on
+            section = you.trackSectionIndex
+
+            # which tile is that?
+            tile = track.getSections().get(section).getTile()
+
+            # if the entry-to-exit angle is 0, full speed
+            if tile.getEntryToExitAngle().angle == 0:
+                return ControllerSignal(60, False)
+
+            # if it's a turn tile, slow down
+            else:
+                return ControllerSignal(30, False)
+
+        else: # for the dry run
+            return ControllerSignal(10, True)
Index: agents/SampleAgent.py
===================================================================
--- agents/SampleAgent.py	(revision 495)
+++ agents/SampleAgent.py	(working copy)
@@ -1,11 +1,12 @@
-#import de.jacavi.appl.controller.agent.DrivingAgent
-#import de.jacavi.appl.controller.ControllerSignal
+# SampleAgent:
+#   A very simple Jython driving agent that alternates
+#   between a faster and a slower mode every 100 gameticks.
 
 class MyAgent(DrivingAgent):
     def __init__(self):
         self.counter = 0
 
-    def poll(self):
+    def poll(self, you, others, track):
         self.counter += 1
         if self.counter / 100 % 2:
             return ControllerSignal(35, True)
