From eeea4a6380736b536c3cfbe01df9e7f343607828 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:16:34 +0900 Subject: [PATCH 1/8] add skirmish parsing --- .../valorant/MatchGroup/Input/Custom.lua | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lua/wikis/valorant/MatchGroup/Input/Custom.lua b/lua/wikis/valorant/MatchGroup/Input/Custom.lua index d736ac473d8..786c6a5cb4f 100644 --- a/lua/wikis/valorant/MatchGroup/Input/Custom.lua +++ b/lua/wikis/valorant/MatchGroup/Input/Custom.lua @@ -12,6 +12,7 @@ local AgentNames = Lua.import('Module:AgentNames') local FnUtil = Lua.import('Module:FnUtil') local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') +local Page = Lua.import('Module:Page') local Table = Lua.import('Module:Table') local MatchGroupInputUtil = Lua.import('Module:MatchGroup/Input/Util') @@ -148,6 +149,56 @@ function MatchFunctions.getExtraData(match, games, opponents) return { mapveto = MatchGroupInputUtil.getMapVeto(match), mvp = MatchGroupInputUtil.readMvp(match, opponents), + skirmish = MatchFunctions.parseSkirmish(match, opponents), + } +end + +---@param match table +---@param opponents MGIParsedOpponent[] +---@return table? +function MatchFunctions.parseSkirmish(match, opponents) + local skirmishData = match.skirmish + if Logic.isEmpty(skirmishData) then + return + end + + ---@param playerName string? + ---@param opponentIndex integer + ---@return MGIParsedPlayer? + local function lookupPlayer(playerName, opponentIndex) + if Logic.isEmpty(playerName) then + return + end + ---@cast playerName -nil + local nameComponents = Array.parseCommaSeparatedString(playerName, '|') + local link = Page.pageifyLink(Array.parseCommaSeparatedString(playerName, '|')[1]):gsub(' ', '_') + local playerData = Array.find( + opponents[opponentIndex].match2players, + function (match2player, playerIndex) + return match2player.name == link + end + ) + return Table.merge(playerData, { + name = link, + displayname = nameComponents[#nameComponents] + }) + end + + local player1 = lookupPlayer(skirmishData.t1p1, 1) + local player2 = lookupPlayer(skirmishData.t2p1, 2) + if Logic.isEmpty(player1) or Logic.isEmpty(player2) then + return + end + local scores = Array.mapIndexes(function (index) + return tonumber(skirmishData['score' .. index]) + end) + if #scores ~= 2 then + return + end + return { + players = {player1, player2}, + scores = scores, + winner = tonumber(skirmishData.winner) or (scores[1] > scores[2] and 1 or 2) } end From fcff0e5433bce4bc412a34894ada0bffeafc8e07 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:57:43 +0900 Subject: [PATCH 2/8] add skirmish display to matchpage --- .../valorant/MatchGroup/Input/Custom.lua | 7 +- lua/wikis/valorant/MatchPage.lua | 12 +++ .../Widget/Match/Summary/Skirmish.lua | 89 +++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua diff --git a/lua/wikis/valorant/MatchGroup/Input/Custom.lua b/lua/wikis/valorant/MatchGroup/Input/Custom.lua index 786c6a5cb4f..433fcf5bcca 100644 --- a/lua/wikis/valorant/MatchGroup/Input/Custom.lua +++ b/lua/wikis/valorant/MatchGroup/Input/Custom.lua @@ -72,6 +72,11 @@ local VALORANT_REGIONS = {'eu', 'na', 'ap', 'kr', 'latam', 'br', 'pbe1', 'esport ---@field totalKastRounds integer ---@field damageDealt integer +---@class ValorantSkirmishResult +---@field players MGIParsedPlayer[] +---@field scores number[] +---@field winner number + ---@param match table ---@param options table? ---@return table @@ -155,7 +160,7 @@ end ---@param match table ---@param opponents MGIParsedOpponent[] ----@return table? +---@return ValorantSkirmishResult? function MatchFunctions.parseSkirmish(match, opponents) local skirmishData = match.skirmish if Logic.isEmpty(skirmishData) then diff --git a/lua/wikis/valorant/MatchPage.lua b/lua/wikis/valorant/MatchPage.lua index 0d18713eef9..6ff69e9a544 100644 --- a/lua/wikis/valorant/MatchPage.lua +++ b/lua/wikis/valorant/MatchPage.lua @@ -21,6 +21,8 @@ local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom') local Html = Lua.import('Module:Widget/Html') local Carousel = Lua.import('Module:Widget/Basic/Carousel') local Div = Html.Div +local Comment = Lua.import('Module:Widget/Match/Page/Comment') +local Div = Html.Div local GeneralCollapsible = Lua.import('Module:Widget/GeneralCollapsible/Default') local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') local IconImage = Lua.import('Module:Widget/Image/Icon/Image') @@ -29,6 +31,7 @@ local PlayerDisplay = Lua.import('Module:Widget/Match/Page/PlayerDisplay') local PlayerStat = Lua.import('Module:Widget/Match/Page/PlayerStat') local PlayerStatContainer = Lua.import('Module:Widget/Match/Page/PlayerStat/Container') local RoundsOverview = Lua.import('Module:Widget/Match/Page/RoundsOverview') +local SkirmishDisplay = Lua.import('Module:Widget/Match/Summary/Skirmish') local Span = Html.Span local StatsList = Lua.import('Module:Widget/Match/Page/StatsList') local WidgetUtil = Lua.import('Module:Widget/Util') @@ -645,4 +648,13 @@ function MatchPage:_renderPlayerPerformance(player) } end +---@return VNode[]? +function MatchPage:addComments() + local skirmishData = self.matchData.extradata.skirmish + ---@cast skirmishData ValorantSkirmishResult + return { + Comment{children = SkirmishDisplay(skirmishData)} + } +end + return MatchPage diff --git a/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua new file mode 100644 index 00000000000..68f82b5e052 --- /dev/null +++ b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua @@ -0,0 +1,89 @@ +--- +-- @Liquipedia +-- page=Module:Widget/Match/Summary/Skirmish +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Array = Lua.import('Module:Array') +local Logic = Lua.import('Module:Logic') +local PlayerDisplay = Lua.import('Module:Player/Display/Custom') + +local Component = Lua.import('Module:Widget/Component') +local Html = Lua.import('Module:Widget/Html') +local Div = Html.Div + +---@return Widget? +local function ValorantSkirmishDisplay(props) + if Logic.isEmpty(props) then + return + end + local players = Array.map( + props.players, + function (player) + ---@type standardPlayer + return { + displayName = player.displayname, + pageName = player.name, + flag = player.flag, + } + end + ) + return Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + }, + children = { + Html.B{ + css = { + ['grid-column'] = '1 / -1' + }, + children = 'Skirmish Side Selection Result' + }, + Html.Span{ + css = { + ['justify-self'] = 'end', + }, + children = PlayerDisplay.InlinePlayer{ + flip = true, + player = players[1], + } + }, + Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + }, + children = Array.interleave( + Array.map( + props.scores, + function (score, scoreIndex) + return Html.Span{ + css = props.winner == scoreIndex and { + ['font-weight'] = 'bold' + } or nil, + children = score, + } + end + ), + Html.Span{children = '–'} + ) + }, + Html.Span{ + css = { + ['justify-self'] = 'start', + }, + children = PlayerDisplay.InlinePlayer{ + player = players[2], + } + }, + } + } +end + +return Component.component(ValorantSkirmishDisplay) From 28fd150fc3cb3a44782b1142324f4d3a75a2d9c6 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:04:45 +0900 Subject: [PATCH 3/8] add to match summary --- lua/wikis/valorant/MatchSummary.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 3ba3cfb2c96..87cbd15d39f 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -15,6 +15,7 @@ local Operator = Lua.import('Module:Operator') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') +local SkirmishDisplay = Lua.import('Module:Widget/Match/Summary/Skirmish') local WidgetUtil = Lua.import('Module:Widget/Util') ---@class ValorantMatchSummary: CustomMatchSummaryInterface @@ -43,6 +44,7 @@ function CustomMatchSummary.createBody(match) return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} end) }, + SkirmishDisplay(match.extradata.skirmish), MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.MapVeto(MatchSummary.preProcessMapVeto(match.extradata.mapveto, {game = match.game})) ) From 2893b6922bc94bc287991c1cfb9ae21c1aec1926 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:37:37 +0900 Subject: [PATCH 4/8] make things work first --- lua/wikis/valorant/MatchSummary.lua | 94 ++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 87cbd15d39f..4eeb1d53624 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -11,11 +11,12 @@ local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') +local PlayerDisplay = Lua.import('Module:Player/Display/Custom') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') -local SkirmishDisplay = Lua.import('Module:Widget/Match/Summary/Skirmish') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') local WidgetUtil = Lua.import('Module:Widget/Util') ---@class ValorantMatchSummary: CustomMatchSummaryInterface @@ -37,19 +38,96 @@ function CustomMatchSummary.createBody(match) return WidgetUtil.collect( MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', - children = Array.map(match.games, function (game, gameIndex) - if Logic.isEmpty(game.map) then - return - end - return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} - end) + children = WidgetUtil.collect( + Array.map(match.games, function (game, gameIndex) + if Logic.isEmpty(game.map) then + return + end + return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} + end), + CustomMatchSummary._createSkirmishDisplay(match.extradata.skirmish) + ) }, - SkirmishDisplay(match.extradata.skirmish), MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.MapVeto(MatchSummary.preProcessMapVeto(match.extradata.mapveto, {game = match.game})) ) end +---@param skirmishData ValorantSkirmishResult +---@return Widget? +function CustomMatchSummary._createSkirmishDisplay(skirmishData) + if Logic.isEmpty(skirmishData) then + return + end + local players = Array.map( + skirmishData.players, + function (player) + ---@type standardPlayer + return { + displayName = player.displayname, + pageName = player.name, + flag = player.flag, + } + end + ) + return HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-row'}, + children = { + HtmlWidgets.B{ + css = { + ['grid-column'] = '1 / -1', + ['justify-self'] = 'center', + }, + children = 'Skirmish Side Selection Result' + }, + HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-row-detail'}, + children = { + HtmlWidgets.Span{ + css = { + ['justify-self'] = 'end', + }, + children = PlayerDisplay.InlinePlayer{ + flip = true, + player = players[1], + } + }, + HtmlWidgets.Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + ['justify-self'] = 'center', + }, + children = Array.interleave( + Array.map( + skirmishData.scores, + function (score, scoreIndex) + return HtmlWidgets.Span{ + css = skirmishData.winner == scoreIndex and { + ['font-weight'] = 'bold' + } or nil, + children = score, + } + end + ), + HtmlWidgets.Span{children = '–'} + ) + }, + HtmlWidgets.Span{ + css = { + ['justify-self'] = 'start', + }, + children = PlayerDisplay.InlinePlayer{ + player = players[2], + } + }, + } + }, + } + } +end + ---@return string function ValorantMatchSummaryGameRow:createGameOverview() return self:mapDisplay() From c5bb956b11594813cbf0aff04e628f797f7ee90c Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:49:58 +0900 Subject: [PATCH 5/8] fix bad rebase --- lua/wikis/valorant/MatchPage.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/wikis/valorant/MatchPage.lua b/lua/wikis/valorant/MatchPage.lua index 6ff69e9a544..c223ecf7e12 100644 --- a/lua/wikis/valorant/MatchPage.lua +++ b/lua/wikis/valorant/MatchPage.lua @@ -22,7 +22,6 @@ local Html = Lua.import('Module:Widget/Html') local Carousel = Lua.import('Module:Widget/Basic/Carousel') local Div = Html.Div local Comment = Lua.import('Module:Widget/Match/Page/Comment') -local Div = Html.Div local GeneralCollapsible = Lua.import('Module:Widget/GeneralCollapsible/Default') local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') local IconImage = Lua.import('Module:Widget/Image/Icon/Image') From d2ccd93c170bfc819eda39235ad1101915e864f8 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:51:46 +0900 Subject: [PATCH 6/8] finishing touches --- lua/wikis/valorant/MatchPage.lua | 3 +++ lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lua/wikis/valorant/MatchPage.lua b/lua/wikis/valorant/MatchPage.lua index c223ecf7e12..28861d9fbb5 100644 --- a/lua/wikis/valorant/MatchPage.lua +++ b/lua/wikis/valorant/MatchPage.lua @@ -650,6 +650,9 @@ end ---@return VNode[]? function MatchPage:addComments() local skirmishData = self.matchData.extradata.skirmish + if Logic.isEmpty(skirmishData) then + return + end ---@cast skirmishData ValorantSkirmishResult return { Comment{children = SkirmishDisplay(skirmishData)} diff --git a/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua index 68f82b5e052..15535cdbbca 100644 --- a/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua +++ b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua @@ -15,7 +15,8 @@ local Component = Lua.import('Module:Widget/Component') local Html = Lua.import('Module:Widget/Html') local Div = Html.Div ----@return Widget? +---@param props ValorantSkirmishResult +---@return VNode? local function ValorantSkirmishDisplay(props) if Logic.isEmpty(props) then return From 0bfc40f84ca11fa29fe9b78b07f3c44bc5a39789 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:15:06 +0900 Subject: [PATCH 7/8] automate skirmish winner only if the match is finished --- lua/wikis/valorant/MatchGroup/Input/Custom.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/valorant/MatchGroup/Input/Custom.lua b/lua/wikis/valorant/MatchGroup/Input/Custom.lua index 433fcf5bcca..43e929c250e 100644 --- a/lua/wikis/valorant/MatchGroup/Input/Custom.lua +++ b/lua/wikis/valorant/MatchGroup/Input/Custom.lua @@ -203,7 +203,7 @@ function MatchFunctions.parseSkirmish(match, opponents) return { players = {player1, player2}, scores = scores, - winner = tonumber(skirmishData.winner) or (scores[1] > scores[2] and 1 or 2) + winner = tonumber(skirmishData.winner) or (match.finished and (scores[1] > scores[2] and 1 or 2) or nil) } end From 0dadf43ecd765310da191f489f17b47da627fac9 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:20:20 +0900 Subject: [PATCH 8/8] simplify parsing --- lua/wikis/valorant/MatchGroup/Input/Custom.lua | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lua/wikis/valorant/MatchGroup/Input/Custom.lua b/lua/wikis/valorant/MatchGroup/Input/Custom.lua index 43e929c250e..26a05cf2b52 100644 --- a/lua/wikis/valorant/MatchGroup/Input/Custom.lua +++ b/lua/wikis/valorant/MatchGroup/Input/Custom.lua @@ -175,18 +175,13 @@ function MatchFunctions.parseSkirmish(match, opponents) return end ---@cast playerName -nil - local nameComponents = Array.parseCommaSeparatedString(playerName, '|') - local link = Page.pageifyLink(Array.parseCommaSeparatedString(playerName, '|')[1]):gsub(' ', '_') - local playerData = Array.find( + local link = Page.pageifyLink(playerName) + return Array.find( opponents[opponentIndex].match2players, - function (match2player, playerIndex) - return match2player.name == link + function (match2player) + return match2player.name == link or match2player.displayname == link or match2player.displayname == playerName end ) - return Table.merge(playerData, { - name = link, - displayname = nameComponents[#nameComponents] - }) end local player1 = lookupPlayer(skirmishData.t1p1, 1)