Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

들어가며

note.project-record

시작하며

  • README.md에 써놓기에는 주저리 주저리 뒷썰같은 느낌.
  • 필요한 것만 들어가는 간결한 프로젝트와는 다른 뭔가가 필요했다.

시도

저장소 이름 짓는게 귀찮았다. gpt 무료버전을 사용해봤다.

project-log
retrospect
post-mortem
knowhow
lab-notes
dev-journey

여러가지가 나왔는데. retrospect / post-mortem는 왠지 끝나고 하는 느낌이라 도중에도 적는 느낌이 안나 제외.

일단 저장소 이름을 note.dev-journey 해서 한글 타이틀을 정하는데 study.dev-notes의 한글 타이틀이 넷평의 개발 노트 였다.

뭔가 dev도 중복되고 journey가 가지고있는 여행의 느낌이 맘에 안들었다. 그래서 한글 타이틀을 건조하게 넷평의 프로젝트 기록이라 먼저 정하고 영문 저장소 이름을 정했다. note.project-record

이모지도 정하고 싶었는데

  • 📄는 이미 study.에서 쓰고 있다
  • 📓도 note라서 생각했지만, 팬을 넣는게 좀 더 느낌이 있어 보인다.
  • 📝도 팬이 달려있어 고려해봤는데 종이장이 study.에서 쓰이는 거랑 겹친다.
  • ✒️ 펜촉을 써본적이 없지만. 뭔가 느낌이 있어 노트의 아이콘은 이걸로 하겠다.

언어코드 ko ! kr ??

어느날 다른 공부 노트쪽에 PR이 올라왔다. 그냥 한국이니까 kr썼는데

  • https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
    • kr - https://www.loc.gov/standards/iso639-2/php/langcodes-keyword.php?SearchType=iso_639_1&SearchTerm=kr
      • 나이지리아 카누리(Kanuri) 민족

아…. ko로 가야 맞는거구나… 여튼 어디서 유입이 되었는지 모르겠지만 PR이 와서 감사했다.

🎨 unity.webp

  • https://www.google.com/search?q=steamdb+%22unity.webp%22

🔑 unity.libsodium

💾 SqlCipher4Unity3D

https://github.com/sqlkata/querybuilder/

https://netpyoung.github.io/study.dotnet/dotnet/PInvoke.html 참고

NF.Tool.UnityPackage

시작하며

  • 유니티 패키지에 있는 파일들을 쉽게 확인하고 싶었다. (이미자, 사운드 등등)
  • 드레그 드랍으로 쉽게 만들고 싶었다.

결정

  • winform 아니면 WPF 아니면 Maui
    • 간단하게 만들거라 winform으로.
    • 나중에 크로스플렛폼이 되는 Maui로 하면 어떨까? 너무 무겁나?

unitypackage경로

ospath
winC:\Users{User}\AppData\Roaming\Unity\Asset Store-5.x
mac~/Library/Unity/Asset\ Store/
linux~/.local/share/unity3d/Asset Store-5.x/

기타

  • pack : yaml
  • unpack: tar/gzip

Ref

tar-cs https://code.google.com/archive/p/tar-cs/ https://learn.microsoft.com/ko-kr/dotnet/api/system.formats.tar.tarfile?view=net-8.0

unity yaml이 key:value쌍이 맞지 않는 것도 있음. YamlDotNet https://github.com/aaubry/YamlDotNet 에서 파싱 오류 - 엄격한 검사

https://github.com/TwoTenPvP/UnityPackager 기반

avaloniaui 한번 적용해봤으나 Winform버전은 800Kb 언더라면, avaloniaui로 40Mb 가 나옴.

https://github.com/icsharpcode/SharpZipLib SharpZipLib을 System.Formats.Tar - TarFile로 대채 YamlDotNet 파싱 오류도 있고, 어차피 guid만 얻어오는 부분만 쓰고 있어서 YamlDotNet을 걷어내니

  • 800kb가 200kb로 줄어듬

NF.Tool.ReleaseNoteMaker

시작하며

기록

라이브러리 결정

렌더템플릿 및 라이브러리 선택

visual studio에서 디버깅이 되는거에 가중치를 많이 줌.

  • t4
    • 디버깅 가능한걸로
    • mono t4 디버깅 꽤 괜찮네, 근데 string넘기는게 아니라 filepath라 찝찝
  • razor
    • 아직 관리가 되지 않는듯 : https://github.com/adoconnection/RazorEngineCore/pull/148
    • razor로도 template만들어 봤는데 의외로 t4보다 가시성이 안좋았다.
  • liquid
  • towncrier는 Jinja2
  • 일단 liquid를 넣긴 넣었는데 t4가 더 나아보여서 삭제할까 보류중 => 혹시나 다른 사람들이 쓰면 돌이키기 힘드니 빠른 삭제로 결정.
  • fluid / scriban / dotliquid
  • liquid를 지원했으나 whitespace관리가 어렵고 fluid에서 class의 method호출이 안되었다.
    • 안되서 {%- assign categoryIssues = category.GetAllIssues() -%}
    • 이렇게 함 {%- assign categoryIssues = category.CategoryIssues -%}

