Gamertag


quarta-feira, 4 de novembro de 2026

A Biblioteca #4 — a parte que cresce

O problema não é a biblioteca crescer. É que ela cresce num lugar diferente de onde é organizada — e a distância entre os dois é onde a bagunça se instala.

O que o post 3 não resolveu

O hash resolveu o passado. Mil e seiscentos e seis jogos cortados em oitenta e um blocos, cada um com o seu post, cada um com a sua amostra aleatória.

Mas ele é uma fotografia. E fotografia envelhece no dia seguinte.

Porque a biblioteca não parou. A Epic entrega de quatro a cinco jogos toda quinta. O Prime entrega vinte a trinta por mês. E a promoção que eu não consigo ignorar entra por cima disso.

Se eu não fizer nada, em um ano são quatrocentos ou quinhentos jogos novos — e a planilha que eu levei três posts para organizar volta a ser um depósito.

A tentação de decidir na entrada

A primeira solução que eu considerei foi criar um portão: o jogo entra, fica trinta dias em observação, e depois vira fila, descarte ou arquivo.

Parece organizado. É errado.

Porque A Biblioteca não é sobre jogar. É sobre catalogar — saber o que eu tenho, onde tenho, de que gênero, se tem conquista, o que já joguei e o que ficou no meio. E decidir o destino de um jogo olhando um pedaço dele é exatamente o oposto de catalogar.

Um portão de decisão na entrada resolve o problema de quem quer jogar. O meu problema é de quem quer saber.

Então o jogo novo entra no acervo. Ponto. Sem estado provisório, sem prazo, sem cobrança.

O que realmente apodrece

O problema não é o volume. É a despadronização.

Se os jogos novos entram sem gênero, sem conquista, com loja errada, em seis meses eu tenho dois acervos: um completo e um pela metade. E o segundo contamina qualquer filtro, porque uma consulta por gênero passa a mentir sem avisar.

A solução não é decidir o destino do jogo. É garantir que a linha dele esteja pronta.

Cinco colunas obrigatórias: título, plataforma, loja, gênero, conquistas. Enquanto faltar uma, a linha fica marcada como incompleta e aparece na lista de pendências. Não é uma decisão sobre o jogo — é uma decisão sobre o dado.

O lugar certo já existia

Aqui está a parte que eu demorei para ver.

Eu já escrevo um post semanal de domingo sobre o que estou jogando. Ele já existe, já tem rotina, já tem pauta. Enfiar a catalogação dentro dele não cria compromisso nenhum — só aproveita um que já estava de pé.

Então o semanal ganha uma segunda parte: o que entrou na biblioteca esta semana. Cinco ou seis jogos, na maioria das vezes. Um parágrafo, não uma lista.

E é ali que eles são catalogados. Na semana em que entraram, dentro de um texto que eu ia escrever de qualquer jeito.

Não criei um sistema novo. Descobri que o post de domingo já era o lugar certo — só faltava um script para não deixar passar nada.

Como o script funciona

Vale explicar o mecanismo, porque ele é a única coisa aqui que eu vou querer reler daqui a dois anos.

A ideia central é simples: o script não sabe o que é um jogo novo. Ele sabe o que já viu antes.

Na primeira execução, ele lê a planilha inteira e grava num arquivo de estado a chave de cada jogo. Na segunda, ele lê de novo e compara: o que está na planilha e não está no estado é novo. O que já está no estado é velho, e ele ignora.

É o mesmo princípio de um backup incremental. Não é preciso saber a data de nada — basta lembrar o que já passou.

A chave é o hash, não o título

O script não compara títulos. Compara o MD5 do título normalizado — a mesma função do post 3.

Isso importa por um motivo prático: "Fallout: London" e "Fallout London" são o mesmo jogo, mas como texto são strings diferentes. Se a comparação fosse por título, o script reportaria o mesmo jogo duas vezes em semanas diferentes, e eu iria catalogar de novo o que já estava catalogado.

Com o hash da versão normalizada — sem acento, sem pontuação, sem artigo no começo — as duas formas produzem a mesma chave. O script reconhece que é o mesmo jogo e não repete.

O estado é um arquivo, não uma coluna

Poderia guardar essa informação numa coluna da planilha. Optei por um arquivo separado, o estado_semana.json.

A razão é que a planilha é minha e o estado é do script. Se eu mexer na planilha, apagar linha, reordenar, corrigir um título — o estado continua intacto, porque ele não depende da estrutura da planilha. Ele só guarda uma lista de hashes.

E se eu quiser recomeçar do zero, apago o arquivo. A próxima execução vai considerar tudo novo, o que é o comportamento certo para uma reinstalação.

O que ele devolve

Três arquivos, cada um com uma função.

O novos_da_semana.csv é a matéria-prima do post de domingo: título, plataforma, loja, gênero, conquista, e a marcação de catalogado ou pendente.

O catalogacao_pendente.csv é a lista de trabalho. Só os jogos que entraram e ainda têm coluna obrigatória vazia, com a indicação exata de qual coluna falta.

E o terminal imprime um resumo: quantos entraram, quantos estão completos, a distribuição por loja e os gêneros que apareceram. É esse resumo que eu leio antes de escrever o domingo, porque ele já me diz sobre o que vale falar.

Por que ele roda no sábado

Não é preferência. É ordem de operação.

Se rodasse no domingo, eu estaria catalogando e escrevendo ao mesmo tempo, e a catalogação viraria a parte chata do post. Rodando no sábado, eu tenho a lista pronta, sei o que falta preencher, e chego no domingo só com a escrita.

É a mesma lógica de separar a coleta da redação em qualquer processo de escrita. Quem junta as duas coisas faz as duas mal.

O script

import csv, re, sys, json, unicodedata, hashlib
from pathlib import Path
from datetime import date, datetime

ESTADO   = "estado_semana.json"
SAIDA    = "novos_da_semana.csv"
PENDENTE = "catalogacao_pendente.csv"

ARTIGOS = {"the","a","an","o","os","as","um","uma"}
MAPA_PLAT = {"steam":"Steam","gog":"GOG","epic":"Epic","amazon":"Amazon",
             "ea":"EA","uplay":"Uplay","windows":"Windows"}
OBRIGATORIAS = ["Titulo","Plataforma","Loja","Genero","TemConquistas"]

def normalizar(t):
    t = unicodedata.normalize("NFKD", (t or "").lower())
    t = "".join(c for c in t if not unicodedata.combining(c))
    t = re.sub(r"\s*[\(\[]\s*[^\)\]]*\s*[\)\]]", " ", t)
    t = re.sub(r"[^a-z0-9 ]", " ", t)
    p = [x for x in t.split() if x]
    while p and p[0] in ARTIGOS:
        p.pop(0)
    return " ".join(p)

def chave(titulo):
    return hashlib.md5(normalizar(titulo).encode("utf-8")).hexdigest()

def corrigir_loja(l):
    loja = (l.get("Loja") or "").strip()
    plat = (l.get("Plataforma") or "").strip()
    if loja.lower() in ("", "local", "windows") and plat:
        return MAPA_PLAT.get(plat.lower(), loja or plat)
    return loja or plat

def faltando(l):
    return ";".join(c for c in OBRIGATORIAS if not (l.get(c) or "").strip())

