kengz/SLM-Lab

How to add a non-gym envrinment?

williamyuanv0 opened this issue · 6 comments

Hi, kengz,
How to add a non-gym environment, such as Mahjong or Poker enviroment in rlcard project(https://github.com/datamllab/rlcard). Would you provide a simple demo for adding a new non-gym env, or give some suggestions about how to quickly add ?

kengz commented

Hey the best way is to conform to the gym API via a wrapper and registering it as a gym env. Here's their official doc on that: https://www.gymlibrary.ml/pages/environment_creation/#subclassing-gymenv

Thanks a lot. I have made a gym env, but I meet a new problem in gym API. For squential games like poker, there is a function (denote P ) to choose who to player next. How to add this function in control.py with multiprocess setting (env_num>1)? The problem is that the returns (e.g. state, action, info) of env.step() are list or tuple, rather than a scalar (the result of function P is appended in list info which is returned by env.step() ).
Get the process ID, then calssify through if-else? The multiprocess part in this project is a bit complex, could you give some advice about how to add function P?

kengz commented

This sounds like a multi-agent setting, which the gym API doesn't handle out of the box. However you still make it appear like a single-player env from the wrapper: in step, check the flag from the original environment and keep stepping internally, storing the states, opponent actions and rewards until it is the agent's turn, then return all of that. Of course this mean you'd have to implement logic for the agent to handle the returned lists, such as spreading out and adding all the elements to its memory. In any case, depending on how your agent needs to handle the chunk of data, you'd need to add custom logic, possibly by extending the Agent object similar to how you'd do for the Env object.

Alternatively, you may have a custom control loop logic already and in that case the better way may be to embed an agent in your code instead embedding your environment in the lab - meaning, import the Agent class and initialize it using the same spec from JSON where you need it. Depending on whether it's possible to conform the environment to the common API (singleton, single step at a time), if not I'd personally do it this way. Here's how the lab does the initialization:

def make_agent_env(spec, global_nets=None):

Hope these ideas provide some useful clues.

Thanks, but I am not quite clear about that. You means I should modify the spec JSON file, especially add an agent setting for multiagent setting? But how to set the body to let the two players interact? Could you privide a demo or a sepc for multiagent setting?

kengz commented

SLM Lab doesn't support multiagent yet, although the spec design intended for future compatibility but we never got to implementing it, and don't have immediate plan for doing it.

For this use case you'd need to implement your own code since the lab is single-agent only. To get started, here's an example of how to import use the lab's agent in a project (but you'd have to write a custom Session class): https://slm-lab.gitbook.io/slm-lab/using-slm-lab/using-slm-lab-in-your-project

Thanks a lot! I'v solved this problem.