When Streamlit refreshes/reruns, session state is lost but the old
simulation server thread keeps running on ports 5001-5003. This caused
"address already in use" errors when trying to start a new server.
Solution: Use a module-level singleton for the simulation server that
persists across Streamlit reruns. The get_or_create_server() function
checks if a server is already running before creating a new one.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>