def main():
    if len(sys.argv) < 2:
        print("Uso: python novos_da_semana.py biblioteca.csv [--post N]")
        return

    post = None
    if "--post" in sys.argv:
        i = sys.argv.index("--post")
        if i + 1 < len(sys.argv):
            post = int(sys.argv[i + 1])

    bruto = Path(sys.argv[1]).read_text(encoding="utf-8-sig", errors="ignore")
    primeira = bruto.split("\n", 1)[0]
    delim = ";" if primeira.count(";") >= primeira.count(",") else ","
    linhas = list(csv.DictReader(bruto.splitlines(), delimiter=delim))

    estado = {"vistos": [], "ultimo_post": 0}
    if Path(ESTADO).exists():
        estado = json.loads(Path(ESTADO).read_text(encoding="utf-8"))
    vistos = set(estado["vistos"])

    if post is None:
        post = estado.get("ultimo_post", 0) + 1

    novos = []
    for l in linhas:
        k = chave(l.get("Titulo"))
        if not k or k in vistos:
            continue
        l["Chave"] = k
        l["Loja"] = corrigir_loja(l)
        l["OrigemAcervo"] = "fluxo"
        l["PostEntrada"] = post
        l["DataEntrada"] = date.today().isoformat()
        l["Faltando"] = faltando(l)
        l["Catalogado"] = "nao" if l["Faltando"] else "sim"
        novos.append(l)

    if not novos:
        print("Nenhum jogo novo desde a ultima execucao.")
        return

    campos = ["Titulo","Plataforma","Loja","Genero","TemConquistas",
              "DataLancamento","Desenvolvedor","Chave","PostEntrada",
              "DataEntrada","Catalogado","Faltando"]
    with open(SAIDA, "w", newline="", encoding="utf-8-sig") as fh:
        w = csv.DictWriter(fh, fieldnames=campos, delimiter=";",
                           extrasaction="ignore")
        w.writeheader()
        w.writerows(novos)

    pend = [l for l in novos if l["Catalogado"] == "nao"]
    with open(PENDENTE, "w", newline="", encoding="utf-8-sig") as fh:
        w = csv.writer(fh, delimiter=";")
        w.writerow(["Titulo","Loja","Faltando"])
        for l in pend:
            w.writerow([l["Titulo"], l["Loja"], l["Faltando"]])

    estado["vistos"] = sorted(vistos | {l["Chave"] for l in novos})
    estado["ultimo_post"] = post
    Path(ESTADO).write_text(json.dumps(estado, ensure_ascii=False, indent=2),
                            encoding="utf-8")

    from collections import Counter
    print("Jornada Gamer Semanal #{}".format(post))
    print("Novos .............", len(novos))
    print("Catalogados .......", len(novos) - len(pend))
    print("Pendentes .........", len(pend))
    print()
    for k, v in Counter(l["Loja"] for l in novos).most_common():
        print("  {:<12} {}".format(k, v))
    print()
    for l in pend[:10]:
        print("  {:<34} {}".format(l["Titulo"][:34], l["Faltando"]))

if __name__ == "__main__":
    main()

O que acontece quando ele roda errado

Três falhas possíveis, e vale saber o que cada uma significa antes de acontecer.

A primeira é o estado apagado ou perdido. Se o estado_semana.json sumir, a próxima execução considera os mil e seiscentos jogos como novos. O script não quebra — ele simplesmente reporta tudo. A saída é não publicar nada naquele domingo e reconstruir o estado rodando uma vez com a planilha completa antes de qualquer jogo novo entrar.

A segunda é o título alterado na planilha. Se eu corrigir o nome de um jogo que já foi catalogado, o hash muda e o script passa a vê-lo como novo. Ele vai aparecer de novo no post. Não é grave, mas é o tipo de coisa que eu preciso reconhecer na hora em que acontecer, em vez de achar que o script está errado.

A terceira é a planilha exportada incompleta. Se o LaunchBox exportar antes de terminar de carregar, o CSV vem truncado e o script reporta menos jogos do que entraram. A conferência é simples: o total de linhas do CSV tem que bater com o total de jogos do LaunchBox. Se não bater, o export falhou.

O dado que me incomodou

Tem uma coisa que só apareceu quando eu montei isso.

O acervo de fluxo é mais bem documentado que o da fotografia.

Os jogos novos vêm com data de entrada, loja corrigida, post de origem, gênero vindo da API. Os mil e seiscentos antigos têm gênero em 43% das linhas e data de aquisição em quase nenhuma.

Ou seja: o fluxo não é o problema do acervo. Ele é o modelo do que o acervo deveria ter sido desde o começo.

O que chega agora é catalogado melhor do que o que eu passei quinze anos acumulando. A parte que cresce virou o padrão da parte que já estava aqui.

Isso muda o que a série precisa fazer daqui para frente. Não é só seguir os blocos de hash — é usar o fluxo como régua, e ir corrigindo o acervo antigo na medida em que os blocos o trazem de volta.

A biblioteca não dobra de tamanho. Ela ganha uma segunda camada, e a segunda camada é a que está certa.

terça-feira, 3 de novembro de 2026

A Biblioteca #3 — o hash, a fila e o problema de uma biblioteca que não para de crescer

No post anterior eu terminei prometendo o texto sobre duplicatas. Sentei para escrever e travei na terceira linha, por um motivo que vou registrar aqui porque é o problema inteiro deste projeto resumido em uma frase: eu não consigo comparar a versão da Steam com a versão da Epic se eu não souber antes onde cada uma delas mora.

Onde a série estava

O post 1 resolveu a posse: o CSV saiu do LaunchBox, cada linha sabendo de onde veio. O post 2 resolveu o uso: a Steam devolve horas, as outras cinco não devolvem nada, e essa assimetria virou a tese da série.

Ficaram pendentes quatro colunas vazias. Duas eu resolvi. E foi ao atacar a terceira — GrupoDuplicata — que tudo parou.

Porque a pergunta "qual das três versões de Batman é a boa" pressupõe que as três estejam na mesma página. E para estarem na mesma página, elas precisam estar no mesmo corte. O corte vem antes de tudo. Não é organização prévia, é condição de existência do problema seguinte.

Por que não por loja, e por que a intuição estava certa

A primeira ideia que eu tive foi a mais óbvia: dividir por loja. Um post por loja, por mês, algo assim.

Aí eu olhei os números reais da planilha.

Origem Jogos Como chegaram
Epic549Resgate semanal gratuito
GOG408Prime Gaming e resgates
Steam320Compra, na maioria
Amazon277Assinatura Prime
Windows (sem loja identificada)74A resolver pelo caminho
EA10Resgate
Uplay11Resgate
Total1.606

Dividir por loja significa vinte e sete posts seguidos sobre jogos da Epic. Vinte e sete textos onde a única coisa em comum entre os jogos é o fato de terem sido resgatados de graça, na mesma plataforma, por motivos que não têm nada a ver uns com os outros.

A loja não é uma categoria do jogo. É uma categoria da sua relação com o jogo, e ela é a mais pobre de todas — porque foi decidida por um algoritmo de desconto, não por você.

A loja não diz nada sobre o jogo. Só diz por onde ele entrou em você.

Por que o alfabético também não serve

A segunda ideia foi a ordem alfabética, e eu gostei dela por um motivo honesto: parecia aleatória.

Não é. Ordenar por título agrupa exatamente o que eu queria evitar.

Todas as franquias caem juntas. Todos os Call of Duty, todos os Need for Speed, todos os Batman. E depois de remover os artigos — The, A, An, O, Os, As — ainda sobra outro agrupamento: as franquias com prefixo numérico e as séries que compartilham a primeira palavra. O alfabeto é um agrupador silencioso, e ele é pior que a loja porque é menos óbvio.

Um bloco alfabético de vinte jogos não é uma amostra da biblioteca. É um recorte de uma prateleira.

E por que não por data

A ordem cronológica seria a melhor de todas, e é a única que eu não tenho.

A data de aquisição não está no CSV, porque o LaunchBox nunca foi usado como launcher — ele foi usado como verificador de compra. Os jogos entraram nele quando eu abri a promoção, não quando eu comprei o jogo. A data que existe é a data em que eu catalogou, e ela não serve para nada neste problema.

Seria possível reconstruir isso da Steam pela API e do GOG pelo banco local. Mas 549 jogos da Epic continuariam sem data, e um corte que cobre dois terços da biblioteca é pior que um corte que cobre tudo.

Eu queria cortar por biografia. Tive que cortar por matemática.

O hash

A solução é calcular o MD5 do título normalizado de cada jogo e ordenar por esse valor.

Normalizar significa: minúsculas, sem acentos, sem pontuação, sem parênteses, sem artigos no começo. O MD5 é a mesma função que eu usei no post do RetroAchievements — aquela que decide se o seu arquivo existe ou não —, só que aplicada a texto em vez de bytes.

E o resultado é o que eu queria desde o começo: uma ordem que não significa nada. Nenhum agrupamento por franquia, por loja, por gênero, por época. Cada bloco de vinte vira uma amostra verdadeiramente aleatória da biblioteca.

