Module:ObbyGameInfobox
From Obby Wiki
More actions
This module is heavily used across the Obby Wiki
This module automatically collects and sorts the majority of pages on this wiki, a breaking change could damage the functionality of the wiki largely. Be careful when making edits.
Please refer to any documentation for the Obby Infobox template at: https://obbywiki.com/wiki/Template:ObbyGameInfobox.
This infobox uses InfoboxNeue, which is likely imported, view more information at: https://obbywiki.com/wiki/Module:InfoboxNeue.
--[=[
DO NOT EDIT THIS FILE MANUALLY.
This file was automatically minified and transpiled from Luau by DarkLua.
The original source code was written in Luau, the below code is transpiled and compatible with Lua 5.1.5 and contains the necessary polyfills.
Uploaded automatically via WikiWire. View the original source at our central code repository: https://github.com/obbywiki/modules
ANY EDITS WILL LIKELY BE OVERWRITTEN. A copyright notice should be supplied at the bottom of this page.
]=]--
local ObbyGameInfobox={}local i18n=require('Module:i18n2').new('ObbyGameInfobox')local months_full={'January','February','March','April','May','June','July','August','September','October','November','December'}local function month_by_index(month)local monthnum=tonumber(month)if not monthnum then return i18n:get('label_na','N/A')end return months_full[monthnum]or i18n:get('label_na','N/A')end local function get_comma_val(num)local formatted=num while true do local k formatted,k=string.gsub(formatted,'^(-?%d+)(%d%d%d)','%1,%2')if(k==0)then break end end return formatted end local function page_exists(page_title)local title=mw.title.new(page_title)return title and title.exists end local smm={twitter={icon='External Twitter Coloured Small.webp',url='https://twitter.com/',display='Twitter'},bsky={icon='External BlueSky White Small.png',url='https://bsky.app/profile/',display='BlueSky'},youtube={icon='External YouTube White Small.png',url='https://youtube.com/@',display='YouTube'},discord={icon='External Discord White Small.png',url='https://discord.com/invite/',display='Discord'},guilded={icon='External Guilded White Small.png',url='https://guilded.gg/',display='Guilded'},roblox={icon='External Roblox White Small.png',url='https://roblox.com/users/profile?username=',display='Roblox'},website={icon='GoogleMaterialIcons-Globe.svg',url='https://',display='Website'},wiki={icon='External MediaWiki White Small.png',url='https://',display='MediaWiki'}}local obby_schema={_table='Obbies',_drilldownTabs='Tab1(format=list;delimiter=;;fields=creator)',root_place_id='String',universe_id='String',name='String',thumbnail='String',creator='String',developers='List (,) of String',contributors='List (,) of String',publisher='String',stages='Integer',tier='Integer',visits='Float',likes='Float',dislikes='Float',favorites='Float',playability='String',is_public='Boolean',avatar_type='String',subgenre='String',year='Integer',month='Integer',day='Integer'}function ObbyGameInfobox.declare(frame)local declare_args={}table.insert(declare_args,'_table='..obby_schema._table)for k,v in pairs(obby_schema)do if k~='_table'and k~='_drilldownTabs'then table.insert(declare_args,k..'='..v)end end return frame:callParserFunction{name='#cargo_declare',args=declare_args}end function ObbyGameInfobox.store(frame,data,debug_mode)local store_args={}table.insert(store_args,'_table='..obby_schema._table)for k,v in pairs(data)do if v~=nil and v~=''then table.insert(store_args,k..'='..tostring(v))end end mw.logObject(store_args,'ObbyGameInfobox Store Args')local cargo_store_res=frame:callParserFunction{name='#cargo_store',args=store_args}local debug_output=''if debug_mode then debug_output=[[<div class="obby-debug-storage" style="border: 1px solid #ccc; padding: 10px; margin: 10px 0; background-color: #f9f9f9;">]]debug_output=debug_output..[[<strong>[ObbyGameInfobox Debug] Cargo Store Args:</strong><pre>]]..mw.text.nowiki(mw.text.jsonEncode(store_args))..'</pre>'if cargo_store_res and cargo_store_res~=''then debug_output=debug_output..[[<div style="color: red;"><strong>Cargo Store Result/Error:</strong> ]]..cargo_store_res..'</div>'else debug_output=debug_output..[[<div style="color: green;"><strong>Cargo Store Status:</strong> Success (Empty Result)</div>]]end debug_output=debug_output..'</div>'return cargo_store_res,debug_output end return cargo_store_res,''end function ObbyGameInfobox.main(frame)local InfoboxNeue=require('Module:InfoboxNeue')local test=InfoboxNeue:new({placeholderImage='Standard169placeholder.webp'})local args=require('Module:Arguments').getArgs(frame)local absolute_title=mw.title.getCurrentTitle()local obby_name=args.name or'{{PAGENAME}}'local obby_starter_place_id=args.root_place_id or args.start_place_id or 1818 local obby_join_sharelink_id=args.play or args.sharelink or args.play_sharelink or''local obby_subgenre=args.subgenre or args.sub_genre or args.type or'N/A'local obby_maturity=args.maturity or args.rating or'na'local obby_genai=args.ai_generated_content_disclosure or args.genai or args.ai local obby_ai_generated_content_disclosure=(obby_genai=='branding'or obby_genai=='thumbnails'or obby_genai=='icon'or obby_genai=='identity')and'branding'or obby_genai=='stated_none'and'stated_none'or obby_genai=='description'and'description'or'unknown'local obby_is_public=(args.is_public=='true'or args.is_public=='yes')and true or(args.is_public=='false'or args.is_public=='no')and false if tonumber(obby_starter_place_id)==nil then return[[ObbyGameInfobox rendering was skipped due to an invalid start place ID.]]end if args.is_public==nil then obby_is_public=true end local obby_subgenre_lower=string.lower(obby_subgenre)obby_subgenre_lower=string.gsub(obby_subgenre_lower,' ','')obby_subgenre_lower=string.gsub(obby_subgenre_lower,'-','')obby_subgenre_lower=string.gsub(obby_subgenre_lower,'_','')local obby_verified_status=(args.verified=='true'or args.verified=='full')and'verified'or args.verified=='false'and'unstable'or args.verified=='broken'and'broken'or(args.verified=='broken2'or args.verified=='does_not_load')and'does_not_load'or'unknown'local subgenre_map={['dco']='subgenre_dco',['jpdco']='subgenre_jpdco',['njpdco']='subgenre_njpdco',['wpdco']='subgenre_wpdco',['wdco']='subgenre_wdco',['njdco']='subgenre_njdco',['sopdco']='subgenre_sopdco',['pdco']='subgenre_pdco',['st']='subgenre_stage_tower',['stagetowerobby']='subgenre_stage_tower',['towerstageobby']='subgenre_stage_tower',['stage_tower_obby']='subgenre_stage_tower',['t']='subgenre_tower',['towerobby']='subgenre_tower',['tower_obby']='subgenre_tower',['so']='subgenre_story',['storyobby']='subgenre_story',['difficultychartobby']='subgenre_dco',['trollobby']='subgenre_troll',['gimmickobby']='subgenre_gimmick',['nojumpperdifficultychartobby']='subgenre_njpdco',['wraparounddifficultychartobby']='subgenre_wdco',['wraparoundperdifficultychartobby']='subgenre_wpdco',['coopobby']='subgenre_coop',['2playerobby']='subgenre_coop',['tierobby']='subgenre_tier',['tier']='subgenre_tier',['multiplayer']='subgenre_multiplayer',['4playerobby']='subgenre_multiplayer',['obby']='subgenre_classic',['classic']='subgenre_classic',['classicobby']='subgenre_classic',['timetrial']='subgenre_time_trial',['tt']='subgenre_time_trial',['roundbased']='subgenre_round_based',['roundbasedobby']='subgenre_round_based'}local subgenre_key=subgenre_map[obby_subgenre_lower]if subgenre_key then obby_subgenre=i18n:get(subgenre_key)else obby_subgenre=i18n:get('subgenre_unsupported')end local maturity_map={['minimal']='maturity_minimal',['mild']='maturity_mild',['mature']='maturity_mature',['restricted']='maturity_restricted',['unrated']='maturity_unrated',['none']='maturity_unrated'}local maturity_lower=string.lower(obby_maturity)local maturity_key=maturity_map[maturity_lower]if maturity_key then obby_maturity=i18n:get(maturity_key)else obby_maturity=i18n:get('maturity_unknown')end local obby_developer,obby_developer_was_corrected=args.developer or args.creator or'Unknown',false local obby_developer_raw=obby_developer local obby_developer_canonical local obby_publisher=args.publisher or'Self-Published'local obby_system=args.system or args.obby_system or'NA'local obby_creation_year=args.year or''local obby_creation_month=month_by_index(args.month and tonumber(args.month)or 0)local obby_creation_day=args.day or''local obby_stats_visits=args.visits or'N/A'local obby_stats_visits_raw local obby_stats_peak_ccu=args.peak_ccu or'N/A'local obby_stats_likes=args.likes or 0 local obby_stats_dislikes=args.dislikes or 0 local obby_stats_favorites if tonumber(obby_stats_visits)~=nil then obby_stats_visits=get_comma_val(args.visits)end if tonumber(obby_stats_peak_ccu)~=nil then if obby_stats_peak_ccu=='0'then obby_stats_peak_ccu='N/A'else obby_stats_peak_ccu=get_comma_val(args.peak_ccu)end end if tonumber(obby_stats_likes)~=nil then obby_stats_likes=tonumber(obby_stats_likes)else obby_stats_likes=0 end if tonumber(obby_stats_dislikes)~=nil then obby_stats_dislikes=tonumber(args.dislikes)or 0 else obby_stats_dislikes=0 end local obby_levels=args.levels or args.stages or'N/A'local obby_obbies=args.obbies or args.maps or'N/A'local obby_levels_total=args.levels_total or args.stages_total or nil local obby_difficulties=args.difficulties or''local obby_difficulties_total=args.difficulties_total or nil local obby_towers=args.towers or''local obby_towers_total=args.towers_total or nil local obby_avatar_type=args.avatar_type or args.rig_type or'N/A'obby_avatar_type=string.lower(obby_avatar_type)local avatar_map={['r6']='avatar_r6',['r15']='avatar_r15',['rthro']='avatar_rthro',['choice']='avatar_choice'}local avatar_key=avatar_map[obby_avatar_type]if avatar_key then obby_avatar_type=i18n:get(avatar_key)else obby_avatar_type=i18n:get('avatar_unknown')end local obby_tier=args.tier or'0'local thumb=args.image or args.thumbnail or args.thumb local s,res=pcall(function()return mw.ext.externalData.getExternalData{url='https://edge.obbywiki.com/v1/get-obby/'..obby_starter_place_id,format='json'}end)local obby_wiki_edge_res=res and res.__json local universe_id,thumbs local last_updated=''local data_last_fetched=''local use_external_thumbs=false local obby_stats_favorites_raw=obby_stats_favorites if obby_wiki_edge_res then universe_id=obby_wiki_edge_res.universe_id if obby_wiki_edge_res.thumbnails and#obby_wiki_edge_res.thumbnails>0 then thumbs=obby_wiki_edge_res.thumbnails use_external_thumbs=true end if obby_wiki_edge_res.up_votes and obby_wiki_edge_res.down_votes then obby_stats_likes=obby_wiki_edge_res.up_votes or 0 obby_stats_dislikes=obby_wiki_edge_res.down_votes or 0 end if obby_wiki_edge_res.info then if obby_wiki_edge_res.info.creator then local c=obby_wiki_edge_res.info.creator local base=(c.creator_type=='Group')and'communities'or'users'obby_developer_raw=obby_developer local source_creator_name=c.name if not source_creator_name or source_creator_name==''then source_creator_name=args.developer or args.creator or'Unknown'end if page_exists(c.creator_type=='Group'and source_creator_name or'@'..source_creator_name)then obby_developer='[['..(c.creator_type=='Group'and source_creator_name or'@'..source_creator_name)..']]'..(c.is_verified and[==[ [[File:Roblox_Verification_Badge.svg|12px|alt=Verified|link=]==]..obby_developer_raw..']]'or'')else obby_developer=string.format('[https://roblox.com/%s/%s/%s %s%s]',base,c.id,base=='communities'and(string.gsub(source_creator_name,' ','_')..'#!/about')or'profile',(c.creator_type=='User'and'@'or'')..source_creator_name,(c.is_verified and[=[ [[File:Roblox_Verification_Badge.svg|12px|alt=Verified|link=]]]=])or'')obby_developer_was_corrected=true end obby_developer_canonical=c.creator_type=='User'and'@'..source_creator_name or source_creator_name end obby_stats_visits=obby_wiki_edge_res.info.visits or obby_stats_visits obby_stats_favorites=obby_wiki_edge_res.info.favorites or'N/A'if obby_wiki_edge_res.info.visits and tonumber(obby_stats_visits)~=nil then obby_stats_visits_raw=tonumber(obby_stats_visits)obby_stats_visits=get_comma_val(obby_stats_visits)end if obby_wiki_edge_res.info.favorites and tonumber(obby_stats_favorites)~=nil then obby_stats_favorites=get_comma_val(obby_stats_favorites)obby_stats_favorites_raw=obby_wiki_edge_res.info.favorites end if obby_wiki_edge_res.info.updated then last_updated=obby_wiki_edge_res.info.updated end if obby_wiki_edge_res.info.created and(not obby_creation_day or obby_creation_day=='')then obby_creation_day=obby_wiki_edge_res.info.created and type(obby_wiki_edge_res.info.created)=='string'and obby_wiki_edge_res.info.created~=''and obby_wiki_edge_res.info.created:sub(9,10)end if obby_wiki_edge_res.info.avatar_type then if obby_wiki_edge_res.info.avatar_type=='MorphToR6'then obby_avatar_type='R6'elseif obby_wiki_edge_res.info.avatar_type=='MorphToR15'then obby_avatar_type='R15'end end end data_last_fetched=obby_wiki_edge_res.fetched_at or os.date('%Y-%m-%d %H:%M:%S')end if use_external_thumbs and thumbs and#thumbs>0 and args.disable_auto_thumb~='false'then if#thumbs==1 then if thumb then test:renderImage(thumb)end else if thumb then test:renderInvisibleImage(thumb)end test:renderCarousel(thumbs)end else if thumb and thumb~=''then test:renderImage(thumb)else test:renderImage('Standard169placeholder.webp')end end local obby_status_key=args.unreleased=='true'and'status_unreleased'or obby_is_public and'status_public'or'status_private'local obby_status=i18n:get(obby_status_key)local obby_status_raw=args.unreleased=='true'and'Unreleased'or obby_is_public and'Public'or'Private'test:renderIndicator({data=obby_status,color=obby_status_raw=='Unreleased'and'gray'or obby_status_raw=='Public'and'green'or'red',tooltip=(obby_is_public and i18n:get('tooltip_public')or i18n:get('tooltip_private'))})test:renderHeader({title='[https://roblox.com/games/'..obby_starter_place_id..'/ '..obby_name..']',subtitle=(obby_developer_was_corrected and(i18n:get('label_by').." '''"..obby_developer.."'''")or(i18n:get('label_by').." '''"..obby_developer.."'''"))..(obby_creation_year~=''and(' — '..obby_creation_year)or'')})local function format_with_total(value,total)if total and value then return value..' <small>('..i18n:format('of_total',total)..')</small>'end return value or''end local use_stages=false if obby_levels~='N/A'then use_stages=true end test:renderSection({title=i18n:get('section_gameplay'),col=2,content={(obby_levels~='N/A'or obby_obbies~='N/A')and test:renderItem(use_stages and i18n:get('field_checkpoints')or i18n:get('field_obbies'),use_stages and format_with_total(obby_levels,obby_levels_total)or obby_obbies)or'',test:renderItem(i18n:get('field_difficulties'),format_with_total(obby_difficulties,obby_difficulties_total)),test:renderItem(i18n:get('field_towers'),format_with_total(obby_towers,obby_towers_total)),test:renderItem(i18n:get('field_tier'),'[[Tiers|'..(obby_tier=='0'and'0 - Unrated/Unknown'or obby_tier)..']]'),test:renderItem(i18n:get('field_avatar_type'),obby_avatar_type)}})test:renderSection({title=i18n:get('section_statistics'),col=2,content={test:renderItem(i18n:get('field_visits'),obby_stats_visits..'+'..[[ <ref name="statistics_data">The Obby Wiki automatically sources live statistics directly from Roblox's database. See [https://roblox.com/games/]]..obby_starter_place_id..[[/ {{PAGENAME}} on Roblox] for more information. Statistics last retrieved at: ]]..data_last_fetched..' UTC.</ref>'),test:renderItem(i18n:get('field_peak_ccu'),'{{#simple-tooltip: '..(obby_stats_peak_ccu..'+')..' | '..i18n:get('tooltip_peak_ccu')..' }}'),test:renderItem(i18n:get('field_rating'),(obby_stats_likes+obby_stats_dislikes)>0 and(math.floor((obby_stats_likes/(obby_stats_likes+obby_stats_dislikes))*1000)/10)..'% ( [[File:Likes.svg|12px|alt=Likes|link=]] '..get_comma_val(tostring(obby_stats_likes))..' [[File:Dislikes.svg|12px|alt=Dislikes|link=]] '..get_comma_val(tostring(obby_stats_dislikes))..')'or i18n:get('label_na')),test:renderItem(i18n:get('field_favorites'),(obby_stats_favorites or'N/A')..'+ <ref name="statistics_data" />')}})local ai_disclosure_map={['branding']='ai_branding',['stated_none']='ai_stated_none',['description']='ai_description'}local ai_disclosure_key=ai_disclosure_map[obby_ai_generated_content_disclosure]local ai_disclosure_text=ai_disclosure_key and i18n:get(ai_disclosure_key)or i18n:get('ai_unknown')local last_updated_year=last_updated:sub(1,4)local last_updated_month=month_by_index(tonumber(last_updated:sub(6,7)or 1))local full_my=obby_creation_month..' '..obby_creation_year test:renderSection({title=i18n:get('section_publishing'),col=2,content={test:renderItem(i18n:get('field_released'),'[[:Category:'..full_my..'|'..full_my..']]'),test:renderItem(i18n:get('field_latest_update'),last_updated_month..' '..last_updated_year),test:renderItem(i18n:get('field_publisher'),obby_publisher),test:renderItem(i18n:get('field_maturity'),obby_maturity),test:renderItem(i18n:get('field_genre'),'[[Obby|'..i18n:get('genre_obby')..']]'),test:renderItem(i18n:get('field_sub_genre'),page_exists(obby_subgenre)and'[['..obby_subgenre..']]'or obby_subgenre),obby_system~='NA'and test:renderItem(i18n:get('field_obby_system'),obby_system)or'',test:renderItem(i18n:get('field_ai_content'),ai_disclosure_text)}})local social_icons_wikitext={}local platform_icons_wikitext={}for i,v in pairs(smm)do if args[i]then local handle=args[i]local full_url=v.url..handle local wikitext=string.format([=[[%s [[File:%s|24px|link=|alt=%s|class=social-icon %s-social-icon]]]]=],full_url,v.icon,v.display..' icon',string.lower(v.display))table.insert(social_icons_wikitext,wikitext)end end for _,i in pairs({'pc','tablet','phone','console','vr'})do if args[i]then local wikitext=string.format('[[File:%s|24px|alt=%s|class=platform-icon|link=]]',(i=='pc'and'Platform Computer White Small.png'or i=='tablet'and'Platform Tablet White Small.png'or i=='phone'and'Platform Phone White Small.png'or i=='console'and'Platform Console White Small.png'or i=='vr'and'Platform VR White Small.png'or''),i)table.insert(platform_icons_wikitext,wikitext)end end if#social_icons_wikitext>0 or#platform_icons_wikitext>0 then test:renderSection({title=i18n:get('section_presence'),content={test:renderItem({label=i18n:get('field_socials'),plainlinks_enabled=true,data=table.concat(social_icons_wikitext,' ')}),test:renderItem({label=i18n:get('field_platforms'),plainlinks_enabled=true,data=table.concat(platform_icons_wikitext,' ')})}})end local verified_info_map={['verified']='verified_verified',['unstable']='verified_unstable',['broken']='verified_broken',['does_not_load']='verified_does_not_load'}local verified_info_key=verified_info_map[obby_verified_status]or'verified_unknown'local verified_info_text=i18n:get(verified_info_key)test:renderSection({title=i18n:get('section_playability'),col=2,content={test:renderItem({label=i18n:get('field_status'),plainlinks_enabled=true,data=obby_verified_status=='verified'and[=[[[File:Verified-check-green-96.webp|36px|alt=Verified|link=]]]=]or(obby_verified_status=='unstable'or obby_verified_status=='broken'or obby_verified_status=='does_not_load')and'[[File:Verified-dash-red-72.webp|36px|alt=Unstable|link=]]'or obby_verified_status=='unknown'and[=[[[File:Verified-dash-orange-72.webp|36px|alt=Unknown|link=]]]=]}),test:renderItem({label=i18n:get('field_info'),data=verified_info_text})}})test:renderSection({title=i18n:get('section_technical'),col=2,content={test:renderItem(i18n:get('field_start_place_id'),'<code>'..(obby_starter_place_id==1818 and i18n:get('label_unlisted')or tostring(obby_starter_place_id)or i18n:get('label_na'))..'</code>'),test:renderItem(i18n:get('field_universe_id'),'<code>'..(tostring(universe_id)or i18n:get('label_na'))..'</code>')}})test:renderFooter({button={icon='GoogleMaterialIcons-Globe.svg',icon_alt='Web',label=i18n:get('section_external_links'),type='popup',content=test:renderSection({content={test:renderItem({label=i18n:get('link_roblox'),data=table.concat({test:renderLinkButton({label=i18n:get('link_view_roblox'),link='https://www.roblox.com/games/'..obby_starter_place_id..'/'}),test:renderLinkButton({label=i18n:get('link_play_roblox'),link=(obby_join_sharelink_id~=''and'https://www.roblox.com/join/'..obby_join_sharelink_id)or'https://www.roblox.com/start?placeId='..obby_starter_place_id..'&launchData=obbywiki'})},'')}),test:renderItem({label=i18n:get('link_analytics'),data=table.concat({test:renderLinkButton({label=i18n:get('link_romonitorstats'),link='https://romonitorstats.com/experience/'..obby_starter_place_id..'/'}),test:renderLinkButton({label=i18n:get('link_rolimons'),link='https://rolimons.com/game/'..obby_starter_place_id..'/'})},'')}),class='infobox__section--linkButtons'}},true)}})local rendered=test:renderInfobox(nil,'[https://roblox.com/games/'..obby_starter_place_id..'/ '..obby_name..']')local parsed_month=obby_creation_month local append_categories={}if tonumber(obby_creation_year)>=2008 and tonumber(obby_creation_year)<=os.date('*t').year+2 then table.insert(append_categories,'[[Category:'..tostring(obby_creation_year)..']]')if parsed_month~='N/A'then table.insert(append_categories,'[[Category:'..parsed_month..' '..tostring(obby_creation_year)..']]')end end if parsed_month~='N/A'then table.insert(append_categories,'[[Category:'..parsed_month..']]')end if obby_subgenre then table.insert(append_categories,'[[Category:'..obby_subgenre..']]')end if not obby_stats_visits_raw then obby_stats_visits_raw=0 end if obby_stats_visits_raw<5000 then table.insert(append_categories,'[[Category:'..'0-5%2C000_visits'..']]')elseif obby_stats_visits_raw<25000 then table.insert(append_categories,'[[Category:'..'5%2C000-25%2C000_visits'..']]')elseif obby_stats_visits_raw<50000 then table.insert(append_categories,'[[Category:'..'25%2C000-50%2C000_visits'..']]')elseif obby_stats_visits_raw<100000 then table.insert(append_categories,'[[Category:'..'50%2C000-100%2C000_visits'..']]')elseif obby_stats_visits_raw<500000 then table.insert(append_categories,'[[Category:'..'100%2C000-500%2C000_visits'..']]')elseif obby_stats_visits_raw<1000000 then table.insert(append_categories,'[[Category:'..'500%2C000-1%2C000%2C000_visits'..']]')else table.insert(append_categories,'[[Category:'..'Above_1%2C000%2C000_visits'..']]')end table.insert(append_categories,'[[Category:'..'Obby'..']]')local shortdesc='{{SHORTDESC:'..(obby_subgenre..' by '..(obby_developer_canonical or obby_developer_raw or'Unknown')..' - '..obby_creation_year)..'}}'local cargo_store_res,cargo_debug_res='',''if absolute_title and absolute_title.namespace==10 then append_categories={}else if universe_id~=nil and universe_id~=0 then cargo_store_res,cargo_debug_res=ObbyGameInfobox.store(frame,{root_place_id=tostring(args.root_place_id),universe_id=tostring(universe_id),name=args.name or mw.title.getCurrentTitle().text,thumbnail=thumb,publisher=obby_publisher~='Self-Published'and obby_publisher or nil,creator=obby_developer_canonical or obby_developer_raw,stages=tonumber(args.stages)or nil,tier=tonumber(args.tier)or 0,visits=obby_stats_visits_raw,likes=obby_stats_likes,dislikes=obby_stats_dislikes,favorites=tonumber(obby_stats_favorites_raw)or 0,subgenre=obby_subgenre,year=tonumber(obby_creation_year)or nil,month=tonumber(args.month)or nil,day=tonumber(obby_creation_day)or nil,is_public=obby_is_public,avatar_type=obby_avatar_type=='R6'and'R6'or obby_avatar_type=='R15'and'R15'or obby_avatar_type=='Rthro'and'Rthro'or obby_avatar_type=='Choice'and'Choice'or nil,developers=args.developers,contributors=args.contributors,playability=verified_info_key},args.debug=='true'or args.debug==true)end end local game_url='https://roblox.com/games/'..obby_starter_place_id..'/'local page_url=mw.title.getCurrentTitle():fullUrl('','https')local seo_obby_name=obby_name seo_obby_name=string.gsub(seo_obby_name,''',"'")seo_obby_name=string.gsub(seo_obby_name,'"','"')seo_obby_name=string.gsub(seo_obby_name,'&','&')local seo_description=seo_obby_name..' is a '..obby_subgenre..' developed by '..(obby_developer_canonical or obby_developer_raw or'an unknown developer')..' on Roblox and released in '..obby_creation_month..' of '..obby_creation_year if obby_tier and obby_tier~='0'then seo_description=seo_description..'. '..seo_obby_name..' is currently rated at a tier '..obby_tier..' in difficulty'end if obby_stats_visits then seo_description=seo_description..'. The game has been played over '..obby_stats_visits..' times'end if obby_stats_favorites then seo_description=seo_description..', favorited by over '..obby_stats_favorites..' users'end if obby_stats_likes then seo_description=seo_description..', liked by over '..obby_stats_likes..' users'end if obby_stats_dislikes then seo_description=seo_description..', and disliked by over '..obby_stats_dislikes..' users'end seo_description=seo_description..'. Read more on the Obby Wiki.'local json_ld={['@type']='VideoGame',name=args.name or mw.title.getCurrentTitle().text,url=page_url,description=seo_description,gamePlatform='Roblox',genre='Obby',applicationCategory='Game',operatingSystem='Cross-platform'}if thumb and thumb~=''then json_ld.image='https://obbywiki.com/wiki/Special:FilePath/'..mw.uri.encode(thumb,'PATH')elseif use_external_thumbs and thumbs and#thumbs>0 then json_ld.image=thumbs[1]end if obby_developer_canonical or obby_developer_raw then json_ld.author={['@type']=(string.sub(obby_developer_canonical or obby_developer_raw,1,1)=='@'and'Person'or'Organization'),name=obby_developer_canonical or obby_developer_raw}end if obby_publisher and obby_publisher~='Self-Published'then json_ld.publisher={['@type']='Organization',name=obby_publisher}end if tonumber(obby_creation_year)then local date_str=tostring(obby_creation_year)if tonumber(args.month)then date_str=date_str..'-'..string.format('%02d',tonumber(args.month))if tonumber(obby_creation_day)then date_str=date_str..'-'..string.format('%02d',tonumber(obby_creation_day))end end json_ld.datePublished=date_str end local total_votes=obby_stats_likes+obby_stats_dislikes if total_votes>0 then local pct=obby_stats_likes/total_votes json_ld.aggregateRating={['@type']='AggregateRating',ratingValue=tostring(math.floor(pct*50+0.5)/10),bestRating='5',worstRating='0',ratingCount=tostring(total_votes)}end if obby_levels and obby_levels~='N/A'and tonumber(obby_levels)then json_ld.numberOfLevels=tonumber(obby_levels)end local same_as={game_url}for key,v in pairs(smm)do if args[key]and(args[key]=='website')then table.insert(same_as,v.url..args[key])end end if#same_as>0 then json_ld.sameAs=same_as[1]end local game_platforms={}if args.pc then table.insert(game_platforms,'PC')end if args.tablet then table.insert(game_platforms,'Tablet')end if args.phone then table.insert(game_platforms,'Mobile')end if args.console then table.insert(game_platforms,'Console')end if args.vr then table.insert(game_platforms,'VR')end if#game_platforms>0 then end mw.ext.jsonld.setMainEntity(json_ld)mw.ext.jsonld.addData({image=json_ld.image})local seo_image=thumb if not seo_image or seo_image==''then seo_image=(use_external_thumbs and thumbs and#thumbs>0)and thumbs[1]or nil end local seo_date_published if tonumber(obby_creation_year)then seo_date_published=tostring(obby_creation_year)if tonumber(args.month)then seo_date_published=seo_date_published..'-'..string.format('%02d',tonumber(args.month))if tonumber(obby_creation_day)then seo_date_published=seo_date_published..'-'..string.format('%02d',tonumber(obby_creation_day))end end end local seo_keywords_parts={'obby',obby_subgenre,(obby_developer_canonical or obby_developer_raw or''),'roblox'}local seo_keywords=table.concat(seo_keywords_parts,', ')mw.ext.seo.set{type='VideoGame',description=seo_description,keywords=seo_keywords,image=seo_image,published_time=seo_date_published,author=obby_developer_canonical or obby_developer_raw or'Unknown',locale='en_US',site_name='Obby Wiki'}return frame:preprocess(shortdesc)..rendered..(cargo_debug_res or'')..(cargo_store_res or'')..'\n'..table.concat(append_categories,'\n')end return ObbyGameInfobox