Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ea5675f
Add Debug Settings Architecture
JamesVanBoxtel Oct 31, 2025
8f84a10
New User Setup and Input Overlay
JamesVanBoxtel Oct 27, 2025
7319157
Merge branch 'beta' into initialSetupAndInputPickerFinal
JamesVanBoxtel Nov 9, 2025
ab2b89c
Merge branch 'beta' into initialSetupAndInputPickerFinal
JamesVanBoxtel Nov 22, 2025
c136956
rename StartUp to BootScene
Endaris Jan 13, 2026
86feea3
replace triggerNextScene pattern with a simple conditional push seque…
Endaris Jan 13, 2026
c1a9f36
move code for triggering InputConfigMenu on top into Game and remove …
Endaris Jan 13, 2026
fc5eb60
move unregister process for joysticks into joystickManager
Endaris Jan 14, 2026
3018ccf
extract check for joystick being registered on inputs for more clarity
Endaris Jan 14, 2026
8442931
rename write_key_file to writeKeyConfigurationToFile
Endaris Jan 14, 2026
ac73821
rename all local config variables to inputConfig to prevent confusion…
Endaris Jan 14, 2026
9dd0443
add some annotations for inputManager/InputConfiguration
Endaris Jan 14, 2026
c202411
change checkForUnassignedConfigurationInputs to directly take a playe…
Endaris Jan 14, 2026
2878e13
proxy joystickRemoved through Game and fix extra encode for config write
Endaris Jan 14, 2026
188f6ca
rename UiElement functions for generating debug strings
Endaris Jan 14, 2026
4f4e1d1
remove obsolete require from Match
Endaris Jan 14, 2026
a9c377c
readd ModValidationScene (forgot about it)
Endaris Jan 14, 2026
6bd2400
Merge branch 'JamInputPickerSuggestions2' into JamInputPicker
Endaris Jan 21, 2026
7897506
update german localization and change wording for input device select…
Endaris Jan 21, 2026
0ac9d6e
add a disclaimer label to warn users about the quality of the transla…
Endaris Jan 22, 2026
6381509
remove unused function from Player
Endaris Jan 22, 2026
044076e
make ChangeInputButton use Players array directly and remove unused code
Endaris Jan 22, 2026
c9bc45e
consolidate ChangeInputButton by making the inputdevice assignment cl…
Endaris Jan 22, 2026
c2b0e47
open InputDeviceOverlay actively through CharacterSelect instead of h…
Endaris Jan 22, 2026
13f70f6
fix annotations for InputDeviceOverlay
Endaris Jan 22, 2026
2569f07
make InputDeviceOverlay work directly with players instead of going t…
Endaris Jan 23, 2026
d039599
remove unused functions from BattleRoom that have been moved to Playe…
Endaris Jan 23, 2026
9b2d60e
patch up some annotations and remove fuzziness when local inputConfig…
Endaris Jan 23, 2026
1b554a9
always set inputMethod with restrictInputs and don't reset it with un…
Endaris Jan 23, 2026
93f54ca
fix construction args of InputDeviceOverlay for PuzzleMenu
Endaris Jan 23, 2026
1a9acd2
update localization some more, widen labels for keybinds to fit the text
Endaris Jan 23, 2026
0daa5ed
fix localization not being refreshed after selecting language in the …
Endaris Jan 23, 2026
0080fa8
always show the input menu on first start up, just to be sure
Endaris Jan 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions COPYING-ASSETS
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ CC BY-SA 4.0
CC BY-NC-SA 4.0
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/

CC0 1.0
To view a copy of this license, visit http://creativecommons.org/publicdomain/zero/1.0/

SIL OPEN FONT LICENSE
Version 1.1 - 26 February 2007
PREAMBLE
Expand Down Expand Up @@ -230,6 +233,17 @@ themes/Panel Attack Modern/sfx/thud_#
The conclusion is that we cannot obtain new licenses by fault of the licensor but the already acquired license is valid.
Accordingly these assets should be replaced as soon as convenient or once the licensor becomes available again, maintainers shall obtain additional licenses, whichever is first.

themes/Panel Attack Modern/input/
Copyright (C) Kenney
License: CC0 1.0
https://kenney.nl/assets/input-prompts

themes/Panel Attack Modern/input/controller_snes
themes/Panel Attack Modern/input/controller_n64
themes/Panel Attack Modern/input/error
Copyright (C) 2025 JamBox
License: CC0 1.0

Characters
==========