네이밍

  • towncrier

    • 다이나믹 언어 타입 및 네이밍 문제 - 저쪽 세상 네이밍 센스 맘에 안듬.
  • PatchNoteMaker 했는데… ReleaseNoteMaker 도 있는데…

    • PatchNoteMaker했다가 최종적으로 ReleaseNoteMaker로 결정.

기타

> [!NOTE]
> Information the user should notice even if skimming.

.tt vs .t4

  • 확장자를 .tt로 했다가 t4로 했다가 다시 tt로.
    • 처음에 찾아봤을때 t4 template가 어감에 감겨 찾아봤다가 .tt가 많이 쓰인다는 사실을 알고 .tt로 결정
    • 후에 까먹어서 왜 .tt야라고 생각하고 t4가 맘에 들어서 .t4로 변경
    • 후에 또 뭔가 쌔해서 다시 찾아보고 .tt로 롤백

잡다한

nf-tool-release-note-maker-vscode

  • https://marketplace.visualstudio.com/items?itemName=netpyoung.nf-tool-release-note-maker-vscode
  • https://github.com/netpyoung/nf-tool-release-note-maker-vscode

시작하며

참고

  • get-started/your-first-extension
  • yeoman
    • 템플릿 기반 프로젝트 생성기(스캐폴딩 도구)
  • npx --package yo --package generator-code -- yo code
    • yo, generator-code 패키지를 활용하면서 yo code 명령어 실행
  • microsoft/vscode-generator-code
    • 아직 bun을 지원안하네 https://github.com/microsoft/vscode-generator-code/pull/475
  • microsoft/vscode-vsce
    • @vscode/vsce
    • The Visual Studio Code Extension Manager
    • Access Token 생성 - https://azure.microsoft.com/services/devops/
    • Publisher 등록 - https://marketplace.visualstudio.com/manage/createpublisher
      • https://marketplace.visualstudio.com/VSCode > Publish extensions > Create Publisher

기록

배포

vsce package - 패키지 파일로 만듬 - 후 에 파일을 통해서 배포도 가능 vsce login vsce publish - 바로배포

  • publish대신 vsce package 로 패키지 파일을 사이트에서 수동 업로드.
    • 뭔가 마음이 놓인다.

네이밍 실수 nf-tools-release-note-maker-vscode => nf-tool-release-note-maker-vscode

  • 나는 툴에 대해 단수 tool을 썼는데 까먹고 복수형인 tools를 붙여버렸다.
  • nf-tools-release-note-maker-vscode - NF.Tool.ReleaseNoteMaker 이름이 안맞는 문제가 생겼는데,
    • vscode extension market에 올려져 있어 그냥 유지할까 생각도 했지만,
    • 인스톨횟수가 2회(내가 테스트용으로 한것)밖에 없고,
    • nuget과는 달리 삭제가 가능해서 과감히 삭제후 이름바꾸고 다시 마켓에 업로드
    • 처음 tools로 업로드 했을시에는 5분만에 Verifing이 끝나더니만, 이전 툴을 삭제하고 바로 tool로 올린 탓인지 1시간 정도 걸렸네

폴더구조를 바꾸려니 symbolic link가 필요하네

New-Item -ItemType SymbolicLink -Path “./nf-tools-release-note-maker-vscode/README.md” -Target “../README.md” New-Item -ItemType SymbolicLink -Path “./nf-tools-release-note-maker-vscode/LICENSE.md” -Target “../LICENSE.md” New-Item -ItemType SymbolicLink -Path “./nf-tools-release-note-maker-vscode/CHANGELOG.md” -Target “../CHANGELOG.md”

VSCode 멀티인풋을 하려면 webview가 필요하네

  • https://github.com/Microsoft/vscode-extension-samples/tree/main/webview-sample
  • framework가져다 쓸까하다가 그냥 gpt한테 심플하게 만들어달라고 해서 만듬
    • https://github.com/microsoft/vscode-webview-ui-toolkit - deprecated
    • https://vscode-elements.github.io/
    • https://github.com/vscode-elements/elements
    • https://fast.design/
    • https://lit.dev/

