davidADSP/SIMPLE

Add a way to communicate with game engines written in other languages

Opened this issue · 1 comments

I do most of my game engines now in Dart since my apps are written in Dart/Flutter and it's quite a lot of work to write and debug a game engine in both Dart and Python (especially given how many games I plan on implementing) so I'd like to create a generic interface in SIMPLE that can be used to call out to a game engine over HTTP. I'm also aware of other people that would benefit from an open source stub that calls out to a remote game engine.

Here's my current rough idea for how this could be done:

  • Model definition will still be in Python.
  • Everything else will be done in a way that calls out to a server which implements the following endpoints:
    • /newgame endpoint returns {"id": "unique game identifier used by the server to map game IDs to in-memory game states", "player_count": X, "action_space_size": X, "observation_space_size": X, "player_count": X, "current_player": X, "observation": [], "legal_actions": []}
    • /step/{id} POSTed to with {"action": integer of action selected} returns the following: {"observation": [one hot encoding of current game state], "next_player": integer representing the player whose turn it is after the move is made, "reward": [array of rewards for each player], "done": true|false}

I am working on this now. I added an environment named remote and I've added a test client for Tic-Tac-Toe that responds like this:

$ curl http://localhost:5000/newgame
{"action_space_size":9,"current_player":0,"id":"213361bf-c1c9-40a9-bca2-4bbf880fbc6d","legal_actions":[1,1,1,1,1,1,1,1,1],"observation":[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1],"observation_space_size":9,"player_count":2}
$ curl http://localhost:5000/step/213361bf-c1c9-40a9-bca2-4bbf880fbc6d -d '{"action": 0}'
{"done":false,"legal_actions":[0,1,1,1,1,1,1,1,1],"next_player":1,"observation":[-1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1],"reward":[0,0]}
$ curl http://localhost:5000/step/213361bf-c1c9-40a9-bca2-4bbf880fbc6d -d '{"action": 3}'
{"done":false,"legal_actions":[0,1,1,0,1,1,1,1,1],"next_player":0,"observation":[1,0,0,-1,0,0,0,0,0,0,1,1,0,1,1,1,1,1],"reward":[0,0]}
$ curl http://localhost:5000/step/213361bf-c1c9-40a9-bca2-4bbf880fbc6d -d '{"action": 1}'
{"done":false,"legal_actions":[0,0,1,0,1,1,1,1,1],"next_player":1,"observation":[-1,-1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,1],"reward":[0,0]}
$ curl http://localhost:5000/step/213361bf-c1c9-40a9-bca2-4bbf880fbc6d -d '{"action": 4}'
{"done":false,"legal_actions":[0,0,1,0,0,1,1,1,1],"next_player":0,"observation":[1,1,0,-1,-1,0,0,0,0,0,0,1,0,0,1,1,1,1],"reward":[0,0]}
$ curl http://localhost:5000/step/213361bf-c1c9-40a9-bca2-4bbf880fbc6d -d '{"action": 2}'
{"done":true,"legal_actions":[0,0,0,0,0,1,1,1,1],"next_player":0,"observation":[1,1,1,-1,-1,0,0,0,0,0,0,0,0,0,1,1,1,1],"reward":[1,-1]}

I'll push the branch after I've more thoroughly end-to-end tested it.