Map team composition metadata
Closed this issue · 11 comments
SPADs uses the DynamicMapRotation plugin to support next map etc.
There are 2 files in spads:
- https://github.com/beyond-all-reason/spads_config_bar/blob/main/etc/mapLists.conf
- https://github.com/beyond-all-reason/spads_config_bar/blob/main/etc/DynamicMapRotation.conf
that should be automatically generated from metadata in Rowy.
One related piece of metadata is also selection of startpos for the given team composition.
All this information is related to each other, this issue is for overall:
- Design how to best store this information in Rowy: we already have e.g.
teamcount
andplayercount
because they were in chobby for whatever reason. We also have some metadata dimensions in https://docs.google.com/spreadsheets/d/1rn4kIIc9Nnyv_ZiBxXvNXdhUSnh15aLrLsQXmtUBJt8/edit#gid=0 that are currently not important and ofc in the above mentioned files. - Import as much metadata to Rowy as possible
- Write exporters for the
mapLists.conf
andDynamicMapRotation.conf
: we already have all in place to commit to spads repo, so that part is easy
For FFA metadata, there is a bunch of info linked from https://discord.com/channels/549281623154229250/1108192123829891082
I started looking at this. Trying to add the teamsize data in similar manner that it is in the google spreadsheet and writing a python script to make it into mapLists.conf format. I don't think DynamicMapRotation.conf needs to be updated regularly/automatically.
teamSize:
type: array
items:
title: TeamSize
type: string
enum:
- 1v1
- 2v2
- 3v3
- 4v4
- 5v5
- 6v6
- 7v7
- 8v8
- ffa3
- ffa4
- ffa5
- ffa6
- ffa7
- ffa8
- ffa9
- ffa10
- ffa11
- ffa12
- ffa13
- ffa14
- ffa15
- ffa16
- 2v2v2
- 2v2v2v2
- 2v2v2v2v2
- 2v2v2v2v2v2
- 2v2v2v2v2v2v2
- 2v2v2v2v2v2v2v2
- 3v3v3
- 3v3v3v3
- 3v3v3v3v3
- 4v4v4
- 4v4v4v4
- 5v5v5
uniqueItems: true
default: []
I don't think DynamicMapRotation.conf needs to be updated regularly/automatically.
Agree
Trying to add the teamsize data in similar manner that it is in the google spreadsheet
I'm not sure if this is the most ergonomic way to represent this information and make it easy to maintain. 33 tags X 165 maps is effectively 5445 boolean fields that need to be maintained manually.
For example, alternative to consider is to derive it automatically from startboxes for team games, and startpos for ffa games:
- Map supports 3 teams, if there are startboxes defined for 3 teams. Then per startbox we also add one number: information how many people fit in that startbox.
- For ffa games, we will have beyond-all-reason/Beyond-All-Reason#2041 so when startpos combinations are defined for the map, it can be used to extract the max ffa and team ffa sizes.
This way we reduce the amount of redundant information that need to be added, maintained and keept consistent. That information is also more structured, it's not a collection of strings without meaning, so e.g. lobby could also get this in structured manner, and you can do filtering "Show me maps that support 3 teams, and between 2-4 people per team" without matching some "XvXvX" strings.
That is just one alternative proposal how to maintain it, it might not be the best one, there are probably more alternatives, but I e.g. prefer that to set of 33 tags.
Another question with that approach is if a map can support 8v8 should it still be included in 1v1,2v2,3v3 etc. lists. Probably not in all of them, but definitely in some of them. So maybe instead of [Number of Starting Spots] (or [Player Count]) we should have [Min Player Count] and [Max Player Count].
So maybe we add and [Max Total Player Count] to each Startboxes Set and not Start Box. I think we can assume the boxes are made to be fair so that each box in a set can fit same amount of players. We also add [Min Player Count] to each map (and rename [Player Count] to [Max Player Count]).
Then logic goes like this:
Map has e.g. [Min Player Count] = 8 and it's tagged as Team and FFA.
It has starting boxes for 2 teams with [Max Total Player Count] = 16.
It has starting boxes for 4 teams with [Max Total Player Count] = 12.
It would then be added to all these lists in mapLists.conf: 4v4, 5v5, 6v6, 7v7, 8v8, 2v2v2v2, 3v3v3v3, ffa8, ffa9, ffa10, ffa11, ffa12, ffa13, ffa14, ffa15, ffa16.
The ffa stuff can be refined later when that metadata gets added to rowy.
Does this sound reasonable?
Another question with that approach is if a map can support 8v8 should it still be included in 1v1,2v2,3v3 etc. lists. Probably not in all of them, but definitely in some of them. So maybe instead of [Number of Starting Spots] (or [Player Count]) we should have [Min Player Count] and [Max Player Count].
Yeah, I was thinking about that too, it's definitely important for the !nextmap. Having additional tunable is probably ok, or we could leave it as "maybe we actually don't need this tunable", and e.g. default like: min_player_count=max(floor(max_player_count/2), 1)
is good enough?
But I also see that you propose the min_player_count
is per-map. It is some middleground, it's less maintenance this way. Frankly I'm fine with either way personally, this should be easy to change later if we want in either direction. My intuition tells me start with something minimal and apply YANGI principle but maybe there are already some good cases I'm just not aware of that would benefit from dedicated setting.
So maybe we add and [Max Total Player Count] to each Startboxes Set and not Start Box. I think we can assume the boxes are made to be fair so that each box in a set can fit same amount of players. We also add [Min Player Count] to each map (and rename [Player Count] to [Max Player Count]).
Oh yes, sorry for not being precise, or to even be more precise, StartboxesInfo
:) that's what I had in mind. For me more logical is also that the max_player_count
is per-startbox, not total on map. That way validation is a bit more obvious: you don't need to check "did person specify the count that is divisible by the number of startboxes", we can just constraint field value to be between 1 and 8.
(...)
Does this sound reasonable?
Sounds great to me! And thank you for looking at this issue! 😃
Okay so like this:
minPlayerCount:
type: integer
playerCount:
type: integer
...
startboxesSet:
type: object
collection: true
additionalProperties:
type: object
title: StartboxesInfo
properties:
startboxes:
type: array
minItems: 1
items:
type: object
title: Startbox
properties:
poly:
type: array
minItems: 2
maxItems: 2
items:
title: Point
type: object
properties:
x:
type: integer
minimum: 0
maximum: 200
y:
type: integer
minimum: 0
maximum: 200
additionalProperties: false
required:
- x
- y
additionalProperties: false
required:
- poly
maxPlayersPerStartBox:
type: integer
additionalProperties: false
required:
- startboxes
- maxPlayersPerStartBox
I think minPlayerCount is nice to have, some maps are viable for both 2v2 and 8v8 and some are not. We can default to min_player_count=max(floor(max_player_count/2), 1)
if it's empty or missing though. I'll make up some testdata in this format in map_list.yaml and write some python to convert it into mapLists.conf. Not sure what else is needed to make it all automatic after that but I'll think about that once I get there.
@RebelNode I went ahead and kinda following https://github.com/beyond-all-reason/maps-metadata/wiki/Adding-new-input-dimension:
- Added the
maxPlayersPerStartbox
column in Rowy (note thatb
is lowercase for consistency with rest of the fields - Gave you editor access in Rowy (just log in and out) so you can just set those values for testing easily (until they are used, column value doesn't matter)
- Gave you access to be able to run
make update_all_from_rowy
so you can test it's properly importing and all that (follow the instructions above to setup your env to correctly authorize to database)
Cool, thanks! I'll see what I can get done.
Okay getting everything setup on WSL just to run the existing code was a bit of a ride. But I managed to succesfully run make update_all_from_rowy
and pull some maxPlayersPerStartbox
test numbers in. Also had to learn a bunch of stuff about makefiles and whatnot, but I'm somewhat motivated to learn some of that anyway so that's fine.
Here's what I made so far: RebelNode@8f5ca3f. It does what I set out to do, though I am a rather noob-level programmer (I mostly just write SQL for a living) so I'm not sure how pretty or professional it looks. If it's good enough then I just have to fill in all the required maxPlayersPerStartbox
metadata for the maps in rowy and then I can make a PR.
Also no idea how to setup the github-actions to commit the mapLists.conf to spads repo, but that probably requires some permissions anyway so maybe @p2004a can do that?
Great to hear you successfully set up everything and made progress!
If you are happy with how this works, I recommend just opening a PR even without all data in Rowy. We can fill it later as we want: there are a lot of maps and startboxes for many they are not configured correctly (they were imported to rowy from other sources). It's quite some work that we want to do but I wouldn't want to block PR on that.
(...) I'm not sure how pretty or professional it looks (...)
Don't worry, there is going to be some minimal quality bar, and above that I can do review at whatever quality you want (we can stop at minimum quality or I can do more detailed review as learning exercise)
Also no idea how to setup the github-actions to commit the mapLists.conf to spads repo, but that probably requires some permissions anyway so maybe @p2004a can do that?
Sure, that's trivial :). Because we already commit to that repo startboxes, we just need to add one like like this: https://github.com/beyond-all-reason/maps-metadata/blob/main/.github/workflows/ci.yaml#L154
Okay I made it so that empty maplists default to .*
which seems to mean "all maps" in mapLists.conf. I also added .*
for "[small]", "[medium]", "[large]", "[extraLarge]" and "[misc]" lists. As far as I know dynamic map rotation doesn't use them anyway as they're not mentioned in DynamicMapRotation.conf, but some other legacy thing might so they're there now.
I also went through rowy and added playerCount to all maps that I know or that are popular. The script uses playerCount/2
as a backup for 2-team setups if there's no maxPlayersPerStartbox
defined so this way popular maps don't fall off the lists. It also uses playerCount for ffa maps currently as there's no better metadata available.
Also added that one line to ci.yaml as it was pretty trivial now that you pointed me to the right place.
PR is here: #128 . Need to run and commit make update_all_from_rowy
after pulling this to prevent some popular maps from falling off the rotation lists.
We now have information in rowy for every single starbox about max number of players etc. The only thing that kinda fits for this issue is getting more information about FFA setup https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/luarules/configs/ffa_startpoints/README.md but it can be tracked as a separate issue.