Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding own map to SMAC_maps #2

Closed
SoyGema opened this issue Feb 18, 2019 · 8 comments
Closed

Adding own map to SMAC_maps #2

SoyGema opened this issue Feb 18, 2019 · 8 comments

Comments

@SoyGema
Copy link

SoyGema commented Feb 18, 2019

Hey there,

Thanks so much for open-source this project in a turn for a multiagent cooperative environment for Starcraft II research environment 👍 !

I am on the current task of adding a new map to the SMAC environment , for that, I´ve already

  • Add the .SC2 map file to smac/env/starcraft2/maps/SMAC_Maps and Applications/StarCraftII/Maps/SMAC_Maps folders

  • Add the current structure as a dictionary following the structure from other maps smac/env/starcraft2/maps/smac_maps.py file in map_param_registry
    },
    "HallucinIce": {
    "n_agents": 4,
    "n_enemies": 6,
    "limit": 180,
    "a_race": "P",
    "b_race": "T,
    "unit_type_bits": 0,
    "map_type": "sentry",
    },

  • Changed smac/examples/random_agents.py 7th line for

env = StarCraft2Env(map_name="HallucinIce")

However, when I run the example python file , it gives me the following error :

  File "random_agents.py", line 43, in <module>
    main()
  File "random_agents.py", line 10, in main
    env = StarCraft2Env(map_name="HallucinIce")
  File "/Users/g/Desktop/SMAC/lib/python3.6/site-packages/smac/env/starcraft2/starcraft2.py", line 180, in __init__
    map_params = get_map_params(self.map_name)
  File "/Users/g/Desktop/SMAC/lib/python3.6/site-packages/smac/env/starcraft2/maps/__init__.py", line 10, in get_map_params
    return map_param_registry[map_name]
KeyError: 'HallucinIce'
  • I interpret from the error that map_param_registry is unable to read the HallucinIce dictionary addition structure and not call to get_map_params ... even though I´ve added to smac_maps.py file. Any idea or guide on how could I solve this issue ? :)

Thanks in advance for the time dedicated to this issue .

@samvelyan
Copy link
Collaborator

Hi there!

Did you re-install the smac package after making the changes in the codebase?

@SoyGema
Copy link
Author

SoyGema commented Feb 18, 2019

Hi !
Thanks for the response .
No , I didn´t . Will definetly try and let you know, many thanks for your speed!

I am digging into smac/smac/env/starcraft2/starcraft2.py and adding in #MapInfo some relevant info about the units in the custom map .

Ln: 254

        self.marine_id = self.hellion_id = self.reaper_id = self.marauder_id = self.medivac_id = 0

Ln : 256

        self.stalker_id = self.sentry_id = self.colossus_id = self.zealot_id = 0

Regarding the actions in Ln:45 from smac/smac/env/starcraft2/starcraft2.py I was thinking in add the special ability from sentry so the multiagent setup might allow sentry units to learn guardian shields, hallucinations or sentry defense . However, the number (id) doesn´t match pysc2 functions ID . ( e.g : in SMAC, attack is 23, and in pysc2 attack is 12 ) Am I identifying correctly the setup for adding complexity to the actin space?

Many thanks again ! 👍

@SoyGema
Copy link
Author

SoyGema commented Feb 18, 2019

Mikayel ,
Please, let me take a more deep approach into the action space and I will go back to you with a more thoughtfull and studied approach.
Sorry for the inconvenience caused for adding other functionality to the issue

@samvelyan
Copy link
Collaborator

The actions indices that we use actually correspond to the 4th parameter of the Function.ability's from pysc2. For instance, Attack is 23, Stop is 4th, Move is 16, etc.

Would be great to have additional skills such as the guardian shields, etc.
For a given unit, the available actions can be queried using the following commands:

from s2clientprotocol import query_pb2 as q_pb
...
self._controller.query(q_pb.RequestQuery(abilities=[q_pb.RequestQueryAvailableAbilities(unit_tag=unit.tag)]))

The query command is currently not a part of the remote controller. However, you can find it in my pysc2 PR.

I remember trying to use the Sentry's guardian shield long time ago, but it was not working. Maybe with the recent fixes of pysc2, it would be possible.

@SoyGema
Copy link
Author

SoyGema commented Feb 25, 2019

Mikayel ,
Hope you are doing well. My apologies for reaching you again with an issue related with this .
Ive come to add the query PR to pysc2/lib/remote_controler.py sucessfully and the line showed above self._controller.query(q_pb.RequestQuery(abilities=[q_pb.RequestQueryAvailableAbilities(unit_tag=unit.tag)])) with the import statement

However, the error displays

File "/Users/SMAC/smac/smac/examples/random_agents.py", line 19, in main
    env.reset()
  File "/Users/SMAC/smac/smac/env/starcraft2/starcraft2.py", line 338, in reset
    self._launch()
  File "/Users/SMAC/smac/smac/env/starcraft2/starcraft2.py", line 313, in _launch
self._controller.query(q_pb.RequestQuery(abilities=[q_pb.RequestQueryAvailableAbilities(unit_tag=unit.tag)]))
NameError: name 'unit' is not defined

I´m guessing I am not understanding the 'unit' concept correctly.
Been however in sc2client repository and couldn´t find the exact guidance about this. Should it be exactly oriented to sentry unit ?

