Problem
New users are assigned a character via assign_character_to_player (users/utils.py):
character = (
Character.objects.filter(can_link=True, death_date__isnull=True)
.exclude(links__is_active=True)
.first()
)
This pulls from every Character with can_link=True across the whole map, so new users land in villages essentially at random. There's currently no way to control which population centres are open for new players.
As new users join, I want to open up villages one at a time (lock all but the currently "active" one) instead of having everyone spread across the entire map.
Proposal
Add a characters_can_link boolean field directly on PopulationCentre (default True), rather than deriving "is this centre open" from the residents' can_link values or bulk-toggling Character.can_link per resident.
("Locked" was considered as the field/flag name, but a population centre could plausibly be "locked" for other reasons in future — e.g. not yet open to visit/travel to — so characters_can_link is more precise about what this specific flag controls.)
Shape, following the existing pattern in locations/management/commands/manage_centres.py + locations/services/population_centre_admin.py:
- Migration adding
PopulationCentre.characters_can_link = models.BooleanField(default=True).
- A service function, e.g.
set_population_centre_characters_can_link(name: str, characters_can_link: bool) -> PopulationCentre in locations/services/population_centre_admin.py.
--lock NAME / --unlock NAME options on the existing manage_centres management command (alongside --list / --delete).
assign_character_to_player (users/utils.py) needs to additionally filter on the resident's centre being open, e.g. .filter(can_link=True, death_date__isnull=True, population_centre__characters_can_link=True). Need to decide how characters with no population_centre are handled here (currently population_centre is nullable) — presumably still linkable, since they're not tied to a lockable centre.
- Optionally, expose
characters_can_link on PopulationCentreAdmin (locations/admin.py) as an editable/list-display field, similar to the existing mark_as_npc / mark_as_canlink actions on CharacterAdmin.
Behavior
- Locking must not touch actively linked characters. Locking a centre only affects new assignment via
assign_character_to_player — it must not deactivate or otherwise change any character's existing active PlayerCharacterLink. Existing players in a locked centre keep playing normally.
- Locking/unlocking does not write to
Character.can_link at all under this design — it's a separate flag read at assignment time, which sidesteps the bulk-update-clobbers-other-state problem entirely.
Related
See #682 — Character.can_link is currently a single stored boolean written by several independent code paths (age at spawn, admin toggle, active-link signal, and now this centre flag would be a fourth). That issue proposes deriving can_link from underlying reasons instead of one flat field; this centre flag would be one of those inputs once that lands.
Notes
Character.can_link (default False): character/models/character.py
Character.population_centre FK, related_name="residents", nullable: character/models/character.py
- Assignment logic:
users/utils.py::assign_character_to_player
- Existing per-centre command/service to extend:
locations/management/commands/manage_centres.py, locations/services/population_centre_admin.py
- Existing per-character admin actions:
character/admin.py (mark_as_npc, mark_as_canlink)
Problem
New users are assigned a character via
assign_character_to_player(users/utils.py):This pulls from every
Characterwithcan_link=Trueacross the whole map, so new users land in villages essentially at random. There's currently no way to control which population centres are open for new players.As new users join, I want to open up villages one at a time (lock all but the currently "active" one) instead of having everyone spread across the entire map.
Proposal
Add a
characters_can_linkboolean field directly onPopulationCentre(defaultTrue), rather than deriving "is this centre open" from the residents'can_linkvalues or bulk-togglingCharacter.can_linkper resident.("Locked" was considered as the field/flag name, but a population centre could plausibly be "locked" for other reasons in future — e.g. not yet open to visit/travel to — so
characters_can_linkis more precise about what this specific flag controls.)Shape, following the existing pattern in
locations/management/commands/manage_centres.py+locations/services/population_centre_admin.py:PopulationCentre.characters_can_link = models.BooleanField(default=True).set_population_centre_characters_can_link(name: str, characters_can_link: bool) -> PopulationCentreinlocations/services/population_centre_admin.py.--lock NAME/--unlock NAMEoptions on the existingmanage_centresmanagement command (alongside--list/--delete).assign_character_to_player(users/utils.py) needs to additionally filter on the resident's centre being open, e.g..filter(can_link=True, death_date__isnull=True, population_centre__characters_can_link=True). Need to decide how characters with nopopulation_centreare handled here (currentlypopulation_centreis nullable) — presumably still linkable, since they're not tied to a lockable centre.characters_can_linkonPopulationCentreAdmin(locations/admin.py) as an editable/list-display field, similar to the existingmark_as_npc/mark_as_canlinkactions onCharacterAdmin.Behavior
assign_character_to_player— it must not deactivate or otherwise change any character's existing activePlayerCharacterLink. Existing players in a locked centre keep playing normally.Character.can_linkat all under this design — it's a separate flag read at assignment time, which sidesteps the bulk-update-clobbers-other-state problem entirely.Related
See #682 —
Character.can_linkis currently a single stored boolean written by several independent code paths (age at spawn, admin toggle, active-link signal, and now this centre flag would be a fourth). That issue proposes derivingcan_linkfrom underlying reasons instead of one flat field; this centre flag would be one of those inputs once that lands.Notes
Character.can_link(defaultFalse):character/models/character.pyCharacter.population_centreFK,related_name="residents", nullable:character/models/character.pyusers/utils.py::assign_character_to_playerlocations/management/commands/manage_centres.py,locations/services/population_centre_admin.pycharacter/admin.py(mark_as_npc,mark_as_canlink)