@@ -20,9 +20,7 @@ public function matchup(): void
2020 // Check if current player is an observer
2121 if ($ this ->qmPlayer ->isObserver ())
2222 {
23- // If yes, then we skip the matchup because we don't want to compare
24- // observer with other actual players to find a match.
25- // Observer will be added to the match later on.
23+ Log::debug ("TeamMatchup ** {$ playerInQueue } is an observer, skipping matchup process. Will be added to match when other players form one. " );
2624 return ;
2725 }
2826
@@ -31,21 +29,44 @@ public function matchup(): void
3129 ->filter (function ($ entry ) {
3230 return $ entry ->id !== $ this ->qmQueueEntry ->id ;
3331 })->values ();
34- $ count = $ opponents ->count () + 1 ;
32+
33+ $ totalInQueue = $ opponents ->count () + 1 ;
3534 $ timeInQueue = $ this ->qmQueueEntry ->secondsinQueue ();
36- Log::debug ("FindOpponent ** inQueue= {$ playerInQueue }, players in q: {$ count }, for ladder= {$ ladder ->abbreviation }, seconds in Queue: {$ timeInQueue }" );
35+ $ waitTimeBonus = $ timeInQueue * $ ladderRules ->points_per_second ;
36+ $ effectiveRange = $ ladderRules ->max_points_difference + $ waitTimeBonus ;
37+
38+ Log::info ("=== TeamMatchup START for {$ playerInQueue } === " );
39+ Log::info (" Player: {$ playerInQueue } | Points: {$ this ->qmQueueEntry ->points } | Ladder: {$ ladder ->abbreviation }" );
40+ Log::info (" Time in queue: {$ timeInQueue }s | Wait bonus: + {$ waitTimeBonus } pts | Effective range: {$ effectiveRange } pts " );
41+ Log::info (" Total players in queue: {$ totalInQueue } (including {$ playerInQueue }) " );
42+
43+ $ allPlayerNames = $ opponents ->map (fn ($ e ) => $ e ->qmPlayer ?->player?->username ?? 'Unknown ' )->implode (', ' );
44+ Log::debug (" All players in queue: {$ playerInQueue }, {$ allPlayerNames }" );
3745
3846 // Find opponents in same tier with current player.
47+ $ beforeTierFilter = $ opponents ->count ();
3948 $ matchableOpponents = $ this ->quickMatchService ->getEntriesInSameTier ($ ladder , $ this ->qmQueueEntry , $ opponents );
49+ $ afterTierFilter = $ matchableOpponents ->count ();
50+
51+ if ($ afterTierFilter < $ beforeTierFilter ) {
52+ $ filtered = $ beforeTierFilter - $ afterTierFilter ;
53+ Log::debug (" Tier filter: {$ filtered } players filtered out ( {$ afterTierFilter } remain in same tier) " );
54+ }
4055
41- // Find opponents that can be matched with current player.
56+ // Find opponents that can be matched with current player based on points .
4257 $ matchableOpponents = $ this ->getEntriesInPointRange2v2 ($ this ->qmQueueEntry , $ matchableOpponents );
4358
4459 $ opponentCount = $ matchableOpponents ->count ();
4560 $ matchableNames = $ matchableOpponents ->map (function ($ entry ) {
4661 return $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
4762 })->implode (', ' );
48- Log::debug ("FindOpponent ** inQueue= {$ playerInQueue }, amount of matchable opponent after point filter: {$ opponentCount } of {$ count }. Names: [ {$ matchableNames }] " );
63+
64+ if ($ opponentCount > 0 ) {
65+ Log::info (" ✅ Point filter passed: {$ opponentCount } matchable opponents found " );
66+ Log::debug (" Matchable players: [ {$ matchableNames }] " );
67+ } else {
68+ Log::info (" ❌ Point filter: No matchable opponents found after point range validation " );
69+ }
4970
5071 // Count the number of players we need to start a match
5172 // Excluding current player
@@ -55,64 +76,84 @@ public function matchup(): void
5576 $ matchableOpponentsCount = $ matchableOpponents ->count ();
5677 if ($ matchableOpponentsCount < $ numberOfOpponentsNeeded )
5778 {
58- Log::debug ("FindOpponent ** inQueue= {$ playerInQueue }, Team matchup handler ** Not enough players for match yet ( $ matchableOpponentsCount of $ numberOfOpponentsNeeded) " );
79+ Log::info (" ❌ MATCH FAILED: Not enough players ( {$ matchableOpponentsCount }/ {$ numberOfOpponentsNeeded } needed) " );
80+ Log::info ("=== TeamMatchup END for {$ playerInQueue } - NO MATCH === \n" );
5981 $ this ->qmPlayer ->touch ();
6082 return ;
6183 }
6284
85+ Log::debug (" ✅ Sufficient players found, attempting to form teams... " );
86+
6387 [$ teamAPlayers , $ teamBPlayers , $ stats ] = $ this ->quickMatchService ->getBestMatch2v2ForPlayer (
6488 $ this ->qmQueueEntry ,
6589 $ matchableOpponents ,
6690 $ this ->history
6791 );
6892
69- Log::debug ("FindOpponent ** TEAMS : "
70- . json_encode ($ teamAPlayers ) . ' VS '
71- . json_encode ($ teamBPlayers ));
72-
7393 // Log player names and their team
7494 $ teamALog = $ teamAPlayers ->map (function ($ entry ) {
75- return $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
95+ $ pts = $ entry ->points ;
96+ $ name = $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
97+ return "{$ name } ( {$ pts } pts) " ;
7698 })->implode (', ' );
7799 $ teamBLog = $ teamBPlayers ->map (function ($ entry ) {
78- return $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
100+ $ pts = $ entry ->points ;
101+ $ name = $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
102+ return "{$ name } ( {$ pts } pts) " ;
79103 })->implode (', ' );
80- Log::debug ("Team A ( " . $ teamAPlayers ->count () . "): " . $ teamALog );
81- Log::debug ("Team B ( " . $ teamBPlayers ->count () . "): " . $ teamBLog );
104+
105+ Log::info (" Teams formed: " );
106+ Log::info (" Team A ( {$ teamAPlayers ->count ()}): {$ teamALog }" );
107+ Log::info (" Team B ( {$ teamBPlayers ->count ()}): {$ teamBLog }" );
82108
83109 // Ensure both teams have exactly two players
84110 if ($ teamAPlayers ->count () !== 2 || $ teamBPlayers ->count () !== 2 ) {
85- Log::warning ("Team size error: Team A has {$ teamAPlayers ->count ()} players, Team B has {$ teamBPlayers ->count ()} players. Expected 2 each. " );
111+ Log::warning (" ⚠️ Team size error: Team A has {$ teamAPlayers ->count ()} players, Team B has {$ teamBPlayers ->count ()} players. Expected 2 each. " );
86112 }
87113
88114 $ players = $ teamAPlayers ->merge ($ teamBPlayers );
89115
90116 $ commonQmMaps = $ this ->quickMatchService ->getCommonMapsForPlayers ($ ladder , $ players );
117+ $ mapCount = count ($ commonQmMaps );
91118
92- if (count ( $ commonQmMaps ) < 1 )
119+ if ($ mapCount < 1 )
93120 {
94- Log::info ("FindOpponent ** No common maps available " );
121+ Log::info (" ❌ MATCH FAILED: No common maps available between all players " );
122+ Log::info ("=== TeamMatchup END for {$ playerInQueue } - NO MATCH === \n" );
95123 $ this ->qmPlayer ->touch ();
96124 return ;
97125 }
98126
127+ Log::debug (" ✅ Map validation: {$ mapCount } common maps available " );
128+
99129 // Add observers to the match if there is any (maximum of one observer per match)
100130 // Prioritize observers who have been waiting the longest
101- $ observers = $ opponents
102- ->filter (fn (QmQueueEntry $ qmQueueEntry ) => $ qmQueueEntry ->qmPlayer ?->isObserver())
103- ->sortBy ('created_at ' )
104- ->take (1 );
105- if ($ observers ->count () > 0 )
106- {
131+ $ allObservers = $ opponents ->filter (fn (QmQueueEntry $ qmQueueEntry ) => $ qmQueueEntry ->qmPlayer ?->isObserver());
132+ $ observers = $ allObservers ->sortBy ('created_at ' )->take (1 );
133+
134+ if ($ observers ->count () > 0 ) {
107135 $ this ->matchHasObservers = true ;
136+ $ observerName = $ observers ->first ()->qmPlayer ?->player?->username ?? 'Unknown ' ;
137+ $ observerWait = $ observers ->first ()->secondsinQueue ();
138+ Log::info (" 👁 Observer added: {$ observerName } (waited {$ observerWait }s) " );
139+
140+ if ($ allObservers ->count () > 1 ) {
141+ $ remainingCount = $ allObservers ->count () - 1 ;
142+ Log::debug (" {$ remainingCount } other observer(s) remain in queue " );
143+ }
144+ } else {
145+ Log::debug (" No observers in queue " );
108146 }
109147
110148 // Throw exception if team sizes are not exactly two
111149 if ($ teamAPlayers ->count () !== 2 || $ teamBPlayers ->count () !== 2 ) {
112- Log::warning ( " Team size error: Team A has {$ teamAPlayers ->count ()} players , Team B has {$ teamBPlayers ->count ()} players. Expected 2 each. " );
150+ Log::error ( " ❌ MATCH FAILED: Invalid team sizes - Team A: {$ teamAPlayers ->count ()}, Team B: {$ teamBPlayers ->count ()}" );
113151 throw new \RuntimeException ("Team size error: Team A has {$ teamAPlayers ->count ()} players, Team B has {$ teamBPlayers ->count ()} players. Expected 2 each. " );
114152 }
115153
154+ Log::info (" ✅ MATCH CREATED: All validations passed, creating match... " );
155+ Log::info ("=== TeamMatchup END for {$ playerInQueue } - MATCH CREATED === \n" );
156+
116157 // Start the match with all other players and other observers if there is any
117158 $ this ->createTeamMatch ($ commonQmMaps , $ teamAPlayers , $ teamBPlayers , $ observers , $ stats );
118159 }
@@ -156,32 +197,46 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
156197 {
157198 $ rules = $ currentQmQueueEntry ->ladderHistory ->ladder ->qmLadderRules ;
158199 $ playerName = $ currentQmQueueEntry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
200+ $ playerPoints = $ currentQmQueueEntry ->points ;
201+ $ playerWaitTime = $ currentQmQueueEntry ->secondsinQueue ();
202+ $ waitBonus = $ playerWaitTime * $ rules ->points_per_second ;
159203
160- Log::debug ("2v2 Search start: queueEntry= { $ currentQmQueueEntry -> id } , name= { $ playerName } , opponentsInQueue= " . count ( $ opponents ) );
204+ Log::debug (" --- 2v2 Point Range Search for { $ playerName } ( { $ playerPoints } pts, + { $ waitBonus } wait bonus) --- " );
161205
162206 // Filter opponents to those that pass point range check with the current player
163207 $ potentialOpponents = $ this ->filterOpponentsInRange ($ currentQmQueueEntry , $ opponents , $ rules )
164208 ->filter (function ($ opponent ) use ($ currentQmQueueEntry ) {
165209 return $ opponent ->id !== $ currentQmQueueEntry ->id ;
166210 })->values ();
167211
168- Log::debug ($ potentialOpponents ->count () . " potential opponents for {$ playerName }: " . $ potentialOpponents ->pluck ('qmPlayer.player.username ' )->implode (', ' ));
212+ $ potentialCount = $ potentialOpponents ->count ();
213+ $ potentialNames = $ potentialOpponents ->map (function ($ e ) {
214+ return $ e ->qmPlayer ?->player?->username . ' ( ' . $ e ->points . ' pts) ' ;
215+ })->implode (', ' );
216+
217+ Log::debug (" Initial filter: {$ potentialCount } potential opponents pass 1-on-1 range check " );
218+ if ($ potentialCount > 0 ) {
219+ Log::debug (" Potential: {$ potentialNames }" );
220+ }
169221
170222 if ($ potentialOpponents ->count () < 3 )
171223 {
172- Log::debug ("Not enough valid opponents for { $ playerName } to form a 2v2 match: " . $ potentialOpponents -> count () . " /3 " );
224+ Log::debug (" ❌ Not enough opponents for 2v2: { $ potentialCount } /3 needed " );
173225 return collect ();
174226 }
175227
176228 // Sort opponents by a combination of point difference and time in queue bonus
177229 $ pointsPerSecond = $ rules ->points_per_second ;
178230 $ sortedOpponents = $ potentialOpponents ->sortBy (function ($ opponent ) use ($ currentQmQueueEntry , $ pointsPerSecond ) {
179231 $ pointDiff = abs ($ currentQmQueueEntry ->points - $ opponent ->points );
180- $ waitTimeBonus = ( strtotime ( $ opponent ->updated_at ) - strtotime ( $ opponent -> created_at ) ) * $ pointsPerSecond ;
232+ $ waitTimeBonus = $ opponent ->secondsinQueue ( ) * $ pointsPerSecond ;
181233 return $ pointDiff - $ waitTimeBonus ;
182234 })->values ();
183235
236+ Log::debug (" Sorted opponents by closeness (considering wait time) " );
237+
184238 // Try all possible 3-player combinations (since the current player makes 4)
239+ $ combinationsTried = 0 ;
185240 foreach ($ this ->getCombinations ($ sortedOpponents , 3 ) as $ threeOthers )
186241 {
187242 $ matchPlayers = collect ([$ currentQmQueueEntry ])->merge ($ threeOthers )->unique ('id ' )->values ();
@@ -190,17 +245,19 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
190245 continue ;
191246 }
192247
248+ $ combinationsTried ++;
249+ $ comboNames = $ matchPlayers ->pluck ('qmPlayer.player.username ' )->implode (', ' );
250+
193251 if ($ this ->allPlayersInRange ($ matchPlayers , $ rules ))
194252 {
195- Log::debug (
196- "✅ Found valid 2v2 match for {$ playerName }: " .
197- $ matchPlayers ->pluck ('qmPlayer.player.username ' )->implode (', ' )
198- );
253+ Log::debug (" ✅ Found valid 2v2 match after trying {$ combinationsTried } combination(s) " );
254+ Log::debug (" Match: {$ comboNames }" );
199255 return $ matchPlayers ;
200256 }
201257 }
202258
203- Log::debug ("❌ No valid 2v2 match found for {$ playerName }" );
259+ Log::debug (" ❌ No valid 2v2 match found after trying {$ combinationsTried } combination(s) " );
260+ Log::debug (" Reason: All combinations failed cross-player range validation " );
204261 return collect ();
205262 }
206263
@@ -214,21 +271,12 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
214271 private function getCombinations (Collection $ items , int $ size ): Collection
215272 {
216273 $ array = $ items ->all ();
217- $ allNames = collect ($ array )->map (function ($ entry ) {
218- return $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
219- })->implode (', ' );
220- Log::debug ("getCombinations called with items: [ {$ allNames }] and size: {$ size }" );
221274 $ results = [];
222275
223276 $ recurse = function ($ arr , $ size , $ start = 0 , $ current = []) use (&$ results , &$ recurse )
224277 {
225278 if (count ($ current ) === $ size )
226279 {
227- // Debug log the combination
228- $ names = collect ($ current )->map (function ($ entry ) {
229- return $ entry ->qmPlayer ?->player?->username ?? 'Unknown ' ;
230- })->implode (', ' );
231- Log::debug ("getCombinations: [ {$ names }] " );
232280 $ results [] = $ current ;
233281 return ;
234282 }
@@ -258,8 +306,10 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
258306 $ pointsPerSecond = $ rules ->points_per_second ;
259307 $ maxPointsDifference = $ rules ->max_points_difference ;
260308 $ currentPointFilter = $ current ->qmPlayer ->player ->user ->userSettings ->disabledPointFilter ;
309+ $ currentPlayer = $ current ->qmPlayer ?->player?->username ?? 'Unknown ' ;
261310
262311 $ matchable = collect ();
312+ $ filtered = collect ();
263313
264314 foreach ($ opponents as $ opponent )
265315 {
@@ -268,10 +318,12 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
268318 continue ;
269319 }
270320
321+ $ opponentName = $ opponent ->qmPlayer ?->player?->username ?? 'Unknown ' ;
271322 $ diff = abs ($ current ->points - $ opponent ->points );
272- $ waitTimeBonus = (strtotime ($ current ->updated_at ) - strtotime ($ current ->created_at )) * $ pointsPerSecond ;
323+ $ waitTimeBonus = $ current ->secondsinQueue () * $ pointsPerSecond ;
324+ $ effectiveRange = $ waitTimeBonus + $ maxPointsDifference ;
273325
274- $ inNormalRange = $ waitTimeBonus + $ maxPointsDifference > $ diff ;
326+ $ inNormalRange = $ effectiveRange > $ diff ;
275327 $ inDisabledFilterRange = $ currentPointFilter
276328 && $ opponent ->qmPlayer ->player ->user ->userSettings ->disabledPointFilter
277329 && $ diff < 1000
@@ -282,6 +334,22 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
282334 {
283335 $ matchable ->push ($ opponent );
284336 }
337+ else
338+ {
339+ $ filtered ->put ($ opponentName , [
340+ 'points ' => $ opponent ->points ,
341+ 'diff ' => $ diff ,
342+ 'range ' => $ effectiveRange ,
343+ 'reason ' => $ diff > $ effectiveRange ? 'Points too far ' : 'Filter mismatch '
344+ ]);
345+ }
346+ }
347+
348+ if ($ filtered ->count () > 0 ) {
349+ Log::debug (" Filtered out {$ filtered ->count ()} player(s) outside point range: " );
350+ foreach ($ filtered as $ name => $ info ) {
351+ Log::debug (" - {$ name } ( {$ info ['points ' ]} pts): Δ {$ info ['diff ' ]} > {$ info ['range ' ]} range " );
352+ }
285353 }
286354
287355 return $ matchable ;
@@ -308,8 +376,8 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
308376 if ($ i >= $ j ) continue ; // Skip self and duplicate checks
309377
310378 $ diff = abs ($ p1 ->points - $ p2 ->points );
311- $ waitTimeBonusP1 = ( strtotime ( $ p1 ->updated_at ) - strtotime ( $ p1 -> created_at ) ) * $ pointsPerSecond ;
312- $ waitTimeBonusP2 = ( strtotime ( $ p2 ->updated_at ) - strtotime ( $ p2 -> created_at ) ) * $ pointsPerSecond ;
379+ $ waitTimeBonusP1 = $ p1 ->secondsinQueue ( ) * $ pointsPerSecond ;
380+ $ waitTimeBonusP2 = $ p2 ->secondsinQueue ( ) * $ pointsPerSecond ;
313381
314382 $ passesNormalRange = ($ waitTimeBonusP1 + $ maxPointsDifference >= $ diff )
315383 || ($ waitTimeBonusP2 + $ maxPointsDifference >= $ diff );
@@ -328,6 +396,8 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
328396 'points1 ' => $ p1 ->points ,
329397 'points2 ' => $ p2 ->points ,
330398 'diff ' => $ diff ,
399+ 'wait1 ' => $ p1 ->secondsinQueue (),
400+ 'wait2 ' => $ p2 ->secondsinQueue (),
331401 'pass ' => $ pass
332402 ];
333403
@@ -350,20 +420,37 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
350420 */
351421 private function logComparisonTable (array $ comparisonResults ): void
352422 {
353- Log::debug ("=== 2v2 Player Comparison Table === " );
423+ Log::debug (" === 2v2 Player Pair Validation === " );
424+ $ passCount = 0 ;
425+ $ failCount = 0 ;
426+
354427 foreach ($ comparisonResults as $ result )
355428 {
356- $ status = $ result ['pass ' ] ? '✅ PASS ' : '❌ FAIL ' ;
429+ $ status = $ result ['pass ' ] ? '✅ ' : '❌ ' ;
430+ if ($ result ['pass ' ]) {
431+ $ passCount ++;
432+ } else {
433+ $ failCount ++;
434+ }
435+
436+ $ waitInfo = isset ($ result ['wait1 ' ]) && isset ($ result ['wait2 ' ])
437+ ? " | Wait: {$ result ['wait1 ' ]}s/ {$ result ['wait2 ' ]}s "
438+ : "" ;
439+
357440 Log::debug (sprintf (
358- "%-15s (%4d pts) ↔ %-15s (%4d pts) | Diff: %4d | %s " ,
441+ " %s %-15s (%4d) ↔ %-15s (%4d) | Δ%4d%s " ,
442+ $ status ,
359443 $ result ['p1 ' ],
360444 $ result ['points1 ' ],
361445 $ result ['p2 ' ],
362446 $ result ['points2 ' ],
363447 $ result ['diff ' ],
364- $ status
448+ $ waitInfo
365449 ));
366450 }
367- Log::debug ("=================================== " );
451+
452+ $ total = $ passCount + $ failCount ;
453+ Log::debug (" Summary: {$ passCount }/ {$ total } pairs passed, {$ failCount }/ {$ total } failed " );
454+ Log::debug (" ===================================== " );
368455 }
369456}
0 commit comments