oxwhirl / smac

SMAC: The StarCraft Multi-Agent Challenge
MIT License
1.07k stars 226 forks source link

Add new units into a map #13

Closed chongyi-zheng closed 4 years ago

chongyi-zheng commented 4 years ago

I want to add some new RL units into a map with the editor. The second to last paragraph of the documentation mentions the difference between "RL" and regular units. I tried to modify the corresponding options in the editor, but it doesn't work when smac trying to 'Sending ResponseJoinGame'. It seemed stuck forever... Any suggestion?

samvelyan commented 4 years ago

I have just prepared a step-by-step tutorial that you can use. Please take a look here and let me know if you have any questions.

chongyi-zheng commented 4 years ago

Thanks for the quick response! It's really helpful. I can add a new RL unit into the map now. However, the python program is still stuck at "Sending ResponseJoinGame". I just want to add some advanced units such as ultralisk and dark templar into the game. There should be some modifications in the code too. Could you please give any guidance?

On Wed, Sep 11, 2019 at 10:03 PM mika notifications@github.com wrote:

Closed #13 https://github.com/oxwhirl/smac/issues/13.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oxwhirl/smac/issues/13?email_source=notifications&email_token=AJWMKK5BHJ2XSGAHIOK5LGTQJD3BXA5CNFSM4IVTK5P2YY3PNVWWK3TUL52HS4DFWZEXG43VMVCXMZLOORHG65DJMZUWGYLUNFXW5KTDN5WW2ZLOORPWSZGOTSBUUFA#event-2625849876, or mute the thread https://github.com/notifications/unsubscribe-auth/AJWMKK6CQESERU7C5TODCD3QJD3BXANCNFSM4IVTK5PQ .

samvelyan commented 4 years ago
  1. Did you add the map info here https://github.com/oxwhirl/smac/blob/master/smac/env/starcraft2/maps/smac_maps.py? Go ahead and add it, should be straightforward.
  2. Are the triggers in the .SC2Map file similar to the existing ones (say 3m_3m.SC2Map)?
chongyi-zheng commented 4 years ago

Yes. I just add an ultralisk and an overseer for the RL player and a dark templar for the enemy based on the 3m.SC2Map. And I add my map file into the SMAC_Maps folder with its configuration like this:

...
"1o_1u_vs_1dt": {
        "n_agents": 2,
        "n_enemies": 1,
        "limit": 200,
        "a_race": "Z",
        "b_race": "P",
        "unit_type_bits": 2,
        "map_type": "overseer_ultralisk_and_dark_templar",
    },
...

The get_unit_type_id function looks like:

    def get_unit_type_id(self, unit, ally):
        """Returns the ID of unit type in the given scenario."""
        if ally:  # use new SC2 unit types
            if self.map_type == "overseer_ultralisk_and_dark_templar":
                # ultralisk_rl
                if unit.unit_type == 1971:
                    type_id = 0
                # overseer_rl
                elif unit.unit_type == 1972:
                    type_id = 1
            else:
                type_id = unit.unit_type - self._min_unit_type
        else:  # use default SC2 unit types
            if self.map_type == "stalkers_and_zealots":
                # id(Stalker) = 74, id(Zealot) = 73
                type_id = unit.unit_type - 73
            elif self.map_type == "bane":
                if unit.unit_type == 9:
                    type_id = 0
                else:
                    type_id = 1
            elif self.map_type == "MMM":
                if unit.unit_type == 51:
                    type_id = 0
                elif unit.unit_type == 48:
                    type_id = 1
                else:
                    type_id = 2
            elif self.map_type == "overseer_ultralisk_and_dark_templar":
                # dark templar
                type_id = 0

        return type_id

And the max shield for the dark templar:

    def unit_max_shield(self, unit):
        """Returns maximal shield for a given unit."""
        if unit.unit_type == 74 or unit.unit_type == self.stalker_id:
            return 80  # Protoss's Stalker
        if unit.unit_type == 73 or unit.unit_type == self.zealot_id:
            return 50  # Protoss's Zaelot
        if unit.unit_type == 4 or unit.unit_type == self.colossus_id:
            return 150  # Protoss's Colossus
        if unit.unit_type == 76 or unit.unit_type == self.dark_templar_id:
            return 80  # Protoss's Dark Templar

with

self.stalker_id = self.colossus_id = self.zealot_id = self.dark_templar_id = 0

Do I miss something?

chongyi-zheng commented 4 years ago

By the way, here is my map.

samvelyan commented 4 years ago

I'll take a look and get back to you.

samvelyan commented 4 years ago

I was able to run the map but with few changes.

  1. For some reason the trigger that is supposed to create the Dark Templar was not doing see. No Dark Templar was being spawned. I'm not sure why this is the case. I've modified it to created a Colossus and it works now. Feel free to change this and try out new things.

  2. I've divided the spawn area into two spawn areas, one for the allied units and one for the enemy.

  3. I've also made some changes to the code, but I'm not sure if they were causing the error on your side.

Anyway, I've created a new branch called add_new_units and pushed the changes in https://github.com/oxwhirl/smac/commit/872739834211fa79be75f158b49619e65378f12c. The random_agents.py script with the new map works for me. Please go ahead and try it out to see if it works for you. If yes, you can go ahead and experiment new ideas!

PS. The new .SC2Map map file is in the smac/env/starcraft2/maps/SMAC_Maps/1o_1u_vs_1dt.SC2Map

chongyi-zheng commented 4 years ago

Thanks for your response again!

  1. I tried to create a Colossus instead of a Dark Templar in my original map with the modification in the code as yours, and it works as well.

  2. The problem should be to do with the Dark Templar. It is invisible by default, and we need the Buff of the Overseer named "Detector" to see it. That's the reason why you may think the Dark Templar failed to spawn. Sorry for the late notification.

  3. Currently, SMAC may not work well with the invisible units. I only find the Dark Templar has this ability, and the Terrain Ghost needs to be upgraded to get this. And I think it is a good idea to add some WARNING in the documentation.

samvelyan commented 4 years ago

wrt point 3 - this is not a SMAC issue but rather a StarCraft 2 issue/feature.

Anyway, let me know if you have difficulties in the future! :)