Tem uma coisa nisso que me agrada mais do que devia. A mesma função que decidiu, em outubro, se o meu arquivo existia para o RetroAchievements agora decide em que post cada jogo vai cair. Não foi escolha estética — foi a ferramenta que resolveu, duas vezes, problemas que pareciam sem solução.

O hash não sabe qual jogo é bom. Ele sabe que dois arquivos diferentes são coisas diferentes. Numa biblioteca de mil e seiscentos, isso é a única coisa que eu preciso que ele saiba.

O efeito colateral que virou o método

Quando eu vi o primeiro bloco pronto, entendi que o hash não resolveu apenas o corte. Ele criou um mecanismo de descoberta.

Uma recomendação de algoritmo faz uma coisa específica: ela te devolve mais do que você já gosta. A Steam olha o que você jogou e sugere parecido. O resultado é convergência — você afunila, joga mais do mesmo, e a biblioteca fica cada vez mais homogênea em uso.

O hash faz o oposto. Ele te devolve o que você esqueceu. Não o que você gosta hoje — o que você quis no passado. Um jogo que você resgatou em 2019 porque achou interessante na época, quando você era uma pessoa ligeiramente diferente, e que nunca abriu.

E é por isso que ele serve para achar pérola: porque pérola não é um jogo bom. É um jogo que você quis e abandonou antes de começar.

Juntando os dois lados: um bloco de vinte jogos aleatórios tem, estatisticamente, de três a cinco jogos que você não lembra de ter. Em oitenta blocos, isso são duzentos e cinquenta jogos que voltam a existir. Nenhuma loja vai te recomendar esses, porque eles não geram receita. Só um inventário encontra o que não vende mais.

O problema que eu tinha deixado para depois: a biblioteca é viva

Aqui está a parte que qualquer sistema de organização de biblioteca ignora e que me obrigou a repensar o desenho inteiro.

Se eu cortar 1.606 jogos em 80 blocos hoje, em janeiro o número não será mais 1.606. A Epic dá de quatro a cinco jogos grátis por semana. O Prime entrega entre vinte e trinta por mês. E toda promoção boa demais para ignorar — como a de Halloween, sete itens por trinta e dois reais — coloca mais coisa dentro.

Isso significa talvez quatrocentos ou quinhentos jogos novos por ano. Vinte a vinte e cinco blocos a mais, só de crescimento.

Se os blocos fossem recalculados toda vez, todos os posts já escritos ficariam errados. Se os jogos novos fossem jogados para o bloco que o hash deles indica, eles cairiam em blocos já publicados, e eu teria que emendar posts do passado.

Nenhuma das duas funciona. A saída é separar em duas coisas que não são a mesma.

Congelar o acervo, abrir a cauda

Os 1.606 jogos que existem hoje — ou melhor, no dia 26 de outubro de 2026 — são o acervo. Eles recebem os blocos de 1 a 81 e esses números não mudam nunca mais. É arqueologia: a biblioteca como ela era, fotografada num dia.

Tudo que chegar depois entra na cauda, e os blocos da cauda começam no 82 e sobem. Não é ordem alfabética nem hash — é ordem de chegada. É diário.

E aqui está a parte que eu não esperava e que faz o projeto inteiro valer a pena: a série muda de natureza sozinha.

Os primeiros oitenta e um blocos são sobre quem eu fui — a biblioteca acumulada em quinze anos de resgate automático. Do octogésimo segundo em diante, cada bloco é sobre o que acabou de acontecer comigo naquela semana. É o mesmo formato, mas o tempo muda de direção.

Os sete itens da promoção de Halloween já nasceram na cauda. O post que eu escrevi sobre eles não é o post 3 nem o 4 — é o primeiro registro da cauda, escrito antes de eu saber que a cauda existia.

Os primeiros oitenta blocos olham para trás. Depois deles, a série começa a olhar para o lado.

A Fila, que não é uma aba

Sobre a ideia de separar em abas — jogos com conquista numa, sem conquista na outra — eu mudei de opinião, e o motivo é mecânico.

Aba é amputação. Filtro é lente.

No momento em que eu movo 900 jogos para uma aba "sem conquistas", eu perco a única coisa que este projeto tem de mais valioso: a comparação entre o que é mensurável e o que não é. A assimetria entre as lojas — que é a tese do post 2 — deixa de ser visível quando eu separo. Separar é aceitar que são duas coisas diferentes, e o ponto é justamente que são a mesma biblioteca com tratamentos desiguais.

Tem também o problema braçal: cada vez que um status de conquista muda, o jogo precisa mudar de aba. Manual, em 1.606 linhas, é erro garantido.

O que eu vou fazer é o inverso. Uma planilha mestra, editada só por mim, e duas abas geradas por script a partir dela. Elas não são digitadas — são calculadas. Se der errado, eu apago e rodo de novo.

A primeira é a Fila: os candidatos a virar o jogo da semana. Entram só os que têm conquista disponível, estão parados ou nunca abertos, e não foram marcados como "nunca". A ordenação é por custo de fechar — quanto mais perto do fim, mais alto. Isso é diminuição de backlog com o menor esforço possível, que é o único tipo de backlog que se resolve na vida adulta.

A segunda é a Pérolas: vinte jogos por mês, sorteados por hash sobre o acervo, filtrados por "nunca aberto e você quis jogar". Roda todo mês e nunca repete o mesmo conjunto. É a minha resposta à pergunta de como achar pérola em 1.606 jogos: não procurando. Amostrando, todo mês, para sempre.

O script

Três coisas ele faz: calcula o hash, distribui os blocos com o congelamento, e escreve a planilha com as duas abas derivadas.

import csv, re, hashlib, unicodedata, sys
from datetime import datetime

ARQ_ENTRADA = "biblioteca_launchbox_2026-10-26.csv"
ARQ_MESTRE  = "biblioteca_mestra.csv"
ARQ_XLSX    = "biblioteca.xlsx"

DATA_CORTE = datetime(2026, 10, 26).date()
TAM_BLOCO  = 20

ARTIGOS = {"the","a","an","o","os","as","um","uma",
           "le","la","les","el","los","der","die","das"}

def normalizar(t):
    t = unicodedata.normalize("NFKD", (t or "").lower())
    t = "".join(c for c in t if not unicodedata.combining(c))
    t = re.sub(r"[™®©]", " ", t)
    t = re.sub(r"\s*[\(\[].*?[\)\]]", " ", t)
    t = re.sub(r"[^a-z0-9 ]", " ", t)
    p = [x for x in t.split() if x]
    while p and p[0] in ARTIGOS:
        p.pop(0)
    return " ".join(p)

def chave(titulo):
    return hashlib.md5(normalizar(titulo).encode("utf-8")).hexdigest()

def data_entrada(linha):
    for campo in ("DataEntrada", "DataAquisicao", "Added", "DateAdded"):
        v = (linha.get(campo) or "").strip()
        if not v:
            continue
        for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%Y-%m-%dT%H:%M:%S"):
            try:
                return datetime.strptime(v[:19], fmt).date()
            except ValueError:
                pass
    return None

def numero(v):
    try:
        return float(str(v).replace("%", "").replace(",", "."))
    except (TypeError, ValueError):
        return None

with open(ARQ_ENTRADA, encoding="utf-8-sig") as fh:
    linhas = list(csv.DictReader(fh, delimiter=";"))

if not linhas:
    sys.exit("CSV vazio ou separador errado.")

for l in linhas:
    l["_data"]  = data_entrada(l)
    l["_chave"] = chave(l.get("Titulo"))
    l.setdefault("Status", "")
    l.setdefault("TemConquistas", "")
    l.setdefault("PctConquistas", "")
    l.setdefault("Intencao", "")

# acervo = fotografado hoje | cauda = chegou depois
acervo = [l for l in linhas if l["_data"] is None or l["_data"] <= DATA_CORTE]
cauda  = [l for l in linhas if l["_data"] is not None and l["_data"] > DATA_CORTE]

# hash, com desempate deterministico para variantes do mesmo jogo
ORDEM = lambda l: (l["_chave"], (l.get("Loja") or ""), (l.get("Titulo") or ""))
acervo.sort(key=ORDEM)
cauda.sort(key=ORDEM)

