Skip to main content
Version: 🚧 Alpha 🚧

11. Testing in GAMA GUI

By Killian Trouillet


From Headless to GUI​

During training, we used GAMA in headless mode for speed. Now that the model is trained, we switch to the GAMA GUI to watch the agent in action.

Key Difference​

ModePortSpeedDisplayUse
Headless1001Fast (no rendering)NoneTraining
GUI1000Slow (renders display)YesTesting / Visualization

Starting GAMA GUI​

  1. Open GAMA normally (double-click the application)
  2. The GUI server runs on port 1000 by default β€” no extra setup needed

The Test Script​

Loading the Trained Model​

from stable_baselines3 import PPO

model = PPO.load("saved_models/ppo_forager")

This loads the neural network weights saved during training.

Connecting to GUI​

The only change from training: the port number.

env = None
for attempt in range(5):
try:
env = gym.make(
"gama_gymnasium_env/GamaEnv-v0",
gaml_experiment_path="path/to/forager_gym.gaml",
gaml_experiment_name="gym_env",
gama_ip_address="localhost",
gama_port=1000,
)
break
except Exception as e:
print(f"GAMA GUI not ready. Retrying in 5s...")
time.sleep(5)

if env is None:
raise RuntimeError("Failed to connect to GAMA GUI after several attempts.")

Deterministic Evaluation​

action, _ = model.predict(obs, deterministic=True)

During training, the policy adds noise to explore new strategies. During testing, we set deterministic=True to use the pure learned policy β€” no randomness, just the best action the network has learned.

Slow Motion​

time.sleep(0.1) # 100ms delay between steps

We add a small delay between steps so the movement is visible in the GAMA display.


Complete Test Script​

Note: The GAML model is unchanged from Step 9. See the Complete Model section there for the full forager_gym.gaml.

"""
Smart Forager - Test Script (GUI Visualization)
Author: Killian Trouillet

Usage:
1. Open GAMA GUI (default port 1000)
2. Run this script: python test_forager.py
"""

import asyncio
from pathlib import Path
import gymnasium as gym
import gama_gymnasium
from stable_baselines3 import PPO
import numpy as np
import time


GAML_FILE = str(Path(__file__).parent / "forager_gym.gaml")
EXPERIMENT_NAME = "gym_env"
GAMA_PORT = 1000
MODEL_PATH = str(Path(__file__).parent / "saved_models" / "ppo_forager")
NUM_EPISODES = 5
STEP_DELAY = 0.1


async def test():
print("=" * 50)
print(" Smart Forager - PPO Test (GUI)")
print("=" * 50)

print(f"Loading model from: {MODEL_PATH}")
model = PPO.load(MODEL_PATH)
print("Model loaded successfully!")

# ---- Create the environment (connected to GAMA GUI) ----
# We use a retry loop because GAMA GUI takes time to initialize the simulation
env = None
for attempt in range(5):
try:
print(f"Connecting to GAMA GUI (attempt {attempt + 1}/5)...")
env = gym.make(
"gama_gymnasium_env/GamaEnv-v0",
gaml_experiment_path=GAML_FILE,
gaml_experiment_name=EXPERIMENT_NAME,
gama_ip_address="localhost",
gama_port=GAMA_PORT,
)
break
except Exception as e:
if "Unable to find" in str(e) or "NOTREADY" in str(e):
print(f"GAMA simulation not ready yet. Waiting 5s...")
time.sleep(5)
else:
raise e

if env is None:
print("Failed to connect to GAMA GUI after several attempts.")
return

print(f"\nRunning {NUM_EPISODES} test episodes...\n")

all_rewards = []
all_steps = []

for episode in range(NUM_EPISODES):
obs, info = env.reset()
time.sleep(1)

total_reward = 0.0
step = 0
done = False

while not done:
action, _ = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
step += 1
done = terminated or truncated
time.sleep(STEP_DELAY)

all_rewards.append(total_reward)
all_steps.append(step)

status = "FOUND FOOD!" if terminated else "TIMEOUT"
print(f" Episode {episode + 1}/{NUM_EPISODES}: "
f"{status} | Steps: {step} | Reward: {total_reward:.1f}")

env.close()

print(f"\n{'=' * 50}")
print(f" Test Results Summary")
print(f"{'=' * 50}")
print(f" Episodes: {NUM_EPISODES}")
print(f" Avg Reward: {np.mean(all_rewards):.1f}")
print(f" Avg Steps: {np.mean(all_steps):.0f}")
print(f" Success Rate: "
f"{sum(1 for r in all_rewards if r > 50) / NUM_EPISODES * 100:.0f}%")
print(f"{'=' * 50}")


if __name__ == "__main__":
asyncio.run(test())

Running the Test​

cd models/gym
python test_forager.py

Watch the GAMA display β€” the blue forager should navigate smoothly around obstacles to reach the green food!


Expected Console Output​

==================================================
Smart Forager - PPO Test (GUI)
==================================================
Loading model from: saved_models/ppo_forager
Model loaded successfully!

Running 5 test episodes...

Episode 1/5: FOUND FOOD! | Steps: 47 | Reward: 93.2
Episode 2/5: FOUND FOOD! | Steps: 52 | Reward: 91.8
Episode 3/5: FOUND FOOD! | Steps: 45 | Reward: 94.1
Episode 4/5: FOUND FOOD! | Steps: 49 | Reward: 92.5
Episode 5/5: FOUND FOOD! | Steps: 51 | Reward: 91.4

==================================================
Test Results Summary
==================================================
Episodes: 5
Avg Reward: 92.6
Avg Steps: 49
Success Rate: 100%
==================================================

Summary​

ConceptImplementation
Continuous worldNo grid, free {x, y} movement in 100Γ—100 space
GAMA↔Python bridgeGymAgent species + gama-gymnasium WebSocket
Neural network policyPPO("MlpPolicy", ...) via Stable Baselines3
Headless traininggama-headless.bat -socket 1001 β†’ fast, no GUI
GUI testingPPO.load() + connect to GAMA GUI (port 1000)
Action spaceBox([-1,-1], [1,1]) β€” continuous velocity (dx, dy)
Observation spaceBox([0]Γ—13, [1]Γ—13) β€” position + food direction + 8 sensors
Reward shapingDistance delta bonus + food reward + living penalty

Key GAML Concepts Used​

global, species, reflex, action, aspect, experiment, parameter, geometry, rectangle, circle, line, distance_to, towards, intersects, inter, cos, sin, list, map, loop, draw

Key Python Concepts Used​

gymnasium, gym.make(), env.reset(), env.step(), PPO, MlpPolicy, model.learn(), model.save(), model.load(), model.predict(), asyncio, BaseCallback

Key Files​

FileDescription
models/gym/forager_gym.gamlGAMA model with GymAgent bridge
models/gym/train_forager.pyPPO training script (headless)
models/gym/test_forager.pyTesting script (GUI visualization)