webview event

      <script>
        const vscode = acquireVsCodeApi();

        // 1) 버튼 클릭 시 확장으로 메시지 보내기
        document.getElementById('send').addEventListener('click', () => {
          vscode.postMessage({ command: 'alert', text: 'Hello from Webview!' });
        });

        // 2) 확장에서 온 메시지 받기
        window.addEventListener('message', event => {
          const message = event.data;
          switch (message.command) {
            case 'init':
              console.log('Message from extension:', message.data);
              break;
          }
        });
      </script>

기타

  • 흠 나중에 wasm파일 쓸 일 있으면 한번 여기서 테스트 해보고 싶네

  • activationEvents는 정적으로만 지정 가능 → configuration 기반 동적 활성화는 불가

  • 폴더에 파일이 존재하면 메뉴가 생겨서 우클릭해서 확인하고싶었지만, Explorer에서 폴더를 선택할 때마다 발생하는 이벤트는 없음

  • ReleaseNote.config.toml 우클릭 임시파일에 preview를 쓰고 마크다운 렌더

  • resourceFilename == ReleaseNote.config.toml

  • ReleaseNote.config.toml를 config쪽으로 빼야겠네

  • https://code.visualstudio.com/api/references/when-clause-contexts#inspect-context-keys-utility

bun add --global yo generator-code

yo code Hello2 --extensionType=ts --pkgManager=npm --skip-install --gitInit=true --bundler=esbuild --skipOpen



node_modules/@types/vscode/index.d.ts.

package.json
  "contributes": {
    "commands": [
      {
        "command": "helloworld.helloWorld",
        "title": "Hello World"
      }
    ]
  },
  
const disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
	vscode.window.showInformationMessage('Hello World!');
});

context.subscriptions.push(disposable);

"menus": {
  "explorer/context": [
	{
	  "command": "myExtension.processFolder",
	  "when": "explorerResourceIsFolder",
	  "group": "navigation"
	}
  ]
}
  • https://github.com/shd101wyy/markdown-preview-enhanced
  • https://github.com/dev-jonghoonpark/ettk-vscode-extention/
  • https://esbuild.github.io/
  • https://github.com/evanw/esbuild
  • https://bun.com/docs/bundler/esbuild
  • Error: Invalid problemMatcher reference: $esbuild-watch
    • https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers

.vscodeignore - VS Code 확장(VSIX) 배포용 필터 파일

.vscode/extensions.json “recommendations”: [“dbaeumer.vscode-eslint”, “connor4312.esbuild-problem-matchers”, “ms-vscode.extension-test-runner”]

when 조건식은 정적 컨텍스트키만 됨 https://code.visualstudio.com/api/references/when-clause-contexts

  • when 조건식 기반
  • setContext 기반 https://code.visualstudio.com/api/references/commands

resourceExtname

https://code.visualstudio.com/docs/languages/markdown

await vscode.commands.executeCommand(‘markdown.showPreviewToSide’, tmpUri);

await vscode.commands.executeCommand(‘markdown-preview-enhanced.openPreview’, doc.uri);

https://github.com/BetterThanTomorrow/joyride 도 있네

“activationEvents”: [“onStartupFinished”],

https://code.visualstudio.com/api/references/activation-events#workspaceContains

“activationEvents”: [ “workspaceContains:**/.editorconfig” ]

“activationCommands”: { “atom-workspace”: “markdown-preview-enhanced:toggle” }, “activationHooks”: [

https://code.visualstudio.com/api/references/contribution-points#contributes.menus https://code.visualstudio.com/api/references/contribution-points#contributes.submenus

https://github.com/microsoft/vscode-extension-samples 예제

DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.

"contributes": {
"commands": [
],
"menus": {
  "explorer/context": [
  ],
  "editor/context": [
  ]
}
}

— 설정

"contributes": {
  "configuration": {
    "title": "My Extension Settings",
    "properties": {
      "myExt.enableFeature": {
        "type": "boolean",
        "default": true,
        "description": "Enable or disable the special feature (토글)"
      },
      "myExt.customMessage": {
        "type": "string",
        "default": "Hello!",
        "description": "Set a custom message (문자열 입력)"
      }
    }
  }
}

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    const config = vscode.workspace.getConfiguration('myExt');

    const isEnabled = config.get<boolean>('enableFeature');
    const message = config.get<string>('customMessage');

    if (isEnabled) {
        vscode.window.showInformationMessage(`Feature is enabled! Message: ${message}`);
    }

    // 설정 변경 감지
    vscode.workspace.onDidChangeConfiguration(event => {
        if (event.affectsConfiguration('myExt.enableFeature') || event.affectsConfiguration('myExt.customMessage')) {
            const newConfig = vscode.workspace.getConfiguration('myExt');
            const newEnabled = newConfig.get<boolean>('enableFeature');
            const newMessage = newConfig.get<string>('customMessage');

            vscode.window.showInformationMessage(`Updated! Enabled: ${newEnabled}, Message: ${newMessage}`);
        }
    });
}