Expand Down
36 changes: 31 additions & 5 deletions client/assets/localization.csv
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ large_garbage,Training mode that drops huge chain blocks,Large Garbage,Gros déc
width,width of garbage blocks in training mode,Width,Largeur,Largura,幅,Ancho,Breite,Larghezza,ความกว้างก้อนขยะ
height,height of garbage blocks in training mode,Height,Hauteur,Altura,高さ,Altura,Höhe,Altezza,ความสูงก้อนขยะ
vs,,vs,vs,vs,対,vs,vs,vs,vs
up,,Up,Haut,Cima,上,Arriba,hoch,Su,ขึ้น
down,,Down,Bas,Baixo,下,Abajo,runter,Giù,ลง
left,,Left,Gauche,Esquerda,左,Izquierda,links,Sinistra,ซ้าย
right,,Right,Droite,Direita,右,Derecha,rechts,Destra,ขวา
up,,Up,Haut,Cima,上,Arriba,Hoch,Su,ขึ้น
down,,Down,Bas,Baixo,下,Abajo,Runter,Giù,ลง
left,,Left,Gauche,Esquerda,左,Izquierda,Links,Sinistra,ซ้าย
right,,Right,Droite,Direita,右,Derecha,Rechts,Destra,ขวา
start,,Start,Start,Começar,START,Empezar,Start,Avvio,เริ่ม
raise,button used to raise the stack,Raise,Monter,Levantar,高める,Elevar,Heben,Aumentare,เลื่อน board ขึ้น
raise,button used to raise the stack with touch inputs,Raise,Monter,Levantar,高める,Elevar,Anheben,Aumentare,เลื่อน board ขึ้น
player,,Player,Joueur,Jogador,プレイヤー,Jugador,Spieler,Giocatore,ผู้เล่น
player_n,,Player %1,Joueur %1,Jogador %1,プレイヤー%1,Jugador %1,Spieler %1,Giocatore %1,ผูู้เล่น %1
page,,Page,Page,Página,ページ,Página,Seite,Pagina,หน้า
Expand Down Expand Up @@ -638,3 +638,29 @@ mod_manage_submods,Label for submods in mod management,Sub Mods,Sous-mods,Submod
mod_manage_enabled,Label for enabled in mod management,Enabled,Activé,Ativado,有効,Activado,Aktiviert,Abilitato,เปิดใช้งาน
mm_2_time,,2P time attack,2J contre la montre,2J contra o tempo,2P スコアアタック,2J Contrareloj,2P Time Attack,2P a tempo,2P time attack
op_about_puzzles,,About custom puzzles,À propos des puzzles personnalisés,Sobre quebra-cabeças personalizados,カスタムパズルについて,Acerca de rompecabezas personalizados,How to: Eigene Puzzles erstellen,A proposito dei puzzle personalizzabili,เกี่ยวกับ custom puzzles
discord_welcome_title,Title for Discord community welcome screen,Welcome to Panel Attack!,Bienvenue dans Panel Attack!,Bem-vindo ao Panel Attack!,パネルアタックへようこそ!,¡Bienvenido a Panel Attack!,Willkommen bei Panel Attack!,Benvenuti in Panel Attack!,ยินดีต้อนรับสู่ Panel Attack!
discord_message_line1,First line of Discord welcome message,"Join our Discord to meet players, share ideas, and talk all things Panel Attack.","Rejoignez notre Discord pour rencontrer des joueurs, partager vos idées et discuter de tout ce qui concerne Panel Attack.","Junte-se ao nosso Discord para conhecer jogadores, compartilhar ideias e falar tudo sobre Panel Attack.","Discordに参加してプレイヤーと出会い、アイデアを共有し、パネルアタックのすべてについて語り合いましょう。","Únete a nuestro Discord para conocer jugadores, compartir ideas y hablar de todo lo relacionado con Panel Attack.","Tritt unserem Discord bei, lerne Spieler kennen, teile Ideen und sprich über alles rund um Panel Attack.","Unisciti al nostro Discord per conoscere giocatori, condividere idee e parlare di tutto ciò che riguarda Panel Attack.","เข้าร่วม Discord ของเราเพื่อพบปะผู้เล่น แชร์ไอเดีย และพูดคุยทุกเรื่องเกี่ยวกับ Panel Attack"
discord_message_line2,Second line of Discord welcome message,"Show off your mods and art, rediscover classic characters and stages, and create exciting new ones.","Présentez vos mods et vos créations, redécouvrez des personnages et des stages classiques, et créez-en de nouveaux passionnants.","Mostre seus mods e artes, redescubra personagens e fases clássicas e crie novidades empolgantes.","自分のMODやアートを披露し、クラシックなキャラクターやステージを再発見し、ワクワクする新しい作品を作りましょう。","Presume tus mods y arte, redescubre personajes y escenarios clásicos y crea otros nuevos emocionantes.","Zeige deine Mods und Kunst, entdecke bekannte Charaktere und Arenen neu und erschaffe deine eigenen.","Mostra i tuoi mod e le tue opere, riscopri personaggi e stage classici e crea nuove emozionanti creazioni.","โชว์ม็อดและงานศิลป์ของคุณ ค้นพบตัวละครและฉากคลาสสิกอีกครั้ง และสร้างสิ่งใหม่ที่น่าตื่นเต้น"
discord_message_line3,Third line of Discord welcome message,"Compete in monthly tournaments and join events for players of every skill level!","Participez à des tournois mensuels et rejoignez des événements pour tous les niveaux !","Compita em torneios mensais e participe de eventos para jogadores de todos os níveis!","毎月のトーナメントで競い合い、あらゆるスキルレベルのプレイヤー向けのイベントに参加しましょう!","Compite en torneos mensuales y únete a eventos para jugadores de todos los niveles.","Tritt in monatlichen Turnieren an und nimm an Events für Spielende aller Fähigkeitsstufen teil!","Competi nei tornei mensili e partecipa a eventi per giocatori di ogni livello di abilità!","เข้าร่วมแข่งขันในทัวร์นาเมนต์รายเดือนและกิจกรรมสำหรับผู้เล่นทุกระดับฝีมือ!"
discord_join_link,Button to join Discord server,Join Discord Server,Rejoindre le serveur Discord,Entrar no servidor Discord,Discordサーバーに参加,Unirse al servidor Discord,Discord-Server beitreten,Unisciti al server Discord,เข้าร่วมเซิร์ฟเวอร์ Discord
next_button,Text shown to continue to next screen,Next,Suivant,Próximo,次へ,Siguiente,Weiter,Avanti,ถัดไป
input_config_new_controller,Message shown when a new controller is detected and configured,"Input configurations added, please verify the button mappings, especially the Confirm, Cancel and Raise keys",Nouvelle manette détectée ! Veuillez vérifier les mappages des boutons.,Novo controlador detectado! Verifique os mapeamentos dos botões.,新しいコントローラーが検出されました!ボタンマッピングを確認してください。,¡Nuevo controlador detectado! Por favor verifique los mapeos de botones.,Neuer Controller erkannt! Bitte überprüfe die Tastenbelegung.,Nuovo controller rilevato! Verifica le mappature dei pulsanti.,ตรวจพบจอยใหม่! กรุณาตรวจสอบการตั้งค่าปุ่ม
swap1,Input configuration label for first swap button,Swap 1 / Select / Confirm,Échanger 1,Trocar 1,スワップ1,Intercambiar 1 / Seleccionar / Confirmar,Tausch 1 / Auswählen / Bestätigen,Scambia 1,สลับ 1
swap2,Input configuration label for second swap button,Swap 2 / Back,Échanger 2,Trocar 2,スワップ2,Intercambiar 2 / Volver,Tausch 2 / Zurück,Scambia 2,สลับ 2
raise1,Input configuration label for first raise button,Raise 1 / Previous Page,Monter 1,Levantar 1,上げる1,Elevar 1 / Página anterior,Stapel anheben 1 / Vorherige Seite,Alza 1,เลื่อน 1
raise2,Input configuration label for second raise button,Raise 2 / Next Page,Monter 2,Levantar 2,上げる2,Elevar 2 / Página posterior,Stapel anheben 2 / Nächste Seite,Alza 2,เลื่อน 2
tauntup,Input configuration label for taunt up button,Taunt Up / Reset Puzzle,Provocation Haut,Provocação Cima,挑発上,Burla Arriba,Spott 1 / Puzzle zurücksetzen,Provocazione Su,เยาะเย้ยขึ้น
tauntdown,Input configuration label for taunt down button,Taunt Down,Provocation Bas,Provocação Baixo,挑発下,Burla Abajo,Spott 2,Provocazione Giù,เยาะเย้ยลง
change_input_device,Label for changing input device,Change Input Device,Changer de périphérique d'entrée,Alterar dispositivo de entrada,入力デバイスを変更,Cambiar dispositivo de entrada,Eingabegerät ändern,Cambia dispositivo di input,เปลี่ยนอุปกรณ์ควบคุม
hold_button_device,Prompt to press a button on desired input device,Hold a button on the device you want to use,Maintenez enfoncé un bouton sur l'appareil que vous souhaitez utiliser,Mantenha premido um botão no dispositivo que pretende utilizar,使用したいデバイスのボタンを押し続けてください,Mantenga pulsado un botón en el dispositivo que desee utilizar.,"Halte auf dem Gerät, das du verwenden möchtest, eine Taste gedrückt.",Tieni premuto un pulsante sul dispositivo che desideri utilizzare,กดปุ่มบนอุปกรณ์ที่คุณต้องการใช้
or_touch_player_slot,Prompt to touch player slot for touch input,or touch the player slot if you want to use touch,ou touchez l'emplacement du joueur si vous souhaitez utiliser le tactile,ou toque no espaço do jogador se quiser usar toque,またはタッチを使用する場合はプレイヤースロットをタッチしてください,o toca el espacio del jugador si quieres usar táctil,oder berühre das Spielerfeld\, wenn du Touch verwenden möchtest,o tocca lo slot del giocatore se vuoi usare il touch,หรือแตะช่องผู้เล่นหากคุณต้องการใช้ระบบสัมผัส
more_players_than_configs,Error message when there are more local players than input configurations,"There are more local players than input configurations configured.
Please configure enough input configurations and try again","Il y a plus de joueurs locaux que de configurations d'entrée configurées.
Veuillez configurer suffisamment de configurations d'entrée et réessayer.","Há mais jogadores locais do que configurações de entrada configuradas.
Configure configurações de entrada suficientes e tente novamente.","ローカルプレイヤーの数がコンフィグ数より多い。
十分なインプットコンフィグを設定してもう一度試してください。","Hay más jugadores locales que configuraciones de entrada configuradas.
Configure suficientes configuraciones de entrada e intente de nuevo.","Es gibt mehr lokale Spieler als Eingabekonfigurationen.
Bitte konfiguriere genügend Eingabemethoden und versuche es erneut.","Ci sono più giocatori locali che configurazioni di input configurate.
Si prega di configurare sufficienti configurazioni di input e riprovare.","มีผู้เล่นท้องถิ่นมากกว่าการกำหนดค่า input
โปรดกำหนดค่า input เพียงพอและลองอีกครั้ง"
translation_disclaimer,Disclaimer shown in language selection to inform about the quality / source of translation,"Initial translation is performed with tools and may be substandard. Translation is open to improvements from the community.","La traduction initiale est effectuée à l'aide d'outils et peut être de qualité médiocre. La traduction peut être améliorée par la communauté.","A tradução inicial é feita com ferramentas e pode não estar à altura dos padrões. A tradução está aberta a melhorias da comunidade.","初期翻訳はツールによって行われ、水準に達していない可能性があります。翻訳はコミュニティからの改善を受け入れています。","La traducción inicial se realiza con herramientas y puede ser de calidad inferior. La traducción está abierta a mejoras por parte de la comunidad.","Die erste Übersetzung von neuem Text wird mit Tools durchgeführt und kann fehlerhaft sein. Übersetzungen sind offen für Verbesserungsvorschläge aus der Community.","La traduzione iniziale viene eseguita con strumenti e potrebbe non essere di qualità ottimale. La traduzione è aperta a miglioramenti da parte della comunità.",
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 51 additions & 70 deletions client/src/BattleRoom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function BattleRoom.createFromServerMessage(message)

