Module:Game
From IFWiki
Documentation for this module may be created at Module:Game/doc
local p = {}
local cargo = mw.ext.cargo
function arrangeIntoGroups(tableName, groupName)
-- groupName is the relevant Cargo field name
local groupedTable = {}
for _, v in ipairs(tableName) do
local group = v[groupName]
if group then
if not groupedTable[group] then
groupedTable[group] = {}
end
table.insert(groupedTable[group], v)
end
end
return groupedTable
end
function displayTime(num)
local result = ""
local hours = math.floor(num / 60)
local minutes = num % 60
if hours > 0 then
result = result .. hours
if hours == 1 then
result = result .. ' hour '
else
result = result .. ' hours '
end
end
if minutes > 0 then
result = result .. minutes
if minutes == 1 then
result = result .. ' minute'
else
result = result .. ' minutes'
end
end
return result
end
function stringToTable(str)
local result = {}
if str then
for word in string.gmatch(str, "([^,]+)") do
table.insert(result, word:match("^%s*(.-)%s*$")) -- Trim spaces
end
end
return result
end
function dateFormat ( dateString, precision, uncertain )
-- Return date formatted nicely
local year=dateString:sub(1,4)
local month=dateString:sub(6,7)
local day=dateString:sub(9,10)
-- Format is YYYY-MM-DD
if precision=='3' then
-- Year only
result = year
elseif precision=='2' then
-- Year and month only
result = os.date('%B %Y', os.time({year=year, month=month, day=day}) )
else
-- Full date
result = os.date('%d %B %Y', os.time({year=year, month=month, day=day}) )
if result:sub(1,1) == '0' then
result = result:sub(2) -- get rid of leading 0
end
end
if uncertain=='1' then
result = result .. ' (uncertain)'
end
return result
end
-----------------------------------------------------------------
function p.Main( frame )
gf = require('Module:Game functions')
cab = require('Module:Combined award boxes')
local output = {}
local categories = {}
-- Easier to type
function echo(text)
table.insert(output, text)
end
function categorise(cat)
-- Could be comma-separated list e.g. system
catTable = stringToTable(cat)
for _,v in ipairs(catTable) do
table.insert(categories, v)
end
end
function parchmentPlayable(filename)
-- Parchment can play these, except ADRIFT 5's blorb
local extensions = { '.blb', '.blorb', '.taf', '.hex', '.gblorb', '.glb', '.ulx', '.gam', '.t3', '.zblorb', '.zlb', '.z3', '.z4', '.z5', '.z8' }
for _, extension in ipairs(extensions) do
if filename:sub(-#extension) == extension and authoringSystem and not string.find(authoringSystem, 'ADRIFT 5', 1, true) then
return true
end
end
return false
end
-- Get game (page) name
local game = mw.title.getCurrentTitle().text
-- Some plurals
plural = {}
plural['Author'] = 'Authors'
plural['Porter'] = 'Porters'
plural['Translator'] = 'Translators'
plural['Artist'] = 'Artists'
plural['Musician'] = 'Musicians'
plural['Tester'] = 'Testers'
plural['Distributor'] = 'Distributors'
plural['Authoring system'] = 'Authoring systems'
plural['Format'] = 'Formats'
plural['System'] = 'Systems'
plural['Literary genre'] = 'Literary genres'
plural['Location'] = 'Locations'
plural['Tag'] = 'Tags'
plural['Language'] = 'Languages'
-- Get game information from Cargo template parameters
authoringSystem = frame:getParent().args['Authoring system']
fileFormat = frame:getParent().args['File format']
zCodeVersion = frame:getParent().args['Z code version']
system = frame:getParent().args['System']
oldInfoboxDate = frame:getParent().args['Old infobox date']
interactionStyle = frame:getParent().args['Interaction style']
literaryGenre = frame:getParent().args['Literary genre']
location = frame:getParent().args['Location']
tag = frame:getParent().args['Tag']
series = frame:getParent().args['Series']
otherTitle = frame:getParent().args['Other title']
language = frame:getParent().args['Language']
IFID = frame:getParent().args['IFID']
licence = frame:getParent().args['Licence']
cruelty = frame:getParent().args['Cruelty']
accessibility = frame:getParent().args['Accessibility']
cover = frame:getParent().args['Cover']
IFArchive= frame:getParent().args['IF Archive']
CASA = frame:getParent().args['CASA']
playOnline = frame:getParent().args['Play online']
download = frame:getParent().args['Download']
sourceCode = frame:getParent().args['Source code']
IFDB = frame:getParent().args['IFDB']
IFDBIgnore = frame:getParent().args['IFDB ignore']
release = frame:getParent().args['Release']
externalLinks = frame:getParent().args['External links']
mainArticleContent = frame:getParent().args['Main article content']
-- IF Archive unbox for zip files
if IFArchive
and ( IFArchive:lower():match('%.zip$')
or IFArchive:lower():match('%.tar%.gz$')
or IFArchive:lower():match('%.tar%.z$')
or IFArchive:lower():match('%.tgz$')
)
and not IFArchive:match('^https://unbox%.ifarchive%.org') then
IFArchiveUnbox = 'https://unbox.ifarchive.org/?url=' .. IFArchive
end
-- Get data from Games table (which are in addition to parameters)
local tables = 'Games'
local fields = 'TUID, Game_date, Game_date__precision, Game_date_uncertain'
local args = {
where = '_pageName = "' .. game .. '"'
}
local results = cargo.query( tables, fields, args )
if #results~=0 then
-- These are strings
--IFDB = results[1]['IFDB']
TUID = results[1]['TUID']
gameDate = results[1]['Game_date']
gameDatePrecision = results[1]['Game_date__precision']
gameDateUncertain = results[1]['Game_date_uncertain']
end
-- Convert some to tables to make things easier later
TUIDTable = stringToTable(TUID)
IFDBTable = stringToTable(IFDB)
IFIDTable = stringToTable(IFID)
-- Get releases information from Game_releases table
local tables = 'Game_releases'
local fields = 'Date, Date__precision, Uncertain, Name, Notes'
local args = {
where = 'Game_releases._pageName="' .. game .. '"',
orderBy = '_rowID'
}
local results = cargo.query( tables, fields, args )
releases = results
-- Template:Game has already taken account of Corrected_date in setting Game_date
if gameDate then
-- Calculated by template from release information
published = gameDate
publishedPrecision = gameDatePrecision
publishedUncertain = gameDateUncertain
end
-- Get all data from Game_people table
local tables = 'Game_people'
local fields = 'Name, Pseudonym, Role'
local args = {
where = 'Game_people._pageName="' .. game .. '"',
orderBy = '_rowID'
}
local gamePerson = cargo.query( tables, fields, args )
-- Get all data from Game_companies table
local tables = 'Game_companies'
local fields = 'Name, Role'
local args = {
where = 'Game_companies._pageName="' .. game .. '"',
}
local gameCompany = cargo.query( tables, fields, args )
-- Get all data from Game_crossreferences table
local tables = 'Game_crossreferences'
local fields = 'Relationship, Game'
local args = {
where = 'Game_crossreferences._pageName="' .. game .. '"',
}
local gameCrossreference = cargo.query( tables, fields, args )
local tables = 'Game_crossreferences'
local fields = '_pageName=Original, Relationship'
local args = {
where = 'Game_crossreferences.Game="' .. game .. '"',
}
local gameCrossreferencedBy = cargo.query( tables, fields, args )
-- Get Events data from the Events and Awards tables
local tables = 'Events, Awards'
local fields = 'Events._pageName=Event, Part_of_series, Total, Award_name, Notes'
local args = {
join = 'Events._pageID=Awards._pageID',
where = 'Game="' .. game .. '"'
}
local events = cargo.query( tables, fields, args )
-- Get other games in series from Games and Game_releases tables
if series and series~='' then
local tables = 'Games, Game_releases'
local fields = 'Games._pageName=Game'
local args = {
join = 'Games._pageName = Game_releases._pageName',
where = 'Series = "' .. series .. '"',
groupBy = 'Games._pageName',
orderBy = 'Series_order, Date',
}
seriesGames = cargo.query( tables, fields, args )
end
-- If we have a TUID, then get some information from 1st IFDB link
-- Unless IFDB ignore box ticked
if TUIDTable and TUIDTable[1] and IFDBIgnore~='Yes' then
local externalData, errors = mw.ext.externaldata.getWebData {
url = 'https://ifdb.org/viewgame?ifiction&id=' .. TUIDTable[1] .. '&json',
format = 'JSON',
}
local json = not errors and externalData.__json or false
if json then
-- Assume ifdb always present
playTimeInMinutesExternal = json['ifdb']['playTimeInMinutes']
starRatingExternal = json['ifdb']['starRating']
ratingCountTotExternal = json['ifdb']['ratingCountTot']
primaryPlayOnlineUrlExternal = json['ifdb']['primaryPlayOnlineUrl']
if json['ifdb']['coverart'] then
coverUrlExternal = json['ifdb']['coverart']['url']
end
if json['bibliographic'] then
firstPublishedExternal = json['bibliographic']['firstpublished']
authorExternal = json['bibliographic']['author']
end
end
end
for i = 1, #IFIDTable do
local externalData, errors = mw.ext.externaldata.getWebData {
url = 'https://ifdb.org/viewgame?json&ifid=' .. mw.uri.encode(IFIDTable[i]),
format = 'JSON',
}
local json = not errors and externalData.__json or false
if json then
IFIDTable[i] = '[https://ifdb.org/viewgame?ifid=' .. IFIDTable[i] .. ' ' .. IFIDTable[i] .. ']'
end
end
------------------------------------------------------------
-- Begin infobox
echo('<table class="wikitable ifwiki-infobox"> ')
-- Game title
content = mw.title.getCurrentTitle():getContent()
displayTitle = content:match("{{DISPLAYTITLE:(.-)}}")
if displayTitle then
-- Use DISPLAYTITLE
citationGame = displayTitle
else
-- Use page name, minus "(by...)" or "(game)"
citationGame = string.gsub(game, "%(by [^)]+%)", "")
citationGame = string.gsub(citationGame, "%(game%)", "")
end
echo(' <tr><th colspan="2" class="ifwiki-infobox-center"> ' )
echo ( '<span style="font-size: 1.3em">' .. citationGame .. '</span>' )
if otherTitle then
echo '<br><span class="font-size: 0.85em">'
echo ( '<i>a.k.a.</i> ' .. string.gsub(otherTitle, "%s*,%s*", " <i>or</i> ") )
echo '</span>'
end
echo ( '</th></tr>' )
-- "Game"
echo('<tr><th colspan="2" class="ifwiki-infobox-center">Game</th></tr>')
-- Cover image
if cover then
echo('<tr><th colspan = "2">[[File:' .. cover .. '|class=ifwiki-infobox-image]]</th></tr>')
else
-- Not in IFWiki database so try IFDB
if coverUrlExternal and coverUrlExternal~='' then
echo('<tr><th colspan = "2">')
echo ( '<span class="plainlinks">[https://ifdb.org/viewgame?coverart&id=' .. TUID .. '&ldesc ' )
echo(frame:callParserFunction( '#widget', { 'cover', url = coverUrlExternal } ) )
echo ( ']</span>' )
echo('</th></tr>')
end
end
-- Links
if playOnline or primaryPlayOnlineUrlExternal or IFDB or IFArchive or CASA or download or sourceCode then
echo ('<tr><th>Main links</th><td>')
-- Display one Play online link, from our form field, or via IFDB, or via IF Archive
if playOnline then
echo ( '<span class="plainlinks">[' .. playOnline )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IFWiki \'Play online\' link">' )
echo ( 'Play online</span>]</span>' )
elseif download and parchmentPlayable(download) then
echo ( '<span class="plainlinks">[https://iplayif.com/?story=' .. download )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IFWIki \'Download\' link">' )
echo ( 'Play online</span>]</span>' )
elseif IFArchive and parchmentPlayable(IFArchive) then
echo ( '<span class="plainlinks">[https://iplayif.com/?story=' .. IFArchive )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IF Archive link">' )
echo ( 'Play online</span>]</span>' )
elseif primaryPlayOnlineUrlExternal then
echo ( '<span class="plainlinks">[' .. primaryPlayOnlineUrlExternal:gsub(' ', '%%20') )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IFDB link">' )
echo ( 'Play online</span>]</span>' )
end
-- Display one Download link, from our form field, or via IF Archive
if download then
echo ( '<span class="plainlinks">[' .. download )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IFWiki link">Download</span>]</span>' )
elseif IFArchive then
echo ( '<span class="plainlinks">[' )
echo ( IFArchiveUnbox or IFArchive or '' )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px" title="via IF Archive link">Download</span>]</span>' )
end
if sourceCode then
echo ( '<span class="plainlinks">[' .. sourceCode )
echo ( '<span class="mw-ui-button mw-ui-progressive" style="margin: 5px">Source code</span>]</span>' )
categorise( 'Games with source code available' )
end
if IFDB or IFArchive or CASA then
echo "<div>"
-- Display text links to IFDB, IF Archive, CASA
if IFDB then
for _,v in ipairs(IFDBTable) do
echo ('[' .. v .. ' IFDB] ')
end
end
if IFArchive then
echo '['
echo ( IFArchiveUnbox or IFArchive or '' )
echo ' IF Archive] '
end
if CASA then
echo ( '[' .. CASA .. ' CASA] ')
end
echo "</div>"
end
echo ('</td></tr>')
end
-- Published
if published or oldInfoboxDate or (firstPublishedExternal and firstPublishedExternal~='') then
echo('<tr><th>Published</th><td>')
end
if published then
local year=published:sub(1,4)
local month=published:sub(6,7)
local day=published:sub(9,10)
categorise( 'Works in ' .. year )
if year >='1970' and year <='1979' then
categorise ( 'Works in 1970s') -- existing category
end
-- Format is YYYY-MM-DD
if publishedPrecision=='3' then
-- Year only
echo(year)
elseif publishedPrecision=='2' then
-- Year and month only
published = os.date('%B %Y', os.time({year=year, month=month, day=day}) )
echo (published)
else
-- Full date
published = os.date('%d %B %Y', os.time({year=year, month=month, day=day}) )
if published:sub(1,1) == '0' then
published = published:sub(2) -- get rid of leading 0
end
echo(published)
end
if publishedUncertain=='1' then
echo(' (uncertain)' )
end
end
-- This is relevant if conversion script couldn't work out what to do with the old 'released' date
if oldInfoboxDate then
echo( ' (Old infobox stated: "' .. oldInfoboxDate .. '")' )
end
-- If date not on IFWiki database then try IFDB
if not published then
if firstPublishedExternal and firstPublishedExternal~='' then
if published or oldInfoboxDate then echo ('<br>') end
echo('IFDB: ' .. firstPublishedExternal .. '*')
usingExternal = true
end
end
if published or oldInfoboxDate or (firstPublishedExternal and firstPublishedExternal~='') then
echo('</td></tr>')
end
-- Credits
if #gamePerson >= 1 or #gameCompany >= 1 then
echo '<tr><th colspan="2" class="ifwiki-infobox-center">Credits</th></tr>'
end
function displayEntityRow(rolesTable, role, entityType)
--Couldn't think of a better word than entities for people + companies
--rolesTable is the table; role is a string for the left column
--entityType is 'Person' or 'Company'
entities = rolesTable[role]
if entities then
echo ("<tr><th>")
if #rolesTable[role] > 1 and plural[role] then
echo (plural[role])
else
echo (role)
end
echo ("</th><td>")
gf.displayEntities(entities, entityType)
echo "</td></tr>"
-- Some categorisation
for i, entity in ipairs(entities) do
if entity.Name == 'Infocom' then categorise( 'Infocom' ) end
end
if role == 'Translator' then categorise( 'Translated works (translations)' ) end
if role == 'Porter' then categorise( 'Ported works (ports)' ) end
if role == 'Author' and #entities > 1 then
categorise( 'Co-written works' )
end
end
end
-- People
rolesTable = arrangeIntoGroups(gamePerson, 'Role')
if rolesTable['Author'] ~= nil then
displayEntityRow(rolesTable, 'Author', 'Person')
else
if authorExternal then
-- No wiki data so try IFDB xxx
echo ("<tr><th>Author(s)</th><td>")
echo (authorExternal)
echo ("*</td></tr>")
usingExternal = true
end
end
if #gamePerson~=0 then
displayEntityRow(rolesTable, 'Porter', 'Person')
displayEntityRow(rolesTable, 'Translator', 'Person')
displayEntityRow(rolesTable, 'Musician', 'Person')
displayEntityRow(rolesTable, 'Artist', 'Person')
-- And the rest, in the order they appear
for r,v in pairs(rolesTable) do
if r~='Author' and r~='Translator' and r~='Porter' and r~='Musician' and r~='Artist' then
displayEntityRow(rolesTable, r, 'Person')
end
end
end
-- Companies
if #gameCompany~=0 then
rolesTable = arrangeIntoGroups(gameCompany, 'Role')
displayEntityRow(rolesTable, 'Development company', 'Company')
displayEntityRow(rolesTable, 'Publisher', 'Company')
--And the rest
for r,v in pairs(rolesTable) do
if r~='Development company' and r~='Publisher' then
displayEntityRow(rolesTable, r, 'Company')
end
end
end
--Reception
if #events~=0 or starRatingExternal then
echo '<tr><th colspan="2" class="ifwiki-infobox-center">Reception</th></tr>'
end
-- Events
if #events~=0 then
echo (cab.displayAwardBoxes(frame, game) )
end
if starRatingExternal then
echo('<tr><th>IFDB rating</th><td>' .. starRatingExternal)
if ratingCountTotExternal then
echo(' out of 5 (' .. ratingCountTotExternal )
if ratingCountTotExternal==1 then
echo(' rating)')
else
echo(' ratings)')
end
end
echo('</td></tr>')
end
function infoboxRow(field, fieldName, isLinked)
-- Display infobox row
-- So many special rules now maybe need separate functions
fieldTable = stringToTable(field)
if field then
echo "<tr><th>"
if #fieldTable>1 and plural[fieldName] then
printFieldName = plural[fieldName]
else
printFieldName = fieldName
end
if fieldName == 'Literary genre' then
echo ('[[IFWiki:Literary genres|' .. printFieldName .. ']]')
elseif fieldName == 'Location' then
echo ('[[IFWiki:Locations|' .. printFieldName .. ']]')
elseif fieldName == 'Interaction style' then
echo ('[[IFWiki:Interaction styles|' .. printFieldName .. ']]')
elseif fieldName == 'Cruelty scale' then
echo ('[[Cruelty scale|' .. printFieldName .. ']]')
else
echo (printFieldName)
end
echo "</th><td>"
if field == location then
-- Icons for location
if location and location~='' then
locationArray = mw.text.split(location, ',')
for s = 1, #locationArray do
locationArray[s] = mw.text.trim(locationArray[s])
categorise( locationArray[s] ) -- would be better to have "...games"
echo(frame:expandTemplate{ title='Game icon', args={ locationArray[s] } } )
end
end
elseif field == literaryGenre then
-- Icons for literary genre
if literaryGenre and literaryGenre~='' then
genreArray = mw.text.split(literaryGenre, ',')
for g = 1, #genreArray do
genreArray[g] = mw.text.trim(genreArray[g])
categorise( genreArray[g] )
echo(frame:expandTemplate{ title='Game icon', args={ genreArray[g] } } )
end
end
elseif field == interactionStyle then
-- Icons for interaction style
-- Parser, Choice, Parser-choice hybrid, Other
if interactionStyle and interactionStyle~='' then
interactionStyleArray = mw.text.split(interactionStyle, ',')
for s = 1, #interactionStyleArray do
interactionStyleArray[s] = mw.text.trim(interactionStyleArray[s])
categorise( interactionStyleArray[s] .. ' games')
echo(frame:expandTemplate{ title='Game icon', args={ interactionStyleArray[s] } } )
end
end
else
-- Just text for other fields
for i,v in ipairs (fieldTable) do
if i > 1 then echo ", " end
if fieldName=='Format' and v=='Z-code' and zCodeVersion then
echo ( zCodeVersion:gsub("%s*,%s*", "]], [["):gsub("^", "[["):gsub("$", "]]") )
elseif fieldName=='Format' and v=='Other' and fileFormatOther then
echo ('[[' .. fileFormatOther .. ']]')
elseif fieldName == 'IFID' then
-- Already will be IFDB link if the IFID is known there
-- Maybe should display this row separately
echo (IFIDTable[i])
elseif fieldName == 'Tag' then
echo ('<span class="plainlinks">[' .. mw.site.server .. '/Special:Drilldown/Games?Tag=' .. mw.uri.encode(v) .. ' ' .. v .. ']</span>')
elseif fieldName == 'Cruelty scale' then
echo ( '[[:Category:' .. v .. ' works|' .. v .. ']]' )
elseif isLinked then
echo ( '[[' .. v .. ']]')
else
echo (v)
end
end
end
echo "</td></tr>"
end
end
-- Gameplay
if interactionStyle or literaryGenre or location or tag or language or cruelty or playTimeInMinutesExternal or accessibility then
echo '<tr><th colspan="2" class="ifwiki-infobox-center">Gameplay</th></tr>'
infoboxRow(interactionStyle, 'Interaction style', true)
infoboxRow(literaryGenre, 'Literary genre', true)
infoboxRow(location, 'Location', true)
infoboxRow(tag, 'Tag', true)
infoboxRow(language, 'Language', true)
if language then
categorise( language:gsub("%s*,%s*", " works,") .. " works" )
end
infoboxRow(cruelty, 'Cruelty scale', true)
if cruelty then
categorise( cruelty .. ' works' )
end
if playTimeInMinutesExternal then
echo('<tr><th>IFDB play time</th><td>' .. displayTime(playTimeInMinutesExternal) .. '</td></tr>')
end
infoboxRow(accessibility, 'Accessibility', false)
end
-- Technical details
if authoringSystem or fileFormat or zCodeVersion or system or licence or IFID then
echo '<tr><th colspan="2" class="ifwiki-infobox-center">Technical details</th></tr>'
infoboxRow(authoringSystem, 'Authoring system', true)
infoboxRow(fileFormat, 'Format', true)
infoboxRow(system, 'System', true)
if licence then
local linked_licences = {
["Freeware"] = true,
["Commercial"] = true,
["Former commercial"] = true,
["Creative Commons"] = true,
["Shareware"] = true,
["GPL"] = true,
["Open Source IF"] = true
}
echo ( '<tr><th>[[Licence|License]]</th><td>' )
if linked_licences[licence] then
echo ( '[[' .. licence .. ']]' )
else
echo ( licence )
end
echo ( '</td></tr>' )
end
infoboxRow(IFID, 'IFID', false)
if licence=='Commercial' then
-- Maybe need to add other licences here
categorise( 'Commercial works' )
end
if authoringSystem then
categorise( authoringSystem:gsub("%s*,%s*", " works,") .. " works" )
end
if fileFormat then
categorise( fileFormat:gsub("%s*,%s*", " works,") .. " works" )
end
if fileFormatOther then
categorise( fileFormatOther:gsub("%s*,%s*", " works,") .. " works" )
end
if system then
categorise( system:gsub("%s*,%s*", " works,") .. " works" )
end
end
-- Encouragement to confirm IFDB data
if usingExternal then
echo '<tr><td colspan="2" style="text-align: center"><i>'
echo '* The asterisked content is taken directly from IFDB. If it is accurate, please edit this page and it to our database.'
echo '</i></td></tr>'
end
-- Final part of infobox
echo('<tr><td colspan="2" style="text-align: center"><i>[[Special:Drilldown/Games|Browse the games database]]')
echo(' • [[Special:FormEdit/Game/' .. game .. '|Edit this page]]</i></td></tr>')
-- End infobox
echo('</table>')
-- Main article content
if mainArticleContent and mainArticleContent~='' then
echo ( '\n' .. mainArticleContent)
end
-- Image gallery
-- Ideally move to Lua
echo( frame:expandTemplate{ title='Game image gallery' } )
-- "Versions" heading for releases
if release and release~='' then
echo ( '\n==Versions==\n' )
for i = 1, #releases do
if releases[i].Name then
echo ( '\n===' .. releases[i].Name .. '===\n')
else
echo ( '\n===Unnamed release===\n' )
end
echo ( "<p>'''Date:''' ")
if releases[i].Date then
echo ( dateFormat ( releases[i].Date, releases[i].Date__precision, releases[i].Uncertain ) )
else
echo ( 'Date unknown' )
end
echo ( ' </p>' )
if releases[i].Notes then
echo ('\n' .. releases[i].Notes)
end
end
end
-- "Related games" heading
if series or #gameCrossreference>0 or #gameCrossreferencedBy>0 then
echo '\n==Related games==\n'
end
-- Series
if series and series~='' then
echo('<ul><li>Part of "' .. series .. '": <ul>')
for _,g in ipairs(seriesGames) do
g = g['Game']
echo '<li>'
echo(frame:expandTemplate{ title='Game citation', args={ game=g } } )
echo '.</li>'
end
echo('</ul></li></ul>')
end
-- Crossreferenes from the game's form
if #gameCrossreference>0 then
relationshipsTable = arrangeIntoGroups(gameCrossreference, 'Relationship')
for relationship, crossreferences in pairs(relationshipsTable) do
echo '<ul><li>'
if #relationshipsTable[relationship] > 1 and plural[relationship] then
echo (plural[relationship])
else
echo (relationship)
end
multiple = #relationshipsTable[relationship] > 1
if relationship=='Port of' then
categorise ('Ported works (ports)')
end
if relationship=='Translation of' then
categorise ('Translated works (translations)')
end
if multiple then echo ' the following:<ul>' else echo ' ' end
for i, crossreference in ipairs(crossreferences) do
if crossreference.Game then
if multiple then echo '<li>' end
echo(frame:expandTemplate{ title='Game citation', args={ game=crossreference.Game } } )
echo '.'
if multiple then echo '</li>' end
else
echo "Unknown" -- shouldn't happen
end
end
if multiple then echo '</ul>' end
echo '</li></ul>'
end
end
-- Has this game been cross-referenced by any others?
-- Ideally would merge and order the two tables and deal with together
if #gameCrossreferencedBy>0 then
relationshipsTable = arrangeIntoGroups(gameCrossreferencedBy, 'Relationship')
for relationship, crossreferences in pairs(relationshipsTable) do
echo ("<ul><li>")
if relationship=='Port of' then echo 'Ported as'
elseif relationship=='Translation of' then echo 'Translated in'
elseif relationship=='Makes reference to' then echo 'Referred to in'
elseif relationship=='Prequel to' then echo 'Followed by sequel'
elseif relationship=='Sequel to' then echo 'Followed by prequel'
elseif relationship=='Adapted from' then echo 'Adapted as'
elseif relationship=='Remake of' then echo 'Remade as'
elseif relationship=='Inspired by' then echo 'Inspired'
elseif relationship=='Spoof of' then echo 'Spoofed by'
end
multiple = #relationshipsTable[relationship] > 1
if relationship=='Ported as' then
categorise ('Ported works (original)')
end
if relationship=='Translation of' then
categorise ('Translated works (original)')
end
if multiple then echo ' the following:<ul>' else echo ' ' end
for i, crossreference in ipairs(crossreferences) do
if crossreference.Original then
if multiple then echo '<li>' end
echo(frame:expandTemplate{ title='Game citation', args={ game=crossreference.Original } } )
echo '.'
if multiple then echo '</li>' end
else
echo "Unknown" -- shouldn't happen
end
end
if multiple then echo '</ul>' end
echo '</li></ul>'
end
end
-- Old series box (will remove when all game pages created)
if series and series~='' and mw.title.new(series, "Template").exists then
echo( frame:expandTemplate{ title=series } )
end
-- "Links" section
if externalLinks and externalLinks~='' then
echo ( '\n==Links==\n' )
-- Temporary warning message about OSA 2023 UK geofence
if IFArchive
or (download and download:find('ifarchive.org', 1, true))
or (playOnline and playOnline:find('ifarchive.org', 1, true))
or (primaryPlayOnlineUrlExternal and primaryPlayOnlineUrlExternal:find('ifarchive.org', 1, true))
then
echo ( '<i>N.B. Many IF Archive games are temporarily unavailable in the UK.</i>\n\n' )
end
echo ( externalLinks )
end
-- Adventure
if game:match(' %(%w%w%w%w%d%d%d%d%)$') or game:match(' %(%w%w%w%w_XXX%)$') then
echo "\n"
echo(frame:expandTemplate{ title='Adventure navbox' } )
end
-- Note about citation
echo '\n<div class="mw-message-box" style="margin-top: 1em; font-size: 0.85em; clear: both; background-color: inherit">'
echo '<p>Note: To refer to this game from another page, you can type '
echo ( '<code>{{game citation|' .. game .. '}}</code>. ' )
echo 'This will display as '
echo(frame:expandTemplate{ title='Game citation', args={ game=game } } )
echo '.</div>'
-- Final categorisation
categorise( 'Works' )
for _, category in ipairs(categories) do
echo ('[[Category:' .. category .. ']]')
end
output = table.concat(output)
return output
end
return p