I spent an afternoon playing around with Sodarace, collecting information on how I could interface an AI application to it. Sodarace creatures (called models) don’t have any controllers, but AI could be used in the construction of their bodies.

I created a thread on the sodarace AI forums, but have included that information here, along with a few other things I’ve found out.

They have API documentation and the DTD for the model XML.

There are two existing “use AI to create/optimize creatures” projects, Wodka and AI Central’s SodaRace.

And a re-implementation of Sodarace with a few changes:

Mins: Mins Is Not Sodarace

The maximum values for:

gravity: 4.0
friction: 1.0
springyness: 0.5

The Soda Ultimate Race!!! thread has some good terrains, such as the “agility” terrain on page 3:

Here’s a simple python client that evaluates a single model:

import socket

model = """<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE sodaconstructor>
        <container width="651" height="422"/>
        <environment gravity="0.2938248" friction="0.05031007" springyness="0.20193903"/>
        <collisions surface_friction="0.1" surface_reflection="-0.75"/>
        <wave amplitude="0.5" phase="0.0" speed="0.009803922"/>
        <settings gravitydirection="down" wavedirection="forward" autoreverse="on"/>
                <mass id="m0" x="294.0" y="265.0" vx="0.0" vy="0.0"/>
                <mass id="m1" x="220.0" y="122.0" vx="0.0" vy="0.0"/>
                <mass id="m2" x="340.0" y="122.0" vx="0.0" vy="0.0"/>
                <muscle a="m0" b="m1" restlength="161" amplitude="0.54761904" phase="0.7529412"/>
                <muscle a="m1" b="m2" restlength="115.0" amplitude="0.52380955" phase="0.5019608"/>
                <muscle a="m2" b="m0" restlength="147.80054" amplitude="0.71428573" phase="0.2509804"/>

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 7777))
sockfile = sock.makefile(mode='r+')

# Read and check the header
header = sockfile.readline()
assert header.startswith('Hello client: ')
print "Connected to sodarace"

# Read and check the request
request = sockfile.readline()
qmark_pos = request.find('?')
assert qmark_pos > 0
print "got request: ", request
id = request[0:qmark_pos]

# Send the model
print "Sent model"

# Wait for the finishing time
while True:
   racer = sockfile.readline()
   print "Received: ", racer
   if racer.startswith(id + '>'): break

print "Time: ", racer[racer.find('>')+1:-1]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s