Would you mind point me in the right direction regarding this?
Thanks so much . 👍

@samvelyan
Copy link
Collaborator

Hi there,

So by unit I meant the data structure that contains information about a given unit, such as health, location, tag, etc. We receive these as observations from sc2client when the raw interface is being used.

We store these unit structures in self.agents. So for our i-th unit, we can get its tag by self.agents[i].tag command. So the call would look like this

self._controller.query(q_pb.RequestQuery(abilities[q_pb.RequestQueryAvailableAbilities(unit_tag=self.agents[i].tag)]))

where i should match the unit corresponding to a Sentry. You could print it for all units by just iterating through all agents after self.init_units() function is called.

Sorry that this required more work than expected. Let me know if you have any further questions.

Best wishes,
Mika

@SoyGema
Copy link
Author

SoyGema commented Mar 14, 2019

Hey Mika,
Hope everything is going ok . Thanks again for all the support !

As I understood for your comment, [i] might be associated to the unit(agent) corresponding to a Sentry.

  • self.agents is an empty dictionary that will store unit data structures when the game is launched, defined here

  • If we have 4 units(agents) that might act cooperativetly , the tag might be

self._controller.query(q_pb.RequestQuery(abilities[q_pb.RequestQueryAvailableAbilities(unit_tag=self.agents[4].tag)]))
  • Or is it related to pysc2/lib/units.py meaning that the call is, in this case because of the sentry unit being 77 ??
self._controller.query(q_pb.RequestQuery(abilities[q_pb.RequestQueryAvailableAbilities(unit_tag=self.agents[77].tag)]))

I´ve actually tried both , and it displays a key error in both cases :

self._launch()
  File "/SMAC/smac/smac/env/starcraft2/starcraft2.py", line 313, in _launch
    self._controller.query(q_pb.RequestQuery(abilities=[q_pb.RequestQueryAvailableAbilities(unit_tag=self.agents[4].tag)]))
KeyError: 4

Please Note that in this case all the units are sentry units.

I´ve also noted that your map desing is different from the mini-games designed in the pysc2 released, and the reward is included as a parameter in starcraft.py
. Do you recommend to simplify the map version in terms of mimiquing information from SMAC_Maps ?

I apologize if my block is causing extra effort for you as I am getting familliar with this .

🥇 Thanks so much and congratulations again in this extensive and detailed piece of OpenSource Software , and for pushing the boundaries to research and understand how cooperation works .

@samvelyan
Copy link
Collaborator

Many thanks for your kinds words. I'm very happy to help.

As I've said in the previous comment, you should take a look at self.agents after self.init_units() function is called. The self.agents will then become a dictionary containing n_agent entries. For 3m map, for instance, the self.agents might look like this:

{0: display_type: Visible
alliance: Self
tag: 4295229441
unit_type: 1957
owner: 1
pos {
  x: 9.0
  y: 15.3115234375
  z: 7.99609375
}
facing: 4.71238899230957
radius: 0.375
build_progress: 1.0
cloak: NotCloaked
is_selected: false
is_on_screen: false
is_blip: false
health: 45.0
health_max: 45.0
shield: 0.0
energy: 0.0
is_flying: false
is_burrowed: false
assigned_harvesters: 0
ideal_harvesters: 0
weapon_cooldown: 0.0
shield_max: 0.0
energy_max: 0.0
is_hallucination: false
, 1: display_type: Visible
alliance: Self
tag: 4294967297
unit_type: 1957
owner: 1
pos {
  x: 9.0
  y: 16.0
  z: 7.99609375
}
facing: 4.71238899230957
radius: 0.375
build_progress: 1.0
cloak: NotCloaked
is_selected: false
is_on_screen: false
is_blip: false
health: 45.0
health_max: 45.0
shield: 0.0
energy: 0.0
is_flying: false
is_burrowed: false
assigned_harvesters: 0
ideal_harvesters: 0
weapon_cooldown: 0.0
shield_max: 0.0
energy_max: 0.0
is_hallucination: false
, 2: display_type: Visible
alliance: Self
tag: 4295491585
unit_type: 1957
owner: 1
pos {
  x: 9.6884765625
  y: 16.0
  z: 7.99609375
}
facing: 4.71238899230957
radius: 0.375
build_progress: 1.0
cloak: NotCloaked
is_selected: false
is_on_screen: false
is_blip: false
health: 45.0
health_max: 45.0
shield: 0.0
energy: 0.0
is_flying: false
is_burrowed: false
assigned_harvesters: 0
ideal_harvesters: 0
weapon_cooldown: 0.0
shield_max: 0.0
energy_max: 0.0
is_hallucination: false
}

Hence,

  • it contains only n_agent entries. Thus, index 4 is out of range in your case since the indices start from 0.
  • self.agent[i] contains all information about about i-th unit (indices need to be from 0 to 3 in your case, since you have 4 sentries), such as health, shield, position, weapon cooldown, etc.
  • you can notice the tag field in this structure. This is the unit_tag argument to be used by the query command above!

You are correct to notice that we don't use the rewards similar to mini-games released with pysc2. Instead, we provide options to construct different team rewards.

I hope this makes sense now. Let me know if you have any further questions.

Regards,
Mika

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants