[{"data":1,"prerenderedAt":429},["ShallowReactive",2],{"blog-list":3},[4,143],{"id":5,"title":6,"body":7,"date":132,"description":133,"extension":134,"lang":135,"meta":136,"navigation":137,"path":138,"seo":139,"stem":140,"translationKey":141,"__hash__":142},"blog\u002Fblog\u002Fllms-no-jogo-com-csharp.md","Construindo um Narrador com LLMs para The Sims 3",{"type":8,"value":9,"toc":126},"minimark",[10,15,24,28,48,71,75,92,96,111,122],[11,12,14],"h2",{"id":13},"o-problema","O problema",[16,17,18,19,23],"p",{},"The Sims 3 tem um sistema de pensamentos simples — balões com ícones. A ideia era substituir isso por ",[20,21,22],"strong",{},"narrativas geradas por IA"," em tempo real, usando o estado do jogo como contexto.",[11,25,27],{"id":26},"a-solução","A solução",[16,29,30,31,35,36,43,44,47],{},"O mod intercepta eventos do jogo (refeição, conversa, trabalho) via hooks de C# no ",[32,33,34],"code",{},".NET Framework 3.5",", formata um prompt e envia para uma API local do ",[37,38,42],"a",{"href":39,"rel":40},"https:\u002F\u002Follama.com",[41],"nofollow","Ollama"," rodando o modelo ",[20,45,46],{},"Gemma 2B",".",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-csharp shiki shiki-themes github-light github-dark","var prompt = $\"O personagem {sim.Name} acabou de {evento}. Gere um pensamento curto e em primeira pessoa.\";\nvar resposta = await OllamaClient.GenerateAsync(prompt);\n","csharp","",[32,56,57,65],{"__ignoreMap":54},[58,59,62],"span",{"class":60,"line":61},"line",1,[58,63,64],{},"var prompt = $\"O personagem {sim.Name} acabou de {evento}. Gere um pensamento curto e em primeira pessoa.\";\n",[58,66,68],{"class":60,"line":67},2,[58,69,70],{},"var resposta = await OllamaClient.GenerateAsync(prompt);\n",[11,72,74],{"id":73},"resultados","Resultados",[76,77,78,82,85],"ul",{},[79,80,81],"li",{},"Narrativas únicas por personagem com base em traits e humor",[79,83,84],{},"Latência aceitável (~800ms) com modelos quantizados",[79,86,87,88,91],{},"Arquitetura baseada no paper ",[20,89,90],{},"\"Generative Agents\""," da Stanford",[11,93,95],{"id":94},"aprendizados","Aprendizados",[16,97,98,99,102,103,106,107,110],{},"Trabalhar com LLMs em contexto restrito (jogos em tempo real) exige controle fino de ",[20,100,101],{},"tempo de inferência",", ",[20,104,105],{},"tamanho de contexto"," e ",[20,108,109],{},"fallback"," gracioso para quando o modelo demora demais.",[112,113,114],"blockquote",{},[16,115,116,117,47],{},"Código disponível no ",[37,118,121],{"href":119,"rel":120},"https:\u002F\u002Fgithub.com\u002Fitpzzi\u002FNarradorPorEventosSimsPensantes",[41],"GitHub",[123,124,125],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":54,"searchDepth":67,"depth":67,"links":127},[128,129,130,131],{"id":13,"depth":67,"text":14},{"id":26,"depth":67,"text":27},{"id":73,"depth":67,"text":74},{"id":94,"depth":67,"text":95},"2026-05-20","Como integrei modelos de linguagem locais (Ollama + Gemma) em um mod de C# para The Sims 3, gerando pensamentos e narrativas em tempo real.","md","pt-BR",{},true,"\u002Fblog\u002Fllms-no-jogo-com-csharp",{"title":6,"description":133},"blog\u002Fllms-no-jogo-com-csharp","sims3-llm-narrator","VYGghhmJ-D6WQE1VLQ-sSPtj0QvW_f7pWl4L4gQ9Kew",{"id":144,"title":145,"body":146,"date":421,"description":422,"extension":134,"lang":135,"meta":423,"navigation":137,"path":424,"seo":425,"stem":426,"translationKey":427,"__hash__":428},"blog\u002Fblog\u002Fvue3-nuxt3-ecossistema.md","Vue 3 + Nuxt 3: o que mudou no ecossistema",{"type":8,"value":147,"toc":414},[148,152,163,262,266,282,369,373,380,384,404,408,411],[11,149,151],{"id":150},"composition-api-é-o-novo-padrão","Composition API é o novo padrão",[16,153,154,155,158,159,162],{},"O maior salto do Vue 2 para o Vue 3 foi a ",[20,156,157],{},"Composition API"," com ",[32,160,161],{},"\u003Cscript setup>",". O código fica mais legível, reutilizável e fácil de tipar com TypeScript.",[49,164,168],{"className":165,"code":166,"language":167,"meta":54,"style":54},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\nconst count = ref(0)\nconst doubled = computed(() => count.value * 2)\n\u003C\u002Fscript>\n","vue",[32,169,170,197,222,252],{"__ignoreMap":54},[58,171,172,176,180,184,187,190,194],{"class":60,"line":61},[58,173,175],{"class":174},"sVt8B","\u003C",[58,177,179],{"class":178},"s9eBZ","script",[58,181,183],{"class":182},"sScJk"," setup",[58,185,186],{"class":182}," lang",[58,188,189],{"class":174},"=",[58,191,193],{"class":192},"sZZnC","\"ts\"",[58,195,196],{"class":174},">\n",[58,198,199,203,207,210,213,216,219],{"class":60,"line":67},[58,200,202],{"class":201},"szBVR","const",[58,204,206],{"class":205},"sj4cs"," count",[58,208,209],{"class":201}," =",[58,211,212],{"class":182}," ref",[58,214,215],{"class":174},"(",[58,217,218],{"class":205},"0",[58,220,221],{"class":174},")\n",[58,223,225,227,230,232,235,238,241,244,247,250],{"class":60,"line":224},3,[58,226,202],{"class":201},[58,228,229],{"class":205}," doubled",[58,231,209],{"class":201},[58,233,234],{"class":182}," computed",[58,236,237],{"class":174},"(() ",[58,239,240],{"class":201},"=>",[58,242,243],{"class":174}," count.value ",[58,245,246],{"class":201},"*",[58,248,249],{"class":205}," 2",[58,251,221],{"class":174},[58,253,255,258,260],{"class":60,"line":254},4,[58,256,257],{"class":174},"\u003C\u002F",[58,259,179],{"class":178},[58,261,196],{"class":174},[11,263,265],{"id":264},"pinia-substituiu-o-vuex","Pinia substituiu o Vuex",[16,267,268,269,272,273,102,276,106,279,47],{},"O Vuex 4 ainda existe, mas o ",[20,270,271],{},"Pinia"," é o store oficial hoje. Sem mutations, sem namespaces verbosos — só ",[32,274,275],{},"state",[32,277,278],{},"getters",[32,280,281],{},"actions",[49,283,287],{"className":284,"code":285,"language":286,"meta":54,"style":54},"language-ts shiki shiki-themes github-light github-dark","export const useCounterStore = defineStore('counter', () => {\n  const count = ref(0)\n  const increment = () => count.value++\n  return { count, increment }\n})\n","ts",[32,288,289,318,335,355,363],{"__ignoreMap":54},[58,290,291,294,297,300,302,305,307,310,313,315],{"class":60,"line":61},[58,292,293],{"class":201},"export",[58,295,296],{"class":201}," const",[58,298,299],{"class":205}," useCounterStore",[58,301,209],{"class":201},[58,303,304],{"class":182}," defineStore",[58,306,215],{"class":174},[58,308,309],{"class":192},"'counter'",[58,311,312],{"class":174},", () ",[58,314,240],{"class":201},[58,316,317],{"class":174}," {\n",[58,319,320,323,325,327,329,331,333],{"class":60,"line":67},[58,321,322],{"class":201},"  const",[58,324,206],{"class":205},[58,326,209],{"class":201},[58,328,212],{"class":182},[58,330,215],{"class":174},[58,332,218],{"class":205},[58,334,221],{"class":174},[58,336,337,339,342,344,347,349,352],{"class":60,"line":224},[58,338,322],{"class":201},[58,340,341],{"class":182}," increment",[58,343,209],{"class":201},[58,345,346],{"class":174}," () ",[58,348,240],{"class":201},[58,350,351],{"class":174}," count.value",[58,353,354],{"class":201},"++\n",[58,356,357,360],{"class":60,"line":254},[58,358,359],{"class":201},"  return",[58,361,362],{"class":174}," { count, increment }\n",[58,364,366],{"class":60,"line":365},5,[58,367,368],{"class":174},"})\n",[11,370,372],{"id":371},"vite-no-lugar-do-webpack","Vite no lugar do Webpack",[16,374,375,376,379],{},"O Nuxt 3 usa ",[20,377,378],{},"Vite"," por padrão. HMR instantâneo, build mais rápido, melhor DX. A diferença é sentida especialmente em projetos grandes.",[11,381,383],{"id":382},"o-que-ainda-é-válido-do-vue-2","O que ainda é válido do Vue 2",[76,385,386,389,401],{},[79,387,388],{},"Options API ainda funciona no Vue 3",[79,390,391,102,394,102,397,400],{},[32,392,393],{},"v-model",[32,395,396],{},"v-for",[32,398,399],{},"v-if"," — mesma API",[79,402,403],{},"Ecosystem de componentes está migrando, mas Vuetify, Quasar e PrimeVue têm versões Vue 3",[11,405,407],{"id":406},"conclusão","Conclusão",[16,409,410],{},"A migração vale a pena. A curva de aprendizado é real, mas o ganho em produtividade e performance compensa.",[123,412,413],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":54,"searchDepth":67,"depth":67,"links":415},[416,417,418,419,420],{"id":150,"depth":67,"text":151},{"id":264,"depth":67,"text":265},{"id":371,"depth":67,"text":372},{"id":382,"depth":67,"text":383},{"id":406,"depth":67,"text":407},"2026-05-10","Um panorama prático das principais mudanças do Vue 2\u002FNuxt 2 para Vue 3\u002FNuxt 3 — Composition API, Pinia, Vite e o que realmente importa no dia a dia.",{},"\u002Fblog\u002Fvue3-nuxt3-ecossistema",{"title":145,"description":422},"blog\u002Fvue3-nuxt3-ecossistema","vue3-nuxt3-ecosystem","Bz7Qqxjk8wlM6rQSQNmEeZf0LcKAHGkaBq41yKNmjpk",1779999660538]