[{"data":1,"prerenderedAt":881},["ShallowReactive",2],{"notes":3},[4,72,212],{"id":5,"title":6,"body":7,"date":55,"description":13,"discussionStatus":56,"extension":57,"hasTldr":58,"meta":59,"navigation":60,"path":61,"seo":62,"stage":63,"stem":64,"tags":65,"__hash__":71},"notes\u002Fnotes\u002Fbatchmode-in-unity.md","Batchmode in Unity & Automating VRC Avatar Bundling",{"type":8,"value":9,"toc":49},"minimark",[10,14,19,32,36],[11,12,13],"p",{},"Looks like you can start a Unity Editor instance in batchmode, which is a headless mode that allows you to run Unity without the graphical user interface. This is useful for automating tasks, running scripts, or building projects from the command line. I want to try to make a script that you can bundle your VRC avatar without opening the whole editor.",[15,16,18],"h2",{"id":17},"anti-feature-warning","Anti-feature warning",[11,20,21,22,26,27,31],{},"VRC SDK is ",[23,24,25],"u",{},"closed source"," ",[28,29,30],"em",{},"(as well as the whole game, duh)",", so looks like I'll have two options: Reverse engineer the SDK, or import the SDK as an assembly on my scripts.",[15,33,35],{"id":34},"references","References",[37,38,39],"ul",{},[40,41,42],"li",{},[43,44,48],"a",{"href":45,"rel":46},"https:\u002F\u002Fdocs.unity3d.com\u002F2022.3\u002FDocumentation\u002FManual\u002FCLIBatchmodeCoroutines.html",[47],"nofollow","Unity Manual: Batchmode Coroutines",{"title":50,"searchDepth":51,"depth":51,"links":52},"",2,[53,54],{"id":17,"depth":51,"text":18},{"id":34,"depth":51,"text":35},"2026-07-04","closed","md",false,{},true,"\u002Fnotes\u002Fbatchmode-in-unity",{"title":6,"description":13},"seedling","notes\u002Fbatchmode-in-unity",[66,67,68,69,70],"unity","vrchat","avatars","csharp","experiments","sP8DOs7wKYlnVI701zwoWtRF3XCGMWQsO0YUoiKiF_s",{"id":73,"title":74,"body":75,"date":55,"description":79,"discussionStatus":148,"extension":57,"hasTldr":58,"meta":203,"navigation":60,"path":204,"seo":205,"stage":63,"stem":206,"tags":207,"__hash__":211},"notes\u002Fnotes\u002Fdiscussion-system.md","Discussion System for my digital garden",{"type":8,"value":76,"toc":197},[77,80,84,87,91,94,139,157,161,168,170],[11,78,79],{},"I just had the idea to implement a discussion system for my knowledge base, authentication will be done through Discord, no account system at all. I could control who can post a comment (anyone, friends, or nobody), maybe even implement a voting system for comments and posts in general.",[15,81,83],{"id":82},"social-sdk-roadblock","Social SDK roadblock",[11,85,86],{},"Looks like I couldn't implement the \"friends-only\" status because Discord's API doesn't allow me to check user's friends list unless I apply for the \"Social SDK\". This is kinda a bummer, but I understand the privacy concerns of allowing apps to check user's friends list. For this road block I'm implementing a \"guild-only\" status, which will allow users to post comments if they are in a specific Discord server.",[15,88,90],{"id":89},"implementation","Implementation",[11,92,93],{},"For this approach I used some stuff that I experienced before, here's the stack of technologies I used for this:",[37,95,96,107,121,131],{},[40,97,98,106],{},[43,99,102],{"href":100,"rel":101},"https:\u002F\u002Fnuxt.com\u002Fmodules\u002Fauth-utils",[47],[103,104,105],"code",{},"nuxt-auth-utils"," for Discord OAuth2 authentication.",[40,108,109,116,117,120],{},[43,110,113],{"href":111,"rel":112},"https:\u002F\u002Fpinia.vuejs.org\u002F",[47],[103,114,115],{},"pinia"," for state management, as well as ",[103,118,119],{},"@pinia\u002Fnuxt"," for Nuxt integration.",[40,122,123,130],{},[43,124,127],{"href":125,"rel":126},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@libsql\u002Fclient",[47],[103,128,129],{},"@libsql\u002Fclient"," for database access.",[40,132,133,134,138],{},"a ",[135,136,137],"strong",{},"Turso Database"," for storing discussions and profiles, which is a SQLite database hosted on the cloud.",[11,140,141,142,145,146,149,150,153,154,156],{},"For the discussion status, I implemented a ",[103,143,144],{},"discussionStatus"," field in the frontmatter of each post, which can be set to either ",[103,147,148],{},"open",", ",[103,151,152],{},"guild-only",", or ",[103,155,56],{},". This allows me to control who can post comments on each post.",[15,158,160],{"id":159},"moderation","Moderation",[11,162,163,164,167],{},"For moderation, I implemented a env var called ",[103,165,166],{},"NUXT_OAUTH_DISCORD_ADMINS"," which is a comma-separated list of Discord user IDs that are allowed to moderate discussions. Users are able to delete their own comments, but moderators can deleta any comment.",[15,169,35],{"id":34},[37,171,172,179,185,191],{},[40,173,174],{},[43,175,178],{"href":176,"rel":177},"https:\u002F\u002Fdocs.discord.com\u002Fdevelopers\u002Fplatform\u002Foauth2-and-permissions",[47],"Discord Dev Docs: OAuth2 and Permissions",[40,180,181],{},[43,182,184],{"href":100,"rel":183},[47],"Nuxt Auth Utils",[40,186,187],{},[43,188,190],{"href":125,"rel":189},[47],"LibSQL Client",[40,192,193],{},[43,194,137],{"href":195,"rel":196},"https:\u002F\u002Fturso.tech\u002F",[47],{"title":50,"searchDepth":51,"depth":51,"links":198},[199,200,201,202],{"id":82,"depth":51,"text":83},{"id":89,"depth":51,"text":90},{"id":159,"depth":51,"text":160},{"id":34,"depth":51,"text":35},{},"\u002Fnotes\u002Fdiscussion-system",{"title":74,"description":79},"notes\u002Fdiscussion-system",[208,209,210],"digital-garden","discussion","discord","qyg2hKIPOcftOtdTvypdxUt2VIDp4xQcSCwWrP4NHzg",{"id":213,"title":214,"body":215,"date":869,"description":219,"discussionStatus":148,"extension":57,"hasTldr":58,"meta":870,"navigation":60,"path":871,"seo":872,"stage":63,"stem":873,"tags":874,"__hash__":880},"notes\u002Fnotes\u002Fi-should-move-to-react.md","Should I Move to React?",{"type":8,"value":216,"toc":863},[217,220,224,229,839,843,859],[11,218,219],{},"It's been a while since the last time I used React. Sticking with Vue is good but I feel like I should try React again, we got some frameworks for it too like Next.js, Preact and Remix. Which one should I try? But I think I should try the library first before them. I found some guides to help me migrate from Vue to React. Vue feels more natural to me, React is a bit more declarative but I think that's the point of it, have more control of what you're writing.",[15,221,223],{"id":222},"translation-samples-from-vue-to-react","Translation samples from Vue to React",[225,226,228],"h3",{"id":227},"simple-counter-component","Simple counter component",[230,231,232,545],"comparison-table",{},[233,234,235],"template",{"v-slot:left":50},[236,237,242],"pre",{"className":238,"code":239,"filename":240,"language":241,"meta":50,"style":50},"language-vue shiki shiki-themes catppuccin-macchiato","\u003Cscript lang=\"ts\" setup>\nimport { ref } from 'vue';\nconst count = ref(0);\nfunction operation(op: 'add' | 'sub') {\n  if (op === 'add') count.value++;\n  else count.value--;\n}\n\u003C\u002Fscript>\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>{{ count }}\u003C\u002Fh1>\n    \u003Cbutton @click=\"operation('add')\">Add\u003C\u002Fbutton>\n    \u003Cbutton @click=\"operation('sub')\">Subtract\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","counter.vue","vue",[103,243,244,274,300,327,370,399,417,423,433,442,453,474,501,526,536],{"__ignoreMap":50},[245,246,249,253,257,261,264,268,271],"span",{"class":247,"line":248},"line",1,[245,250,252],{"class":251},"sXptk","\u003C",[245,254,256],{"class":255},"s57MT","script",[245,258,260],{"class":259},"swja1"," lang",[245,262,263],{"class":251},"=",[245,265,267],{"class":266},"sSZ1V","\"ts\"",[245,269,270],{"class":259}," setup",[245,272,273],{"class":251},">\n",[245,275,276,280,284,288,291,294,297],{"class":247,"line":51},[245,277,279],{"class":278},"sIF4r","import",[245,281,283],{"class":282},"slVFb"," {",[245,285,287],{"class":286},"sFaBz"," ref ",[245,289,290],{"class":282},"}",[245,292,293],{"class":278}," from",[245,295,296],{"class":266}," 'vue'",[245,298,299],{"class":282},";\n",[245,301,303,306,309,311,315,318,322,325],{"class":247,"line":302},3,[245,304,305],{"class":278},"const",[245,307,308],{"class":286}," count ",[245,310,263],{"class":251},[245,312,314],{"class":313},"siK8c"," ref",[245,316,317],{"class":286},"(",[245,319,321],{"class":320},"s7Qn8","0",[245,323,324],{"class":286},")",[245,326,299],{"class":282},[245,328,330,333,336,338,342,345,348,352,355,358,360,363,365,367],{"class":247,"line":329},4,[245,331,332],{"class":278},"function",[245,334,335],{"class":313}," operation",[245,337,317],{"class":282},[245,339,341],{"class":340},"skVQi","op",[245,343,344],{"class":251},":",[245,346,347],{"class":266}," '",[245,349,351],{"class":350},"sB-em","add",[245,353,354],{"class":266},"'",[245,356,357],{"class":251}," |",[245,359,347],{"class":266},[245,361,362],{"class":350},"sub",[245,364,354],{"class":266},[245,366,324],{"class":282},[245,368,369],{"class":282}," {\n",[245,371,373,376,379,382,385,388,391,394,397],{"class":247,"line":372},5,[245,374,375],{"class":278},"  if",[245,377,378],{"class":286}," (op ",[245,380,381],{"class":251},"===",[245,383,384],{"class":266}," 'add'",[245,386,387],{"class":286},") count",[245,389,390],{"class":251},".",[245,392,393],{"class":286},"value",[245,395,396],{"class":251},"++",[245,398,299],{"class":282},[245,400,402,405,408,410,412,415],{"class":247,"line":401},6,[245,403,404],{"class":278},"  else",[245,406,407],{"class":286}," count",[245,409,390],{"class":251},[245,411,393],{"class":286},[245,413,414],{"class":251},"--",[245,416,299],{"class":282},[245,418,420],{"class":247,"line":419},7,[245,421,422],{"class":282},"}\n",[245,424,426,429,431],{"class":247,"line":425},8,[245,427,428],{"class":251},"\u003C\u002F",[245,430,256],{"class":255},[245,432,273],{"class":251},[245,434,436,438,440],{"class":247,"line":435},9,[245,437,252],{"class":251},[245,439,233],{"class":255},[245,441,273],{"class":251},[245,443,445,448,451],{"class":247,"line":444},10,[245,446,447],{"class":251},"  \u003C",[245,449,450],{"class":255},"div",[245,452,273],{"class":251},[245,454,456,459,462,465,468,470,472],{"class":247,"line":455},11,[245,457,458],{"class":251},"    \u003C",[245,460,461],{"class":255},"h1",[245,463,464],{"class":251},">",[245,466,467],{"class":286},"{{ count }}",[245,469,428],{"class":251},[245,471,461],{"class":255},[245,473,273],{"class":251},[245,475,477,479,482,485,487,490,492,495,497,499],{"class":247,"line":476},12,[245,478,458],{"class":251},[245,480,481],{"class":255},"button",[245,483,484],{"class":259}," @click",[245,486,263],{"class":251},[245,488,489],{"class":266},"\"operation('add')\"",[245,491,464],{"class":251},[245,493,494],{"class":286},"Add",[245,496,428],{"class":251},[245,498,481],{"class":255},[245,500,273],{"class":251},[245,502,504,506,508,510,512,515,517,520,522,524],{"class":247,"line":503},13,[245,505,458],{"class":251},[245,507,481],{"class":255},[245,509,484],{"class":259},[245,511,263],{"class":251},[245,513,514],{"class":266},"\"operation('sub')\"",[245,516,464],{"class":251},[245,518,519],{"class":286},"Subtract",[245,521,428],{"class":251},[245,523,481],{"class":255},[245,525,273],{"class":251},[245,527,529,532,534],{"class":247,"line":528},14,[245,530,531],{"class":251},"  \u003C\u002F",[245,533,450],{"class":255},[245,535,273],{"class":251},[245,537,539,541,543],{"class":247,"line":538},15,[245,540,428],{"class":251},[245,542,233],{"class":255},[245,544,273],{"class":251},[233,546,547],{"v-slot:right":50},[236,548,553],{"className":549,"code":550,"filename":551,"language":552,"meta":50,"style":50},"language-tsx shiki shiki-themes catppuccin-macchiato","import { useState } from 'react';\nexport default function Counter() {\n  const [count, setCount] = useState(0);\n  function operation(op: 'add' | 'sub') {\n    if (op === 'add') setCount(count + 1);\n    else setCount(count - 1);\n  }\n  return (\n    \u003Cdiv>\n      \u003Ch1>{count}\u003C\u002Fh1>\n      \u003Cbutton onClick={() => operation('add')}>Add\u003C\u002Fbutton>\n      \u003Cbutton onClick={() => operation('sub')}>Subtract\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  )\n}\n","counter.tsx","tsx",[103,554,555,573,592,626,657,687,705,710,718,726,748,786,821,830,835],{"__ignoreMap":50},[245,556,557,559,561,564,566,568,571],{"class":247,"line":248},[245,558,279],{"class":278},[245,560,283],{"class":282},[245,562,563],{"class":286}," useState ",[245,565,290],{"class":282},[245,567,293],{"class":278},[245,569,570],{"class":266}," 'react'",[245,572,299],{"class":282},[245,574,575,578,581,584,587,590],{"class":247,"line":51},[245,576,577],{"class":278},"export",[245,579,580],{"class":278}," default",[245,582,583],{"class":278}," function",[245,585,586],{"class":313}," Counter",[245,588,589],{"class":282},"()",[245,591,369],{"class":282},[245,593,594,597,600,603,606,609,612,615,618,620,622,624],{"class":247,"line":302},[245,595,596],{"class":278},"  const",[245,598,599],{"class":282}," [",[245,601,602],{"class":320},"count",[245,604,605],{"class":282},",",[245,607,608],{"class":320}," setCount",[245,610,611],{"class":282},"]",[245,613,614],{"class":251}," =",[245,616,617],{"class":313}," useState",[245,619,317],{"class":286},[245,621,321],{"class":320},[245,623,324],{"class":286},[245,625,299],{"class":282},[245,627,628,631,633,635,637,639,641,643,645,647,649,651,653,655],{"class":247,"line":329},[245,629,630],{"class":278},"  function",[245,632,335],{"class":313},[245,634,317],{"class":282},[245,636,341],{"class":340},[245,638,344],{"class":251},[245,640,347],{"class":266},[245,642,351],{"class":350},[245,644,354],{"class":266},[245,646,357],{"class":251},[245,648,347],{"class":266},[245,650,362],{"class":350},[245,652,354],{"class":266},[245,654,324],{"class":282},[245,656,369],{"class":282},[245,658,659,662,664,666,668,671,674,677,680,683,685],{"class":247,"line":372},[245,660,661],{"class":278},"    if",[245,663,378],{"class":286},[245,665,381],{"class":251},[245,667,384],{"class":266},[245,669,670],{"class":286},") ",[245,672,673],{"class":313},"setCount",[245,675,676],{"class":286},"(count ",[245,678,679],{"class":251},"+",[245,681,682],{"class":320}," 1",[245,684,324],{"class":286},[245,686,299],{"class":282},[245,688,689,692,694,696,699,701,703],{"class":247,"line":401},[245,690,691],{"class":278},"    else",[245,693,608],{"class":313},[245,695,676],{"class":286},[245,697,698],{"class":251},"-",[245,700,682],{"class":320},[245,702,324],{"class":286},[245,704,299],{"class":282},[245,706,707],{"class":247,"line":419},[245,708,709],{"class":282},"  }\n",[245,711,712,715],{"class":247,"line":425},[245,713,714],{"class":278},"  return",[245,716,717],{"class":286}," (\n",[245,719,720,722,724],{"class":247,"line":435},[245,721,458],{"class":251},[245,723,450],{"class":255},[245,725,273],{"class":251},[245,727,728,731,733,735,738,740,742,744,746],{"class":247,"line":444},[245,729,730],{"class":251},"      \u003C",[245,732,461],{"class":255},[245,734,464],{"class":251},[245,736,737],{"class":282},"{",[245,739,602],{"class":286},[245,741,290],{"class":282},[245,743,428],{"class":251},[245,745,461],{"class":255},[245,747,273],{"class":251},[245,749,750,752,754,757,759,762,765,767,769,772,774,776,778,780,782,784],{"class":247,"line":455},[245,751,730],{"class":251},[245,753,481],{"class":255},[245,755,756],{"class":259}," onClick",[245,758,263],{"class":251},[245,760,761],{"class":282},"{()",[245,763,764],{"class":278}," =>",[245,766,335],{"class":313},[245,768,317],{"class":286},[245,770,771],{"class":266},"'add'",[245,773,324],{"class":286},[245,775,290],{"class":282},[245,777,464],{"class":251},[245,779,494],{"class":286},[245,781,428],{"class":251},[245,783,481],{"class":255},[245,785,273],{"class":251},[245,787,788,790,792,794,796,798,800,802,804,807,809,811,813,815,817,819],{"class":247,"line":476},[245,789,730],{"class":251},[245,791,481],{"class":255},[245,793,756],{"class":259},[245,795,263],{"class":251},[245,797,761],{"class":282},[245,799,764],{"class":278},[245,801,335],{"class":313},[245,803,317],{"class":286},[245,805,806],{"class":266},"'sub'",[245,808,324],{"class":286},[245,810,290],{"class":282},[245,812,464],{"class":251},[245,814,519],{"class":286},[245,816,428],{"class":251},[245,818,481],{"class":255},[245,820,273],{"class":251},[245,822,823,826,828],{"class":247,"line":503},[245,824,825],{"class":251},"    \u003C\u002F",[245,827,450],{"class":255},[245,829,273],{"class":251},[245,831,832],{"class":247,"line":528},[245,833,834],{"class":286},"  )\n",[245,836,837],{"class":247,"line":538},[245,838,422],{"class":282},[15,840,842],{"id":841},"guides","Guides",[37,844,845,852],{},[40,846,847],{},[43,848,851],{"href":849,"rel":850},"https:\u002F\u002Fwww.index.dev\u002Fblog\u002Fvue-to-react-migration-strategy",[47],"How to Migrate from Vue to React App: A Strategic Guide",[40,853,854],{},[43,855,858],{"href":856,"rel":857},"https:\u002F\u002Fmakersden.io\u002Fblog\u002Fmigrating-from-vuejs-to-reactjs-in-2025-cto-guide",[47],"Migrating from VueJS to ReactJS in 2025",[860,861,862],"style",{},"html pre.shiki code .sXptk, html code.shiki .sXptk{--shiki-default:#8BD5CA}html pre.shiki code .s57MT, html code.shiki .s57MT{--shiki-default:#8AADF4}html pre.shiki code .swja1, html code.shiki .swja1{--shiki-default:#EED49F}html pre.shiki code .sSZ1V, html code.shiki .sSZ1V{--shiki-default:#A6DA95}html pre.shiki code .sIF4r, html code.shiki .sIF4r{--shiki-default:#C6A0F6}html pre.shiki code .slVFb, html code.shiki .slVFb{--shiki-default:#939AB7}html pre.shiki code .sFaBz, html code.shiki .sFaBz{--shiki-default:#CAD3F5}html pre.shiki code .siK8c, html code.shiki .siK8c{--shiki-default:#8AADF4;--shiki-default-font-style:italic}html pre.shiki code .s7Qn8, html code.shiki .s7Qn8{--shiki-default:#F5A97F}html pre.shiki code .skVQi, html code.shiki .skVQi{--shiki-default:#EE99A0;--shiki-default-font-style:italic}html pre.shiki code .sB-em, html code.shiki .sB-em{--shiki-default:#A6DA95;--shiki-default-font-style:italic}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);}",{"title":50,"searchDepth":51,"depth":51,"links":864},[865,868],{"id":222,"depth":51,"text":223,"children":866},[867],{"id":227,"depth":302,"text":228},{"id":841,"depth":51,"text":842},"2026-07-03",{},"\u002Fnotes\u002Fi-should-move-to-react",{"title":214,"description":219},"notes\u002Fi-should-move-to-react",[875,876,877,878,879],"javascript","js-library","library","react","thoughts","Sv953NnqJ79EZNLzpOAP6dHXJ_muYFOuk0y6gCKnnsU",1783639936778]