https://code.visualstudio.com/api/references/contribution-points#contributes.configuration

예제에선 값이 딕셔너리인데, id를 포함한 어레이로 바꾸면 트리형태로 추가됨 - https://github.com/dotnet/vscode-csharp/blob/main/package.json “configuration”: { “title”: “My Extension Settings”,

"configuration": [
  {
    "title": "My Extension Settings",
    "id": "a.a.a1",

https://github.com/qjebbs/vscode-plantuml https://github.com/BetterThanTomorrow/calva

Pulumi

await vscode.window.showQuickPick - 상단 선택 vscode.window.showInformationMessage - 우측 하단 yes, no

TODO

아이콘

https://code.visualstudio.com/api/references/extension-manifest

html을 그냥 문자열로 박아놨는데 뭔가 방법이 없을까?

https://medium.com/@sampsonjoliver/importing-html-files-from-typescript-bd1c50909992

🌶️ NF.Tool.ExcelFlow

  • https://github.com/netpyoung/nf.data-flow

    • assembly로드 하는것까지 했음
  • partial db 갱신도

    • excel을 winform에 드래그하면 그 엑셀에꺼만 갱신
  • Razor page

  • Attr지정

  • 클라랑 서버 데이터 분리

  • 타입지정

validate

  • table column 이름 중복 - 알려주기

???

  • unique id같은경우 알려주기?

템플릿은 T4로 C#함수를 쓸 수 있는

// sheet / enums / consts / class https://marketplace.visualstudio.com/items?itemName=bricelam.T4Language

const

CONST

TypeNameValueDesc
intn11hello

Enum

E_ENUM

NameValueDesc
n11hello
>n1hello

https://shd101wyy.github.io/markdown-preview-enhanced/#/markdown-basics?id=table

{ “markdown-preview-enhanced.enableExtendedTableSyntax”: true, }

셀 합치니까 멀티라인시 표가 안늘어나네? ‘AutoFit Row Height’ on merged cells

class

ATTR[PrimaryKey][Unique]
TYPEintint
NAMEidcharacter_id
DESC
VALUE11

tableroot/ Defines/ Const_1.xlsx Const_2.xlsx Enum_1.xlsx Enum_2.xlsx Hello/ Hello_1.xlsx Hello_2.xlsx

참조 상대경로로 해도 =‘[ComponentsC.xlsx]Sheet1’!A1 => 결국 절대경로로 되어버림

외부 파일과 참조 파일이 동시에 열려 있을 때만 상대경로 사용 가능 - INDIRECT / VLOOKUP https://stackoverflow.com/questions/11629633/how-do-i-make-a-relative-reference-to-another-workbook-in-excel

나중에 git 커밋마다 비교하면서 수정내역 알 수 있으면 좋겠네

  • 누가
  • 언제
  • 파일
  • 시트
  • 내용

NPOI는 수식평가 외부참조가 안됨

  • This workbook contains link to one or more external sources that could be unsafe.
    • File > Info > Edit Links to Files > 톱니바퀴 > Always Refresh

) https://excel-dna.net/

sqlite 추출 json 추출

#Comment ? $Comment $는 엑셀에서 자주쓰는것이므로 쓰지말자

&END ? :END

client - 클라 전용 server - 서버 전용 빈칸 - 둘다 공용

  • 같은 값으로 머지한것도 지원

  • 셀에 대한 Note기능은 활용하지 않는걸로

_ignore

[Unique] [PrimaryKey]

예제 Type id 다른시트 참조

Const / Enum / 클래스

클래스 상속 금지

https://iekill.tistory.com/41

  • https://github.com/catsnipe/XlsToJson

    • json/scriptableobject
  • https://github.com/cathei/BakingSheet

    • enum이랑 dictionary다루는게 신기했었는데 지금보면 별로인 접근방식
  • https://github.com/elky84/ExcelToDotnet **

  • https://github.com/qingfeng346/ScorpioConversion

    • bytes 二进制数据,支持 base64:// file:// https://github.com/kimsama/Unity-QuickSheet https://github.com/hnb-rabear/excel-to-unity
    • winform 툴
    • BouncyCastle.Crypto
    • BouncyCastle.Cryptography
    • markdig
  • https://github.com/MyNameIsDabin/TabbySheet

  • https://blog.naver.com/gamephysics/223825533965

  • https://github.com/NtreevSoft/Crema

    • https://github.com/s2quake/crema
    • https://github.com/MahApps/MahApps.Metro
    • https://github.com/Actipro/WPF-Controls
    • https://github.com/mmanela/diffplex
  • https://github.com/ExcelDataReader/ExcelDataReader

  • https://github.com/tonyqus/npoi

  • https://github.com/ClosedXML/ClosedXML

https://github.com/sveinungf/spreadcheetah

https://github.com/Cysharp/MasterMemory https://www.litedb.org/

https://github.com/zirplsoftware/ZCalcEngine https://github.com/pieterderycke/Jace https://github.com/soomin-kevin-sung/dotnet-calculation-engine

https://github.com/softlion/SQLite.Net-PCL2 - IBlobSerializer 지원

root/ /ByteFiles/image… /Sheets/

byte[] - byte:// - 이미지 같은거 string - text:// - 스크립트 같은거 string - base64:// string - base64url://

설정파일

  • regexp _스코어시작

_스코어 시작

int / float / byte[] / DateTime

시트

주석시트

List [1, 2, 3] Vector3 <1, 2, 3> TimeSpan? nullable

키prim /sub

3번째로 뒤엎는거다.

시트당 클래스/enum/const를 같이 묶으려했다

    // enum
    // - header: *NAME | *FIELD
    // - field: *NAME | *VALUE | DESC | ATTR

    // const
    // - header: *NAME | *FIELD
    // - field: *TYPE | *NAME | *VALUE | DESC | ATTR

    // class
    // - header: ?*NAME | *TYPE | PART | DESC | *TABLE

IFormulaEvaluator evaluator 검증

컴파일 Microsoft.CodeAnalysis.CSharp.Workspaces Microsoft.Build.Locator

https://learn.microsoft.com/ko-kr/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets

client/server assembly만들어서 sqlite에 삽입하니 충돌문제

  • 처음에는 어셈블리 중복로드 문제인가 싶어서 살펴봤지만
    • https://learn.microsoft.com/ko-kr/dotnet/standard/assembly/unloadability
  • 코드를 보니 sqlite.net내부에 타입 맵핑 태이블(_mapping)이 있는데 캐슁되어 있는 부분에서 문제가 발생. 클리어 함수가 노출되어 있지않아, 리플렉션으로 강제호출

TODO

  • 프로토콜 추가
    • file:// file path
    • proto:// json

NF.Tool.UnityCompileCache

레코드

  • IL2CPP로 빌드시 clang.exe로 컴파일이 시작됨. 컴파일 캐쉬를 사용할 수 있으면 시간 절약을 할 수 있을 것임.
    • 다만 유니티가 clang.exe를 실행하는데 어떻게 캐쉬 실행을 하느냐가 문제인데, wrapper에서 그냥 CreateProcess 호출하면 캐쉬가 오동작함.
    • 캐쉬 실행시 lpApplicationName과 lpCommandLine을 조절 해줘야함.

dotnet으로 nativeaot로 빠르게 wrapper작성해보고 dotnet은 아무래도 용량이 크니, c/cpp 생각해봤다가 딱히 내 프로젝트고 해서 zig로 작성.

참고

  • https://github.com/dotnet/runtime/blob/eeaef45074f577f35bfd1b6b02a029d4053a9683/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs#L588
    • dotnet에선 Interop.Kernel32.CreateProcess시 STARTUPINFO에 null을 넘겨주는것 밖에 없음.
    • lpCommandLine에서 argv[0]가 결정됨

nf.unitylibs.managers.assetbundlemanagement

nf.unitylibs.managers.patchmanagement

nf.unitylibs.managers.resourcesextra

시작하며

  • puerts를 가지고 놀다가 DefaultLoader에서 파일있는지 여부를 판별하는데서 UnityEngine.Resources.Load 사용함.
    • 이게 유니티가 Resources쪽 API는 놔버려서 로드를 해서 체크를 해야함.
    // https://github.com/Tencent/puerts/blob/f93907e9b6110497a2fc95827851b7e05ec1e2c9/unity/Assets/core/upm/Runtime/Src/Loader.cs#L96
    public bool FileExists(string filepath)
        bool exist = UnityEngine.Resources.Load(pathToUse) != null;
    

뭘할까

  • Resources가 여러 제약이 있긴해도 간편함때문에 버리지는 못하고 계속 써야하는데, 중복로드 / 의존성그래프 문제
    • Resources는 Assets/Resources/ => Resources.assets
    • Addressable의 로컬로드는 StreamingAssets를 사용
      • Assets/StreamingAssets =>StreamingAssets/
  • 일단 Resources.Load 없이 존재하는지 확인가능(런타임)하는 거랑
  • 정적분석으로 Resources.Load(“asdf”); // 이름 체크기능 - 코드짜면서 아날리시트 타임
    • 정적 분석이라 런타임 기능 함수를 가져다 쓸 수 없음
    • 정적 분석은 netpyoung/nf.unitylibs.utils를 만들면서 조금 깔딱거려봤음

삽질

  • Resources.IsExist 처럼 스태틱클래스를 확장시키고 싶었으나
    • 유니티는 C# 9까지 지원함.
    • 스태틱 클래스 확장은 C# 14 부터 지원
      • https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods#declare-extension-members | | | | ———————————————————————————————— | —————————————————————————————————————— | | AppContext.BaseDirectory; | C:\Program Files\Microsoft Visual Studio\18\Insiders\Common7\ServiceHub\Hosts\ServiceHub.Host.Extensibility.amd64\ | | typeof(ResourceLoadAnalyzer).Assembly.Location; | C:\Users\pyoung\AppData\Local\Temp\Roslyn\AnalyzerAssemblyLoader\4a41c1fd308e4a8b946ef9548f7a1c00\3\HelloHello.dll | | Assembly.GetExecutingAssembly().Location; | C:\Users\pyoung\AppData\Local\Temp\Roslyn\AnalyzerAssemblyLoader\f5def63c834c4efd803ba9f171794778\3\HelloHello.dll | | Environment.GetEnvironmentVariable(“MSBuildProjectFullPath”); | ‘’ | | Environment.GetEnvironmentVariable(“MSBuildProjectFullPath”, EnvironmentVariableTarget.Process); | ‘’ | | context.Node.SyntaxTree.FilePath; | C:\temp\unityProj\Assets\Scenes\NewMonoBehaviourScript.cs |

해킹

  • importer를 만들어서 __ResourceBlabla.txt 갱신

설정은

Ref

nf.unitytools.essentials

Sample.Dotnet.Nes

프로그래밍 언어관련 검색을 하다. 아 crystal언어가 지금 어떻게 되어가고 있지 생각이나서 검색중 블로그 글을 발견.

책을 알게 되었고 crystal언어와 SDL2로 구현되었으나, 개발 환경이 불편하고 include문을 써서 좀 코드 분석하기 불편하게 되어있어 dotnet과 SDL3 / Raylib로 구현해봄.

역시 dotnet이 visual studio가 좋아. 테스트도 잘 할 수 있고 손에 익어 바로바로 코드가 나옴. ruby가 좋아 crystal도 관심을 갖게되었는데, 책의 소스를 보다보니 점점 ruby계열 언어 아니 다른 gc언어에 대한 관심들이 떨어짐. gc언어는 그냥 dotnet 하나로 가는게 좋을듯.

그리고 다행인게 nesdev쪽 위키 가 정리가 잘 되어있어서 좋았고, 여러 youtube나 github에 참고할게 많아서 좋았음.

AMD Ryzen 7 5700g
dotnet --version 10.0.301

릴리즈는 nes기준 60프레임 맞춰서 나오는데, 디버그 빌드가 8프레임 정도밖에 안나온다. zig로 짜면 어떻게 되려나?

PPU랑 APU쪽이 빡셌음.

저 책이 아니였으면 손대볼 염두도 안났을것임. gameboy를 해볼까? 아니면 chip-8 에뮬로 가볍게 작업하고 심화로 chip-8타겟팅하는 롬을 만들 수 있도록?

일단 어찌어찌 완성시켰는데 심화해볼 수 있는것들도 남았고. 다시 관심을 가질때 다시 재미있게 가지고 놀 수 있을 프로젝트라 어느정도 1차 완성하고나서 나름 만족감을 느낄 수 있었음.

기타

구현하면서 Writing NES Emulator in Rust도 참고해서 봤는데, wiki링크가 과거 nesdev.com 기준으로 작성되었음. 사이트 분쟁이 있는지 현재는 nesdev.org로 접속이 되는데 nesdev.com 기준으로 작성된 문서/코드 주석들을 수정하는 PR을 남겼고 받아들여짐. 참고하면서 도움을 받았는데 조금이라도 도움을 줄 수 있어서 나름 만족.

Sample.Zig.Tunneler

record

zig 연습용 클론코딩. zig언어 보면서 뭔가 하나 해보고 싶었음. 스캔 돌리다가 tunneler가 기본 코드도 있고 sdl기반이라 간단해 보였음.

tunneler

  • https://tunneler.org/
    • by Geoffrey Silverton
  • SDL Tunneler v.1.1.1 - sdl 1.2.0
    • Taneli Kalvas
      • https://users.jyu.fi/~tvkalvas/
    • https://users.jyu.fi/~tvkalvas/code/tunneler/
    • https://github.com/guyromm/tunneler
  • Raymond Myers tunneltanks-0.4 - sdl 1.2.10
  • https://ditchers.sourceforge.net/
    • https://sourceforge.net/projects/ditchers/
  • https://app.zdechov.net/Tunneler/

TODO

  • https://tunneler.org/overview/#more-12
press any key

shoots fired
shoots hit
percent hit (shoots hit/shoots fired)%

meters dug
meters travelled

static library?

용량이 너무 커지는데

다음으로 참고용으로 메모해둠

  • https://osgameclones.com/?
    • https://github.com/opengaming/osgameclones
  • https://github.com/krystiankaluzny/Tanks

tetris ? - https://github.com/mmatyas/openblok

sdls - https://www.parallelrealities.co.uk/news/

  • f1spirit - https://f1spirit.jorito.net/

  • supermario - https://github.com/AnthonySturdy/SDL-Mario-Bros.

  • galaga

    • https://github.com/abdullahmaswadeh/galaga
    • https://github.com/frank-zago/xgalaga-sdl
  • tuxfootball - https://tuxfootball.sourceforge.net/index.php?plugin=EnticorePluginStaticContent&config=idx%3A3

  • noiz2sa

    • sdl ex - https://github.com/IoriBranford/noiz2sdl2
    • https://www.asahi-net.or.jp/~cs8k-cyu/windows/noiz2sa_e.html
  • road fighter

    • https://github.com/reybits/road-fighter
    • https://www.ugolnik.info/road-fighter/
    • https://github.com/OSSGames/GAME-SDL-SPORTS-Road_Fighter_Remake
  • 벽돌깨기

    • https://github.com/JoshuaCrotts/Brick-Breaker

elastomania - https://github.com/elastomania/elma-classic

  • xmoto
    • https://github.com/xmoto/xmoto
    • https://xmoto.org/
  • liero
    • https://www.liero.be/
    • https://github.com/gliptic/liero
    • https://github.com/albertz/openlierox
  • gusanos
    • https://github.com/wesz/gusanos
  • https://www.openlierox.net/
  • https://github.com/albertz/openlierox
  • https://github.com/david-vanderson/dvui

raylib ?

const c = @cImport({
    @cInclude("SDL3/SDL.h");
});
const std = @import("std");

pub fn main() !void {
    // 1. SDL 초기화
    if (!c.SDL_Init(c.SDL_INIT_VIDEO)) {
        std.debug.print("SDL 초기화 실패: {s}\n", .{c.SDL_GetError()});
        return error.SDLInitFailed;
    }
    defer c.SDL_Quit();

    // 2. 기본 디스플레이 ID 가져오기 (SDL3는 ID 기반)
    var count: i32 = 0;
    const displays = c.SDL_GetDisplays(&count);
    if (displays == null or count == 0) {
        std.debug.print("디스플레이를 찾을 수 없습니다.\n", .{});
        return;
    }
    const primary_display = displays[0];

    // 3. 해당 디스플레이의 전체화면 모드 목록 가져오기
    var mode_count: i32 = 0;
    // SDL3에서 SDL_GetFullscreenDisplayModes는 모드 포인터 배열을 반환합니다.
    const modes = c.SDL_GetFullscreenDisplayModes(primary_display, &mode_count);
    
    if (modes == null) {
        std.debug.print("모드 목록을 가져오는데 실패했습니다: {s}\n", .{c.SDL_GetError()});
        return;
    }
    defer c.SDL_free(@ptrCast(@constCast(modes))); // SDL3에서 할당한 메모리 해제

    std.debug.print("사용 가능한 모드 개수: {d}\n", .{mode_count});
    std.debug.print("---------------------------------\n", .{});

    // 4. 모드 순회 (Zig의 슬라이스 방식으로 접근 가능)
    const modes_slice = modes[0..@intCast(mode_count)];
    for (modes_slice) |mode_ptr| {
        const m = mode_ptr.*; // SDL_DisplayMode 구조체 역참조
        std.debug.print("{d} x {d} @ {d}Hz (픽셀 포맷: {d})\n", .{
            m.w, 
            m.h, 
            @as(i32, @intFromFloat(m.refresh_rate)), // refresh_rate는 float 타입
            m.format
        });
    }
}

http://netpyoung.github.io

  • 스프링노트 - 서비스 종료
  • 에버노트 - 익숙하지 않음
  • 티스토리 - 커스터마이즈 불편
  • 네이버 블로그 - 처음부터 고려대상 제외

그 당시 서비스가 없었음

  • 노션 - 에메한 포지션
  • 미디엄 - 구독유도 혐오

내용이 없는 이유

블로그 ? 개발 블로그 ? 고찰 부족. 블로그 보다 사이드프로젝트

생각중

  • zig로 된 zine은 어떨까?
    • 아직 성숙하지 않은거 같아 일단 보류
    • https://github.com/kristoff-it/zine

어떻게 구축 시작?

jekyll => zola

snippet

  • 검색창 - https://www.fusejs.io/demo.html
    • heyimalex/wafu- Rust port of Fuse.js
    • https://github.com/netpyoung/netpyoung.github.io/commit/8902af639842a67a4656e2066dac8440ec89fc3b
    • https://github.com/lispkorea/lispkorea.github.io/commit/04c68a1cb20e7e9f2902047c91bfb13d906834da

ADR

  • Architecture Decision Records (ADRs).

결론

컨셉자체는 괜찮은데 짜잘짜잘한거까지 하면 스트레스. 분쟁이 일어날시 팀장역활 중요.

시도

3명이서 해봤는데 adr 드라이븐을 강제해서 해봤다. 찬반으로 해서 결정하는건데 결정이 더 느리고 통과할때까지 문서만 바꾸느라 진도가 안나감.

Title: 제목
Decision: 결정
Issue:
Status: // proposed, accepted, rejected, deprecated, superseded
Expected Result: 예상결과 / Consequences 결과

버그노트
현상
추정
과정
원인
해결책

Ref:

변경내역을 깃 커밋 히스토리로 뽑는것에 대한.

결론

  • 결론은 반대. 자동으로 뽑는건 필요하지만, 커밋 기반으로 뽑는것은 아니다.
  • NF.Tool.ReleaseNoteMaker 를 쓰자

시도

  • git history를 기반으로 changelog를 생성하는 것은 툴도 많고, 깃 히스토리를 파싱해서 만들면 간단하게 만들 수 있을거 같아 만들어 볼까라는 생각을 가지고 있었다.
  • 주객전도
    • 그렇게 몇번 코드를 가지고 놀다가. history기반으로 작업을 하면 changelog를 예쁘게 뽑기위해 커밋을 수정해야하는 경우가 생기는 경우가 생긴다.
  • 불신
    • 플로우에 맞추어 커밋로그를 잘 남긴다는 나 스스로 혹은 다른 넘들을 믿을 수 가 없다.
  • 복잡성 증가
    • 나 역시 몇번 시도 해봤는데 커밋 메시지를 changelog를 생각하면서 남긴다는것 자체가 곤욕이다.

마크업 언어

결론

markdown이 간단해서 1픽으로 하고 만약 요구사항이 늘어난다면 그 다음으로는 asciidoc을 고려.

시도

markdown, asciidoc, reStructuredText, org 들을 써봤다.

fileextension
markdown.md
asciidoc.adoc / .asciidoc / .asc
reStructuredText.rst
org.org

복잡하고 잘 까먹는다. org는 에디터 특성을 탄다.

Ref

Serialization

  • protobuf

  • FlatBuffers

  • captin proto

  • message pack - https://github.com/Cysharp/MemoryPack

  • json

  • bson

  • BinaryPack - https://github.com/Sergio0694/BinaryPack

  • HyperSerializer - https://github.com/adam-dot-cohen/HyperSerializer

  • Apex.Serialization - https://github.com/dbolin/Apex.Serialization

  • https://docs.unity3d.com/Packages/com.unity.serialization@3.1/manual/index.html

Ref

템플릿 언어

결정

  • 디버깅때문이라도 t4쓰자.
  • razor는 웹전용으로만 쓰자.

시도

  • mustache / handlebars 는 문법이 간단한데 이걸 기반으로 템플릿을 작성해보면 더 개판남.
  • 비쥬얼스튜디오 T4 template / razor 가 디버깅이 잘됨
    • t4로 작성해도 <# #> 하다보면 너무 지저분해보임. 디버깅 되고 조금 더 깔끔한게 아직은 없다…
    • html이 아닌 문서 템플릿용도로 razor로 한번 써봤는데 t4보다 지저분해보임.
  • liquid 개인적으로 맘에드는데 디버깅이 안되네..

task runner

결론

  • just를 쓰자
    • 100프로 맘에 드는건 아니지만 일단.. 뭐… 대안이 별로…
  • 로직들어간건 그냥 dotnet으로
    • https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/

주저리

  • https://github.com/ruby/rake
  • https://github.com/pyinvoke/invoke
  • https://github.com/dotnet-script/dotnet-script

rake를 전에 좋아해서 시작함. `dir`같이 명령어 바로 실행시키는 것이 맘에듬. 하지만 라이브러리 사용도 그렇고 점점 코딩하는게 불편해짐. 대중적인 pyhton으로 invoke도 써봤지만 결국엔 ruby와 마찬가지로 코딩도 불편하고 프로젝트안에 알아야 하는 언어가 하나 더 추가되는 것일 뿐. 후에 dotnet-script로 사용하다가 file-based C# apps이 가능해지고선 복잡해진 로직은 .cs로 처리하는게…

다만 dotnet쪽에 태스크 런하는게 썩 괜찮은게 없어서 테스크 러너는 아싸리 just로..

Ref

  • https://github.com/bartdorlandt/Beyond_the_Makefile