battleRoom:updateRankedStatus(message.ranked)

battleRoom:assignInputConfigurations()
battleRoom:restoreInputConfigurations()
GAME.netClient:registerPlayerUpdates(battleRoom)

return battleRoom
Expand Down Expand Up @@ -159,7 +159,7 @@ function BattleRoom.createLocalFromGameMode(gameMode, gameScene, settingChangesU
end
end

if battleRoom:assignInputConfigurations() then
if battleRoom:restoreInputConfigurations() then
return battleRoom
else
return nil
Expand Down Expand Up @@ -413,87 +413,69 @@ function BattleRoom:startLoadingNewAssets()
end
end

-- updates a player's input configuration
-- if lock is true it tries to claim the first unclaim inputConfiguration for which a key is down (may not claim any)
-- if lock is false it unclaims the player's current inputConfiguration
function BattleRoom.updateInputConfigurationForPlayer(player, lock)
if lock then
for i, inputConfiguration in ipairs(GAME.input.inputConfigurations) do
if not inputConfiguration.claimed and tableUtils.length(inputConfiguration.isDown) > 0 then
-- assign the first unclaimed input configuration that is used
player:setInputMethod("controller")
logger.debug("Claiming input configuration " .. i .. " for player " .. player.playerNumber)
player:restrictInputs(inputConfiguration)
break
-- Validates that there are enough input configurations for local players and attempts to restore previous assignments
function BattleRoom:restoreInputConfigurations()
local localPlayers = self:getLocalHumanPlayers()

if #GAME.input:getAssignableDevices() < #localPlayers then
local transition = MessageTransition(GAME.timer, 5, "more_players_than_configs")
GAME.navigationStack:popToTop(transition, function() self:shutdown() end)
return false
end

-- Try to restore previous device assignments
for _, player in ipairs(localPlayers) do
if player.lastUsedInputConfiguration then
-- Check if the device is available (not already claimed by another player)
local deviceAvailable = true
for _, otherPlayer in ipairs(localPlayers) do
if otherPlayer ~= player and otherPlayer.inputConfiguration == player.lastUsedInputConfiguration then
deviceAvailable = false
break
end
end
end
if not player.inputConfiguration and not GAME.input.mouse.claimed then
if tableUtils.length(GAME.input.mouse.isDown) > 0 or tableUtils.length(GAME.input.mouse.isPressed) > 0 then
player:setInputMethod("touch")
logger.debug("Claiming touch configuration for player " .. player.playerNumber)
player:restrictInputs(GAME.input.mouse)

if deviceAvailable then
local success = self:claimDeviceForPlayer(player, player.lastUsedInputConfiguration)
if success then
logger.debug(string.format("BattleRoom: restored device for player %d", player.playerNumber))
end
end
end
else
-- player can always go from controller to touch but not the other way around
player:setInputMethod("controller")
player:unrestrictInputs()
end

return true
end

-- sets up the process to get an input configuration assigned for every local player
-- returns false if there are more players than input configurations
function BattleRoom:assignInputConfigurations()
-- Gets all local human players in the battle room
---@return Player[] localHumanPlayers
function BattleRoom:getLocalHumanPlayers()
local localPlayers = {}
for i = 1, #self.players do
if self.players[i].isLocal and self.players[i].human then
localPlayers[#localPlayers + 1] = self.players[i]
for _, player in ipairs(self.players) do
if player.isLocal and player.human then
localPlayers[#localPlayers + 1] = player
end
end
return localPlayers
end

-- assert that there are enough valid input configurations actually configured
-- 1 is the baseline because you can always use touch without configuration
local validInputConfigurationCount = 1
for _, inputConfiguration in ipairs(GAME.input.inputConfigurations) do
if inputConfiguration["Swap1"] then
validInputConfigurationCount = validInputConfigurationCount + 1
end
end
-- Claims an input device for a specific player
function BattleRoom:claimDeviceForPlayer(player, device)
assert(player, "player is required")
assert(device, "device is required")
logger.debug(string.format("BattleRoom:claimDeviceForPlayer player=%s device=%s", tostring(player.playerNumber), tostring(device)))

if validInputConfigurationCount < #localPlayers then
local messageText = "There are more local players than input configurations configured." ..
"\nPlease configure enough input configurations and try again"
local transition = MessageTransition(GAME.timer, 5, messageText)
GAME.navigationStack:popToTop(transition, function() self:shutdown() end)
return false
else
if #localPlayers == 1 then
-- lock the inputConfiguration whenever the player readies up (and release it when they unready)
-- the ready up press guarantees that at least 1 input config has a key down
localPlayers[1]:connectSignal("wantsReadyChanged", localPlayers[1], self.updateInputConfigurationForPlayer)
elseif #localPlayers > 1 then
-- with multiple local players we need to lock immediately so they can configure
-- set a flag so this is continuously attempted in update
self.tryLockInputs = true
end
if player.inputConfiguration == device then
logger.debug("BattleRoom:claimDeviceForPlayer device already assigned to player")
return true
end

return true
end
assert(not device.claimed or device.player == player, "device already claimed by another player")

-- tries to assign unclaimed input configurations for all local players based on currently used inputs
function BattleRoom:tryAssignInputConfigurations()
if self.tryLockInputs then
for _, player in ipairs(self.players) do
if player.isLocal and player.human and not player.inputConfiguration then
BattleRoom.updateInputConfigurationForPlayer(player, true)
end
end
self.tryLockInputs = tableUtils.trueForAny(self.players,
function(p)
return p.isLocal and p.human and not p.inputConfiguration
end)
end
player:unrestrictInputs()
player:restrictInputs(device)

return true
end

function BattleRoom:update(dt)
Expand All @@ -502,7 +484,6 @@ function BattleRoom:update(dt)

if self.state == BattleRoom.states.Setup then
-- the setup phase of the room
self:tryAssignInputConfigurations()
self:updateLoadingState()
self:refreshReadyStates()
if self:allReady() then
Expand Down
Loading