def numerar(grupo, inicio):
    for i, l in enumerate(grupo):
        l["Bloco"] = str(inicio + i // TAM_BLOCO)

numerar(acervo, 1)
ultimo = 1 + (len(acervo) - 1) // TAM_BLOCO if acervo else 0
numerar(cauda, ultimo + 1)

# ---------- aba Fila: candidatos ao jogo da semana ----------
fila = []
for l in acervo + cauda:
    if (l.get("TemConquistas") or "").strip().lower() != "sim":
        continue
    st = (l.get("Status") or "").strip().lower()
    if st not in ("nunca aberto", "parado"):
        continue
    if (l.get("Intencao") or "").strip().lower() == "nunca":
        continue
    pct = numero(l.get("PctConquistas")) or 0.0
    l["CustoFechar"] = round(100 - pct, 1) if st == "parado" else 150.0
    fila.append(l)

fila.sort(key=lambda l: (l["CustoFechar"], int(l["Bloco"])))

# ---------- aba Perolas: 20 por mes, rotativas ----------
MES = datetime.now().strftime("%Y-%m")
perolas = [
    l for l in acervo
    if (l.get("Status") or "").strip().lower() == "nunca aberto"
    and (l.get("Intencao") or "").strip().lower() in ("", "jogar", "talvez")
    and ((l.get("TemConquistas") or "").strip().lower() == "sim"
         or (l.get("Genero") or "").strip())
]
perolas.sort(key=lambda l: chave(l.get("Titulo") + MES))
perolas = perolas[:20]

# ---------- grava ----------
campos = [c for c in linhas[0].keys() if not c.startswith("_")]
if "Bloco" not in campos:
    campos.append("Bloco")
if "CustoFechar" not in campos:
    campos.append("CustoFechar")

with open(ARQ_MESTRE, "w", newline="", encoding="utf-8-sig") as fh:
    w = csv.DictWriter(fh, fieldnames=campos, delimiter=";", extrasaction="ignore")
    w.writeheader()
    w.writerows(linhas)

try:
    from openpyxl import Workbook
    from openpyxl.utils import get_column_letter
except ImportError:
    print("openpyxl ausente: pip install openpyxl")
    print("CSV mestre gravado em", ARQ_MESTRE)
    raise SystemExit

wb = Workbook()
ws = wb.active
ws.title = "Mestra"

def escrever(aba, dados, colunas):
    aba.append(colunas)
    for l in dados:
        aba.append([l.get(c, "") for c in colunas])
    for i, c in enumerate(colunas, start=1):
        aba.column_dimensions[get_column_letter(i)].width = max(12, min(38, len(c) + 6))
    aba.freeze_panes = "A2"
    aba.auto_filter.ref = aba.dimensions

escrever(ws, acervo + cauda, campos)

colunas_fila = ["Bloco", "Titulo", "Plataforma", "Loja", "Status",
                "PctConquistas", "CustoFechar", "TempoJogado"]
escrever(wb.create_sheet("Fila"), fila, colunas_fila)

colunas_perolas = ["Bloco", "Titulo", "Plataforma", "Loja", "Genero", "Intencao"]
escrever(wb.create_sheet("Perolas"), perolas, colunas_perolas)

wb.save(ARQ_XLSX)

print("acervo ......", len(acervo))
print("cauda .......", len(cauda))
print("blocos ......", ultimo, "de acervo +", ultimo + (len(cauda) - 1) // TAM_BLOCO if cauda else 0)
print("fila ........", len(fila))
print("perolas .....", len(perolas), "(" + MES + ")")
print("gravado .....", ARQ_XLSX)

Três detalhes do código que existem por um motivo específico.

O desempate (chave, loja, titulo) não é preciosismo. Como eu removo parênteses na normalização, "Batman: Arkham Asylum (GOTY)" e "Batman Arkham Asylum" geram o mesmo hash. Sem desempate, a ordem entre eles varia a cada execução e os blocos mudam sem nada mudar. Com desempate, a ordem é fixa.

E isso tem uma consequência boa para o próximo post: variantes do mesmo jogo caem no mesmo bloco, automaticamente. A normalização que eu fiz para ordenar acabou virando o detector de duplicata. O corte e a duplicata, que pareciam problemas separados, se resolvem com a mesma função.

O segundo detalhe é o l["_data"]: se o CSV não tiver data de aquisição, tudo é acervo e a cauda nasce vazia. É o comportamento certo — nenhuma data significa biblioteca toda anterior. E a partir do primeiro jogo novo que você adicionar com data, a cauda começa a funcionar sozinha.

O terceiro é que a Fila e as Pérolas não são digitadas em nenhum momento. Elas são reconstruídas a cada execução. Errou na mestra, consertou, rodou de novo. Nenhum dado derivado sobrevive à execução seguinte, e é assim que tem que ser.

O que isso muda na escrita

Uma coisa que eu não previ e que vale registrar antes de fechar.

Eu passei três posts tentando organizar a biblioteca para poder escrever sobre ela. O que o hash fez foi tirar de mim a decisão do que vem primeiro — e é uma decisão que eu estava tomando mal, porque eu ia sempre escolher os jogos que eu lembro, que são os jogos que eu gosto, que são os jogos que já tiveram espaço aqui.

Um sistema que eu controlo só me dá o que eu já sei. Um sistema que eu não controlo me dá o que eu esqueci.

E é por isso que eu escolhi o hash e não uma planilha ordenada por preferência. Não é sobre eficiência. É sobre permitir que o acervo fale primeiro.

Uma biblioteca organizada por preferência só repete o que eu já penso. Uma biblioteca organizada por acaso pode me surpreender — e é a única coisa que uma coleção de mil e seiscentos jogos tem a oferecer que quatro jogos bem escolhidos não teriam.

segunda-feira, 2 de novembro de 2026

A fartura me ensinou a não jogar

Em 2008 eu tinha quinhentos jogos numa pasta e jogava trinta minutos de cada. Hoje eu tenho um aberto e fico nele até o fim. A diferença não foi disciplina, não foi maturidade e não foi tempo. Foi escassez — e ela veio de um lugar em que eu nunca teria procurado.

Antes, o videogame era descanso e companhia

Até 2019 — ou 2021, nunca consegui datar isso com precisão — o videogame cumpria duas funções na minha vida, e nenhuma delas era desafio.

A primeira era descanso mental. Não era o lugar onde eu ia me superar. Era o lugar onde eu ia parar de pensar.

A segunda era multiplayer, no sentido literal e no sentido doméstico: eu sentava com a minha filha e a gente jogava. O jogo era o pretexto. O que estava acontecendo ali era outra coisa, e eu só fui entender depois.

Nesse arranjo, nenhum jogo precisava ser bom por muito tempo. Precisava ser bom o suficiente para uma tarde. Era um critério baixo, e ele funcionava.

O multiplayer não cessou. Ele mudou de lugar.

Quando o casamento entrou numa crise de afastamento, o multiplayer não acabou de uma vez. Ele apenas ficou mais raro — e no espaço que sobrou, todo o tempo em que eu estava sozinho passou a ir para o Diablo 3.

Eu passei muito tempo achando que era o Diablo 3. Que eu tinha encontrado um jogo que combinava comigo, um gênero que me pegava, alguma coisa assim.

Não era.

O que a temporada entregava

O Diablo 3 tinha uma coisa que, vista de fora, parece pequena: a jornada de temporada.

Ela acontecia. Me entregava um prêmio cosmético. Se encerrava. E começava de novo.

Quatro etapas, sempre na mesma ordem, com um fim visível desde o começo. Eu sabia exatamente onde estava dentro dela e quanto faltava para o próximo degrau. Não havia ambiguidade nenhuma.

A temporada não me dava um jogo melhor. Ela me dava um ciclo completo — com começo, meio, fim e recomeço.

E é aqui que eu preciso ser honesto sobre uma coisa que só entendi anos depois: não era o jogo certo. Era o jogo certo, com a dificuldade certa, com a recompensa certa, no momento certo.

Uma congruência de coisas que não se repete por decisão. Ela se repete por acidente.

Onde o ciclo quebrou

O que veio depois entregou menos, cada um a seu modo.

Jogo O que ele me dá
Diablo 3 Um ciclo fechado. Começa, entrega, encerra, recomeça.
Diablo Immortal Recompensa a carteira, não o tempo. O ciclo existe, mas ele mede outra coisa.
Diablo 2 e o remake Não recompensa. Pune. A recompensa dele é a ausência de punição.
Diablo 4 Não fecha o ciclo. E sobre esse eu não preciso escrever, porque todo mundo já viu.

O caso do Diablo 2 é o mais interessante dos quatro, e é o que eu demorei mais para aceitar.

Porque ele não é um jogo pior. Ele é um jogo que te cobra antes de te dar qualquer coisa, e que só te dá de volta o direito de continuar. Você não sobe. Você deixa de cair.

Isso é uma gramática completamente diferente da que eu tinha aprendido a gostar — e a distância entre as duas não se resolve com boa vontade.

Depois que a casa ficou vazia

Aí eu já não morava mais com a minha família.

Sem o multiplayer doméstico, e sem a temporada que se fechava sozinha, eu fiquei sem os dois eixos ao mesmo tempo. Sobrou o single player e o multiplayer online — e nenhum dos dois me dava um lugar para onde ir.

Foi quando o sistema de conquistas apareceu, e ele apareceu fazendo uma coisa bem específica: entregando a primeira camada do que eu tinha perdido.

Não o jogo certo. Não a companhia. Só o ciclo.

E foi o suficiente para me devolver um direcionamento.

A segunda vez que eu tive fartura

Tem uma parte dessa história que eu não tinha ligado até agora, e ela é a que mais me incomoda.

Cinco anos resgatando jogo grátis na Epic e na Amazon, comprando na Steam. A biblioteca virou um monstro de mais de mil e seiscentos títulos.

E ela é a mesma coisa que eu tive no Nintendo Wii.

Naquela época, o que importava era ter tudo o que eu pudesse colocar num HD. Eu baixava, acumulava, e ia jogando dali. Chegou a um ponto em que eu tinha um set com duzentos mil jogos — Super Nintendo, Nintendinho, Atari — e quinhentos jogos baixados de verdade.

A oferta era tão grande que eu pulava de jogo em jogo. Na hora em que um começava a me exigir um pouco de esforço, eu ia para outro, porque tinha muita novidade esperando e eu não ia ficar ali rodando o mesmo pedaço.

Não era falta de paciência. Era concorrência. Eu não abandonava o jogo porque era difícil — eu abandonava porque tinha outro.

O que o hash mudou

O RetroAchievements fez uma coisa que nenhuma loja fez comigo em quinze anos: ele cobrou uma decisão antes do primeiro minuto.

Antes de jogar, eu preciso resolver qual jogo é. E o jogo pode ter ou não um setlist de conquistas. Qual é a experiência certa? Qual é a ROM certa? Qual é o hash certo?

Isso dá trabalho. Não é muito — não quero exagerar o tamanho disso. Mas é um trabalho que eu faço escolhendo.

E aí a oferta encolhe. Não porque os jogos desapareceram, mas porque agora existe um portão entre a lista e a partida.

É engraçado que a solução para a fartura tenha sido atrito. Eu passei anos tentando me convencer a ter foco com disciplina, e nunca funcionou. O que funcionou foi colocar um obstáculo na entrada.

O segundo gancho veio junto, e ele é o que fecha o ciclo. O RetroAchievements me dá duas coisas distintas: o beaten, que é terminar o jogo, e o complete, que é fazer todas as conquistas dele.

Terminar e completar. Duas réguas, e a distinção entre as duas importa mais do que parece.

Dois jogos, não duzentos

Hoje eu estou jogando dois jogos: um de corrida e um Final Fantasy.

Na época em que esses jogos apareceram, eu jogava esses dois e mais duzentos, ao mesmo tempo, sem foco nenhum, alternando conforme a dificuldade subia e a paciência descia.

E aqui eu preciso reconhecer uma coisa que enfraquece meu próprio argumento: o RPG e o de corrida não são os melhores exemplos de conquista externa. Os dois têm progressão interna própria — subir de level, desbloquear carro, desbloquear pista. Eles se sustentariam sozinhos.

Mas mesmo assim a experiência de agora é superior à de 2008. E eu passei um tempo pensando por quê.

A resposta não está no jogo. Está no fato de que, agora, eu estou dedicando. Um de cada vez, com um fim visível, sem quinhentos outros esperando na pasta.

Eu não jogo melhor porque escolhi melhor. Eu jogo melhor porque a escolha custou alguma coisa.

É uma conclusão desconfortável para quem passou a vida juntando jogo.

Eu construí uma biblioteca enorme justamente para nunca mais precisar de nada. E o que me devolveu o prazer de jogar foi exatamente o contrário: precisar de algo, escolher esse algo, e ficar.

A fartura me ensinou a não jogar. Foi a escassez que me ensinou de novo — e ela não veio de disciplina, veio de um hash de ROM e de uma lista de conquistas que me obrigam a responder, antes de começar, o que eu quero jogar.

domingo, 1 de novembro de 2026

Jornada Gamer Semanal #3 — Entre jogos infinitos, velhos conhecidos e a vontade de terminar alguma coisa

Introdução — Uma semana sem novidades, mas não sem histórias

Cheguei à terceira semana desta nova proposta de acompanhar minha Jornada Gamer de forma semanal e percebi que, desta vez, não havia exatamente uma grande novidade para apresentar. Nenhum jogo novo entrou na minha rotina. Não comecei uma aventura completamente diferente, não descobri um título desconhecido e também não aconteceu nenhuma mudança extraordinária naquilo que venho jogando.

Basicamente, continuei algumas das experiências que já estavam presentes nas semanas anteriores.

Mas isso não significa que tenha sido uma semana sem importância.

Na verdade, uma das coisas que começo a perceber com essa nova série é justamente como a rotina de um jogador não precisa ser construída apenas por estreias, encerramentos ou grandes acontecimentos. Existem semanas em que simplesmente continuamos aquilo que estávamos fazendo. Voltamos aos mesmos jogos, avançamos um pouco em determinada campanha, repetimos algumas fases e utilizamos outras experiências apenas para descansar a cabeça.

E talvez seja exatamente esse tipo de semana que melhor represente uma parte considerável da minha vida com os videogames.

Nem sempre estou procurando uma novidade. Nem sempre quero começar alguma coisa. Às vezes, quero apenas abrir um jogo que conheço, continuar de onde parei e me divertir durante algum tempo.

Foi uma semana assim.

Entre macacos estourando balões, cidades sendo construídas, palavras cruzadas, frutas se combinando, uma aventura antiga de RPG e dois jogos do Nintendo Wii, continuei minha jornada sem grandes alterações.

Entretanto, enquanto organizava tudo aquilo que joguei, comecei a pensar em uma mudança que talvez aconteça na próxima semana.

Talvez esteja chegando a hora de voltar a terminar alguns jogos.

Nem toda semana precisa apresentar um jogo novo. Às vezes, a história está justamente naquilo que continuamos escolhendo jogar.

Capítulo 1 — Bloons TD 6: um jogo que parece não ter fim

Começo novamente por Bloons TD 6.

Esse é um daqueles jogos que parecem ter sido construídos para nunca realmente terminar. Sempre existe uma nova fase, uma nova dificuldade, um desafio diferente ou alguma coisa que ainda não foi completada.

Continuo avançando aos poucos, jogando novas fases e desbloqueando dificuldades conforme vou progredindo.

Também continuo tentando os desafios, que acabam oferecendo uma maneira diferente de aproveitar as mecânicas do jogo.

O interessante é perceber que, apesar de já ter dedicado bastante tempo a Bloons TD 6, ainda sinto que tenho muitas horas pela frente.

Estou avançando pelas fases na dificuldade média, repetindo mapas em dificuldades diferentes e experimentando maneiras de superar cada situação.

Mas existe uma particularidade curiosa nesse processo.

Bloons TD 6 possui tantas fases que, quando retorno a um mapa para jogá-lo novamente, frequentemente não consigo lembrar qual estratégia utilizei na ocasião anterior.

Posso ter passado por aquela fase, encontrado uma combinação de macacos que funcionou perfeitamente e conseguido completar o objetivo. Mas, quando volto algum tempo depois, já não me lembro exatamente de como havia feito aquilo.

Então preciso pensar novamente.

É como se determinados mapas se tornassem pequenas experiências novas, mesmo quando tecnicamente já passei por eles.

Isso ajuda a manter o jogo interessante, porque a repetição não significa necessariamente reproduzir os mesmos movimentos.

Às vezes, encontro uma solução diferente. Outras vezes, preciso experimentar algumas combinações até descobrir o que funciona.

E, como ainda estou longe de esgotar todas as dificuldades, existe bastante espaço para continuar explorando.

Não tenho qualquer impressão de que Bloons TD 6 esteja perto de sair da minha rotina.

Ele continua sendo um daqueles jogos que posso abrir, jogar algumas partidas e fechar sem precisar transformar cada sessão em um grande compromisso.

E, aparentemente, os macacos e balões continuarão presentes na minha vida por bastante tempo.

Capítulo 2 — Cities: Skylines e o prazer de simplesmente continuar uma cidade

Depois de uma semana em que Cities: Skylines ficou completamente ausente, voltei a jogar um pouco.

Mas não foi nada extraordinário.

Não iniciei uma nova cidade, não mergulhei em algum grande projeto de infraestrutura e também não dediquei muitas horas a resolver problemas urbanos.

Simplesmente abri o jogo para relaxar.

Continuei um pouco a cidade que já estava construindo e aproveitei aquele momento sem nenhuma preocupação especial.

Existe algo bastante agradável nessa maneira de jogar Cities: Skylines.

Nem sempre preciso ter um objetivo definido. Às vezes, basta observar a cidade, realizar alguns pequenos ajustes e acompanhar seu funcionamento.

É uma experiência que me permite avançar no meu próprio ritmo.

Depois de tantas horas dedicadas ao jogo, a familiaridade com suas mecânicas também ajuda a transformar essas sessões em momentos de descanso.

Não preciso reaprender tudo a cada vez que abro a cidade.

Posso simplesmente continuar.

E talvez essa seja uma das razões pelas quais Cities: Skylines permanece há tanto tempo entre meus jogos mais utilizados.

Ele não exige que eu esteja sempre procurando alguma coisa nova.

Às vezes, continuar aquilo que já construí é suficiente.

Capítulo 3 — Fruit Clash e Crossword Master: os pequenos intervalos do celular

No celular, continuo mantendo dois hábitos bastante simples.

O primeiro é Fruit Clash, aquele jogo de combinar frutas que venho utilizando como uma pequena distração.

É uma experiência sem conquistas, sem acompanhamento de horas jogadas e sem qualquer grande objetivo que eu esteja tentando alcançar.

Simplesmente abro o jogo e me divirto durante algum tempo.

Não existe uma preocupação com completar tudo, desbloquear alguma coisa específica ou acompanhar estatísticas.

É apenas um jogo relaxante.

E gosto de perceber que, mesmo depois de ter desenvolvido tanto interesse por conquistas e sistemas de acompanhamento, ainda consigo manter experiências nas quais nada disso importa.

O segundo hábito continua sendo Crossword Master.

Tenho jogado aproximadamente uma palavra cruzada por dia.

É uma atividade pequena, que se encaixa facilmente na rotina e não exige que eu reserve um período muito grande para jogar.

Vou avançando aos poucos, resolvendo os desafios e mantendo essa pequena frequência.

Esses dois jogos representam uma parte da minha rotina que talvez fosse completamente ignorada se eu escrevesse apenas sobre jogos terminados.

Não são necessariamente as experiências mais elaboradas da semana.

Mas continuam fazendo parte dela.

E é justamente por isso que merecem aparecer nesta Jornada Gamer.

Capítulo 4 — EarthBound: um jogo de console que mora no meu celular

Entretanto, existe um terceiro jogo que também faz parte da minha experiência no celular.

E, curiosamente, ele não é propriamente um jogo de celular.

Estou falando de EarthBound.

Tenho jogado EarthBound através do RetroArch, utilizando o sistema de conquistas do RetroAchievements.

Esse é um daqueles casos bastante interessantes em que a versão traduzida do jogo é compatível com as conquistas. Portanto, estou conseguindo jogar EarthBound em português sem abrir mão do acompanhamento pelo RetroAchievements.

Isso torna a experiência particularmente agradável para mim.

EarthBound é um jogo de que gosto muito.

Já estou bastante avançado na aventura, embora tenha passado algum tempo sem jogar antes de retomá-la nesta semana.

Agora, minha intenção principal é chegar ao final.

Quero terminar o jogo.

Entretanto, existe uma questão envolvendo as conquistas.

Algumas delas são perdíveis, e eu já deixei passar determinadas oportunidades durante a campanha.

Isso significa que, se decidir buscar todas as conquistas, provavelmente precisarei jogar novamente.

Mas ainda não tomei essa decisão.

Por enquanto, quero concluir a aventura que já comecei.

Depois de terminar, pretendo observar quais conquistas ficaram faltando e avaliar se realmente tenho vontade de voltar para buscá-las.

Como gosto muito de EarthBound, existe uma boa possibilidade de que uma segunda jornada seja interessante.

Mas não quero transformar essa possibilidade em uma obrigação antecipada.

Prefiro terminar primeiro e decidir depois.

Existe uma diferença importante entre jogar novamente porque gosto de uma experiência e me sentir obrigado a repeti-la apenas porque algumas conquistas ficaram para trás.

O RetroAchievements é uma ferramenta que gosto muito de utilizar, mas não quero que ele determine sozinho a maneira como aproveito meus jogos.

EarthBound merece ser terminado por aquilo que representa para mim.

As conquistas podem ficar para uma próxima decisão.

Uma conquista perdida pode justificar uma segunda jornada, mas não deveria apagar o prazer da primeira.

Capítulo 5 — My Life as a King: reconstruindo o reino com mais estratégia

Outro jogo que continua ocupando bastante espaço na minha rotina é Final Fantasy Crystal Chronicles: My Life as a King.

Na semana anterior, contei que havia perdido meu arquivo de salvamento por conta do processo de backup da NAND do Nintendo Wii.

Foi uma situação bastante desagradável, porque precisei recomeçar uma experiência na qual já havia avançado consideravelmente.

Agora, aos poucos, estou me aproximando novamente daquele ponto.

Ainda não cheguei exatamente ao mesmo lugar em que estava antes de perder o primeiro salvamento. Estou um pouco atrás.

Mas existe uma diferença importante nesta nova campanha.

Estou jogando com mais estratégia.

Como já conheço melhor algumas mecânicas e já passei por parte desse conteúdo anteriormente, consigo tomar determinadas decisões com mais consciência.

Não estou simplesmente repetindo os mesmos passos de maneira automática.

Estou aproveitando aquilo que aprendi na primeira tentativa.

Além disso, agora estou utilizando as DLCs, o que também diferencia esse novo arquivo de salvamento da experiência anterior.

Existe ainda uma questão importante envolvendo os arquivos de salvamento.

Eu possuo um salvamento do Nintendo Wii, mas ele não resolveria minha intenção atual de acompanhar a progressão através das conquistas.

Por isso, continuei com o novo arquivo que estou utilizando no computador.

Quero que essa jornada também faça parte do acompanhamento que venho construindo com o RetroAchievements.

E, apesar de ter precisado recomeçar, continuo gostando muito do jogo.

My Life as a King permanece como um forte candidato a meu novo jogo de conforto.

É uma experiência à qual tenho vontade de retornar, mesmo quando não existe nenhuma grande novidade acontecendo.

Talvez seja justamente isso que define um jogo de conforto.

Não é necessariamente aquele que oferece a maior quantidade de conteúdo ou as mecânicas mais complexas.

É aquele ao qual temos vontade de voltar.

Capítulo 6 — Need for Speed: Nitro e a tranquilidade de não ter pressa

O último jogo que continua aparecendo com frequência na minha rotina é Need for Speed: Nitro.

Tenho jogado de maneira bastante descontraída.

Não estou tentando vencer todas as pistas imediatamente, completar cada objetivo na primeira oportunidade ou avançar o mais rapidamente possível.

Vou jogando em uma velocidade que considero confortável.

E existe uma razão bastante simples para isso.

Eu sei que Need for Speed: Nitro é um jogo longo.

Também sei que, conforme avanço, vou conseguir mais dinheiro e ter acesso a carros melhores.

Portanto, não vejo muito sentido em ficar me estressando agora com determinados objetivos que provavelmente serão mais fáceis quando eu possuir veículos superiores.

Posso continuar avançando, ganhar dinheiro e voltar posteriormente para completar aquilo que ficou para trás.

É uma maneira de jogar que combina bastante com aquilo que estou procurando neste momento.

Quero me divertir.

Não quero transformar cada corrida em uma obrigação.

Na semana anterior, comentei como fiquei satisfeito ao descobrir que podia jogar Need for Speed: Nitro utilizando meu controle de Xbox One, em uma experiência mais próxima dos jogos tradicionais de corrida que conheço.

Essa possibilidade continua tornando o jogo bastante agradável.

Agora, estou aproveitando essa experiência sem pressa.

Não preciso conquistar tudo imediatamente.

Não preciso voltar repetidamente à mesma pista apenas porque deixei algum objetivo incompleto.

Sei que poderei retornar depois.

E essa tranquilidade tem feito muito bem à experiência.

Capítulo 7 — O backlog começa a chamar minha atenção

Enquanto organizava os jogos desta semana, percebi que existe uma característica comum entre várias das experiências que venho mantendo.

Bloons TD 6 parece praticamente infinito.

Cities: Skylines também permite continuar jogando durante uma quantidade enorme de horas.

Fruit Clash e Crossword Master fazem parte de pequenos hábitos cotidianos, sem que eu esteja necessariamente procurando um encerramento.

My Life as a King e Need for Speed: Nitro continuam avançando aos poucos.

E EarthBound é um dos poucos jogos da lista que já está bastante próximo daquilo que considero um objetivo concreto: terminar a aventura.

Isso me fez pensar no meu backlog.

Tenho vários jogos que comecei e deixei pela metade.

Alguns foram interrompidos porque apareceu outra coisa que despertou meu interesse. Outros simplesmente perderam espaço na rotina. E certamente existem aqueles que talvez eu já não tenha tanta vontade de continuar.

Começo a considerar a possibilidade de olhar para essa lista com um pouco mais de atenção.

Talvez esteja chegando a hora de escolher alguns desses jogos e finalmente terminá-los.

Ou, quando perceber que realmente não quero mais continuar determinada experiência, simplesmente decidir deixá-la para trás.

Não preciso necessariamente carregar cada jogo iniciado como uma obrigação permanente.

Mas também não quero continuar acumulando aventuras pela metade quando poderia escolher algumas delas e chegar ao final.

Minha intenção é aumentar o número de jogos terminados.

E talvez a próxima semana represente o começo desse movimento.

Posso procurar algum título do backlog que já esteja relativamente avançado.

Posso escolher alguma experiência mais curta.

Ou posso simplesmente retomar um jogo antigo e descobrir se ainda tenho vontade de terminá-lo.

Por enquanto, ainda não decidi.

Mas a possibilidade está começando a me interessar.

Talvez organizar um backlog não seja apenas descobrir quais jogos ainda faltam terminar, mas também decidir quais histórias ainda merecem meu tempo.

Conclusão — Continuar também faz parte da jornada

A terceira Jornada Gamer Semanal não apresentou nenhum grande lançamento dentro da minha rotina.

Continuei jogando Bloons TD 6, avançando por novas fases e dificuldades em um jogo que ainda parece ter muitas horas pela frente.

Voltei brevemente a Cities: Skylines, apenas para relaxar e continuar um pouco minha cidade.

No celular, mantive meus pequenos hábitos com Fruit Clash e Crossword Master.

Também retomei EarthBound, uma aventura de que gosto muito e que já está bastante avançada. Minha intenção agora é terminá-la, mesmo sabendo que algumas conquistas perdíveis poderão justificar uma segunda campanha no futuro.

Continuei reconstruindo meu reino em My Life as a King, aproximando-me do ponto em que estava antes de perder o salvamento, mas agora com mais estratégia e utilizando as DLCs.

E segui jogando Need for Speed: Nitro de maneira descontraída, sem transformar cada corrida ou objetivo incompleto em motivo para estresse.

Foi uma semana de continuidade.

E, olhando para ela, percebo que isso também representa uma parte importante da minha relação com os videogames.

Nem sempre quero novidades.

Nem sempre preciso de um jogo novo.

Nem sempre estou procurando completar uma lista de conquistas ou alcançar imediatamente o encerramento de uma campanha.

Às vezes, quero apenas continuar jogando aquilo de que gosto.

Mas também começo a sentir vontade de equilibrar um pouco melhor essas experiências com jogos que possuem um final mais definido.

Quero aumentar meu número de jogos terminados.

Quero olhar para o backlog e decidir o que realmente pretendo continuar.

E quero aproveitar essa nova série para acompanhar não apenas aquilo que estou jogando, mas também as mudanças que acontecem nas minhas próprias escolhas.

Talvez a próxima semana traga algum jogo novo para a lista.

Talvez eu retome uma aventura que ficou esquecida.

Talvez finalmente termine algum título que está parado há bastante tempo.

Ou talvez continue jogando os mesmos jogos, porque ainda estou me divertindo com eles.

Por enquanto, não sei.

Mas essa é justamente a parte interessante de registrar a jornada enquanto ela acontece.

Não preciso conhecer o próximo capítulo antes de começar a escrevê-lo.

Uma semana sem jogos novos não é uma semana sem progresso. Às vezes, avançar significa apenas continuar aquilo que ainda nos faz querer jogar.

Esta foi a Jornada Gamer Semanal número três.

Uma semana tranquila, de jogos conhecidos, pequenas continuidades e uma vontade crescente de voltar a terminar algumas aventuras.

Vamos ver se a quarta semana será aquela em que finalmente começarei a enfrentar meu backlog.

sábado, 31 de outubro de 2026

A Biblioteca, interlúdio — sete itens, trinta e dois reais e uma aposta

Sete itens. Trinta e dois reais e quarenta e oito centavos. Oitenta e oito por cento de desconto, duzentos e quarenta e três reais economizados. E eu escrevendo uma série sobre organizar uma biblioteca de mil e quatrocentos jogos, no exato momento em que coloco mais seis dentro dela.

Este não é um novo post. O post sobre duplicatas continua de pé, com a coluna GrupoDuplicata ainda vazia esperando a vez.

Este é um interlúdio, e ele existe porque a vida não respeita cronograma de série. Eu passei um bom tempo escrevendo sobre a necessidade de não comprar o que já se tem, e na quinta-feira às 19h55 eu comprei seis jogos de terror de uma vez. Achar isso engraçado é mais produtivo do que fingir que não aconteceu.

O que Thriller fez comigo antes de eu saber o que era um videoclipe

Existe uma coisa na minha relação com terror que eu nunca consegui datar direito, mas sei de onde vem: o Thriller.

Eu era criança. Michael Jackson não era um artista que eu escolhi ouvir — era uma presença, do tipo que existe na casa antes de a gente entender o que é televisão. E aquele vídeo de quatorze minutos, com o John Landis dirigindo e o Rick Baker fazendo as maquiagens, não era um filme de terror. Era outra coisa.

Demorei muitos anos para entender o que aquilo tinha feito comigo. Porque o Thriller não me ensinou a ter medo. Ele me ensinou que o medo podia ser bonito.

Os mortos saem da terra e dançam. Não perseguem, não devoram — dançam, em coreografia, no meio da rua, com o Michael no meio deles. O monstro não é ameaça, é espetáculo. A morte vira número musical. E uma criança que assiste isso aprende uma coisa que não deveria aprender tão cedo: que existe prazer em olhar para o que assusta, desde que alguém esteja conduzindo o espetáculo.

Thriller não me deu medo de monstros. Me deu a certeza de que monstros são interessantes.

Isso ficou. E é por isso que todo outubro, quando as lojas resolvem que é hora de vender terror com desconto, eu fico suscetível de um jeito específico.

Por que outubro, e não abril

Existe uma explicação de mercado, e ela é óbvia: as lojas colocam terror em promoção em outubro porque é o mês em que terror vende. Não preciso explicar isso.

Mas existe uma explicação de outra ordem, e é a que me interessa. Fora de outubro, terror é um gênero de solidão. Você joga sozinho, no escuro, e ninguém ao seu redor compartilha a experiência. É um gênero que se consome escondido, quase com vergonha de admitir que gosta.

Em outubro, o terror vira coletivo. As pessoas decoram casas, fantasiam, assistem as mesmas coisas, comentam. O medo vira ritual social. E é exatamente esse o registro do Thriller — não o susto, a celebração.

Eu compro terror em outubro porque, nesse mês, comprar terror não parece esquisito. Parece participação.

E aí está a ironia que eu só percebi depois de comprar: os jogos que eu levei não têm nada de celebração. São o oposto do Thriller. Em Thriller, os mortos dançam e você assiste, encantado. Em Outlast, você corre e se esconde, e o espetáculo é a sua própria fragilidade.

Comprei o gênero do espetáculo. Levei o gênero da fuga. Vamos ver o que acontece quando eu abrir.

O que chegou na caixa

O recibo, item por item, sem arredondar nada:

Item Preço O que é
Little Misfortune R$ 11,39 Narrativo, point and click, dos criadores de Fran Bow
The Darkness II R$ 4,49 FPS com poderes demoníacos, baseado em quadrinhos
Outlast 2 R$ 4,79 Terror em primeira pessoa, seita, deserto do Arizona
Outlast R$ 3,75 O original. Asilo, câmera com bateria, sem combate
Never Again R$ 3,11 Terror psicológico de casa, indie
Outlast: Whistleblower R$ 2,71 DLC do primeiro, história paralela
The Shore R$ 2,24 Walking sim lovecraftiano numa ilha
Total R$ 32,48 de R$ 276,33

Duas observações que só um inventário produz.

A primeira: Whistleblower é DLC. A decisão que eu deixei pendente no primeiro post — DLC conta como jogo ou é uma coluna do jogo base — acabou de ganhar um caso real, datado e com preço de dois reais e setenta e um centavos. Para a planilha, é uma linha ou uma anotação? Eu ainda não sei. Mas agora eu tenho o exemplo, e isso é melhor que a dúvida abstrata.

A segunda: o recibo diz The Darkness II (ROW). Rest of world, chave de fora do mercado americano. É o mesmo problema de região que eu passei um post inteiro discutindo, aparecendo de novo, agora do lado da compra em vez do lado do emulador. A diferença é que aqui não me custa nada — chave de loja não tem hash para bater.

A aposta

Trinta e dois reais é barato demais para justificar uma compra. Não existe argumento a construir: o valor se defende sozinho, e qualquer texto tentando provar que foi uma decisão inteligente soaria defensivo.

A pergunta boa é outra, e é mais cruel: quantos desses seis eu realmente abro?

Então vou apostar agora, com o recibo ainda quente, e conferir em janeiro. Sem editar depois, sem ajustar a previsão para parecer que eu sabia.

Vou zerar dois. Little Misfortune, porque é narrativo, curto e tem voz própria — o tipo de jogo que se termina numa sentada porque a história puxa. E The Darkness II, porque não é terror de perseguição: é ação com história, do tipo que eu consigo jogar sentado sem tensão. É o menos hostil da lista, apesar de ser o que tem demônios de verdade.

Vou jogar e não terminar dois. Outlast, porque é o mais conhecido e eu vou querer ver com os próprios olhos do que todo mundo fala — mas terror de perseguição pura é o gênero que me expulsa, e eu já sei disso. E The Shore, por curiosidade lovecraftiana: dois reais e vinte e quatro centavos compram exatamente meia hora de atmosfera antes de eu me cansar.

Não vou abrir ou vou abandonar três. Outlast 2, que é mais longo, mais frustrante e mais divisivo que o primeiro — a crítica é unânime em dizer que ele estica o que o original fazia em cinco horas. Never Again, que é o jogo sobre o qual eu sei menos, e a maior incógnita da aposta: comprei no escuro, e no escuro costuma ficar. E Whistleblower, que só existe se eu terminar Outlast — uma aposta condicional, e portanto a mais perdida de todas.

Se eu acertar, são dois zerados de seis. Um terço. Para uma compra de trinta e dois reais, dá dezesseis reais e vinte e quatro centavos por jogo terminado — que é mais do que eu pagaria por qualquer um deles individualmente, e ainda assim menos do que um ingresso de cinema.

É esse o número que eu quero ver em janeiro.

A promoção nunca é sobre o preço do jogo. É sobre o preço do jogo dividido pela chance de você jogá-lo — e esse segundo número ninguém coloca na etiqueta.

O caso Outlast: eu não comprei o jogo, comprei a linha

Tem uma coisa nesta compra que merece parágrafo próprio, porque é a parte que eu não esperava e é a mais reveladora.

Eu já tenho Outlast. No Switch. Ele está lá, na biblioteca, disponível, e eu poderia jogar hoje sem pagar nada.

E paguei três reais e setenta e cinco centavos para ter de novo, no PC.

Não é por causa do jogo. O jogo é o mesmo. Não é por performance, não é por mod, não é por teclado e mouse — e quem já jogou Outlast sabe que teclado e mouse não melhoram em nada a experiência de correr de um homem de dois metros com a cara deformada.

Eu paguei pela conquista.

E aqui é onde eu preciso ser específico, porque a diferença importa: eu não vou platinar Outlast. Provavelmente não vou fazer 100%. Terror de perseguição não é o gênero em que eu me comprometo com desafio — é o gênero em que eu pulo sustos e continuo mesmo assim.

O que eu quero é o zerado. Aquela linha registrada dizendo que eu cheguei ao fim, em tal data, com tal tempo. O registro de que aquilo aconteceu.

É a distinção que eu passei um post inteiro elogiando: zerado e completado são coisas diferentes, e a maioria dos sistemas de conquista só sabe medir a segunda. Quando eu digo que não vou platinar, eu estou dizendo que não vou perseguir o completado — mas o zerado eu quero, e ele vale por si.

Três reais e setenta e cinco centavos não foi o preço de um jogo que eu já tenho. Foi o preço de uma linha na planilha.

Existe um momento na vida de colecionador em que você para de comprar jogos e começa a comprar registros de que jogou. Esse momento chegou para mim numa quinta-feira de outubro, por menos de quatro reais.

E tem uma consequência prática nisso que só ficou clara depois. Os seis são todos Steam. Eles são, literalmente, os únicos jogos da minha biblioteca inteira que vão gerar número de horas, porque a Steam é a única das seis lojas que devolve esse dado. Todo o resto — Epic, GOG, Amazon, EA, Ubisoft — vai continuar sem histórico, por escolha delas.

Ou seja: eu comprei, sem querer, o único lote da minha coleção que é mensurável.

O que o número vai dizer em janeiro

Em janeiro eu volto com três números: quantos eu zerei, quanto tempo eu efetivamente joguei, e quanto custou cada hora.

Só que o terceiro número vai fazer uma pergunta que eu não estou pronto para responder com honestidade. Se eu jogar quinze horas no total dos seis, o custo por hora é de dois reais e dezesseis centavos — mais barato que qualquer coisa que eu faça no computador. Se eu jogar três horas, o custo por hora sobe para quase onze reais, e aí a comparação deixa de ser com cinema e passa a ser com um jogo que eu já tinha e não joguei.

E é aí que este interlúdio encontra a série principal de novo.

Porque a planilha da minha biblioteca tem mais de mil jogos, e o número de horas concentrado nela é sempre o mesmo padrão: cinco ou seis jogos carregam quase tudo, e o resto divide migalhas. Eu não preciso apostar em nada para saber disso — eu só preciso olhar os dados quando eles chegarem.

A aposta que eu fiz acima não é sobre Outlast nem sobre Little Misfortune. É sobre a hipótese mais confortável que um colecionador pode sustentar: dessa vez eu vou jogar.

Veremos.

Comprar é barato. Jogar é o que custa — e é o único custo que não aparece no recibo.