<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Bjorvand</title>
    <description>The latest articles on DEV Community by Kevin Bjorvand (@kevinbjorv).</description>
    <link>https://dev.to/kevinbjorv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1755460%2F258fa6aa-4e53-46fc-b1c3-a98adac28882.jpg</url>
      <title>DEV Community: Kevin Bjorvand</title>
      <link>https://dev.to/kevinbjorv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevinbjorv"/>
    <language>en</language>
    <item>
      <title>Fail-closed accounting workflows: n8n, TypeScript, and a Conta pilot</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Thu, 17 Sep 2026 05:45:19 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/fail-closed-accounting-workflows-n8n-typescript-and-a-conta-pilot-50a9</link>
      <guid>https://dev.to/kevinbjorv/fail-closed-accounting-workflows-n8n-typescript-and-a-conta-pilot-50a9</guid>
      <description>&lt;p&gt;A workflow can finish successfully and still have no valid accounting conclusion. That distinction drives the design of this open-source Conta intercompany balance checker.&lt;/p&gt;

&lt;p&gt;The project combines n8n orchestration with deterministic TypeScript logic. It compares manually selected accounts for two companies and produces Norwegian HTML, CSV and JSON evidence for an accountant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current status:&lt;/strong&gt; this is a pilot. Synthetic tests and local self-hosted n8n tests have passed. Validation against reports from two authorized Conta companies and execution on n8n Cloud are still outstanding. Nothing below establishes a production-ready integration or a completed reconciliation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate data completeness from balance agreement
&lt;/h2&gt;

&lt;p&gt;Consider two synthetic companies:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signed NOK balance&lt;/th&gt;
&lt;th&gt;Company A&lt;/th&gt;
&lt;th&gt;Company B&lt;/th&gt;
&lt;th&gt;A + B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Opening&lt;/td&gt;
&lt;td&gt;100,000&lt;/td&gt;
&lt;td&gt;-85,000&lt;/td&gt;
&lt;td&gt;15,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Period movement&lt;/td&gt;
&lt;td&gt;150,000&lt;/td&gt;
&lt;td&gt;-140,000&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Closing&lt;/td&gt;
&lt;td&gt;250,000&lt;/td&gt;
&lt;td&gt;-225,000&lt;/td&gt;
&lt;td&gt;25,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The closing difference is NOK 25,000, but NOK 15,000 was already present at the start of the month. Reporting the entire difference as something caused this month would be misleading.&lt;/p&gt;

&lt;p&gt;The comparison uses signed balances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;closing residual = closing balance A + closing balance B
opening residual + movement residual = closing residual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Taking absolute values before comparing would lose the distinction between a receivable and a payable.&lt;/p&gt;

&lt;p&gt;The report exposes two separate decisions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data status&lt;/th&gt;
&lt;th&gt;Balance status&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;COMPLETE&lt;/td&gt;
&lt;td&gt;BALANCES_AGREE&lt;/td&gt;
&lt;td&gt;Required checks passed; residual is within tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COMPLETE&lt;/td&gt;
&lt;td&gt;DIFFERENCE&lt;/td&gt;
&lt;td&gt;Required checks passed; residual exceeds tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INCOMPLETE&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;There is insufficient evidence for a balance conclusion.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An absent account, failed request or malformed response must never become a zero balance. Even COMPLETE plus BALANCES_AGREE does not prove that all transactions were recorded or that an accountant approved the reconciliation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep orchestration and accounting logic separate
&lt;/h2&gt;

&lt;p&gt;n8n handles requests, branching, bounded retries and scheduling. TypeScript handles scope validation, response adaptation, exact arithmetic, candidate suggestions and report rendering.&lt;/p&gt;

&lt;p&gt;The TypeScript modules are bundled into JavaScript Code nodes. The shipped workflows require no runtime npm imports or separate backend.&lt;/p&gt;

&lt;p&gt;For each run, the request sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve each company's account list and initial trial balance.&lt;/li&gt;
&lt;li&gt;Retrieve ledger details for every selected account on both sides.&lt;/li&gt;
&lt;li&gt;Retrieve both trial balances again.&lt;/li&gt;
&lt;li&gt;Check each account's opening + movement = closing, detail sum = movement, and unchanged selected totals across the two retrievals.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final retrieval catches some changes during collection. It is not an atomic snapshot: offsetting edits that leave totals unchanged can still escape that check.&lt;/p&gt;

&lt;p&gt;Account ownership is an explicit configuration boundary. An accountant must approve dedicated accounts for the relationship. The workflow does not infer counterparties from amounts or descriptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preserve precision before calculating anything
&lt;/h2&gt;

&lt;p&gt;The local n8n HTTP-node tests exposed a transport issue: text response mode parsed JSON internally and rounded a 64-bit source ID. Converting that rounded value to a string later cannot restore the missing digits.&lt;/p&gt;

&lt;p&gt;The tested configuration therefore receives the response as a file, then decodes its raw bytes inside a Code node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBinaryDataBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Pass this text to the token-preserving parser before mapping values.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project's parser preserves numeric JSON tokens as strings for authoritative decoding. Its implementation and limits are visible in &lt;a href="https://github.com/KevinBjorv/conta-intercompany-checker/blob/039d2efb30d974f99daee0dc7ae029cd62440042/src/transport.ts" rel="noopener noreferrer"&gt;transport.ts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Money is converted from validated decimal strings to integer øre with &lt;code&gt;BigInt&lt;/code&gt;; one NOK is 100 øre. Values cross JSON boundaries as decimal strings. Exponent notation and amounts with more than two fractional digits are rejected instead of silently rounded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;closingA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="nx"&gt;_000_000n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// NOK 250,000.00&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;closingB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="nx"&gt;_500_000n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// NOK -225,000.00&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;residual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;closingA&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;closingB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 2_500_000n øre = NOK 25,000.00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The runtime also exposed a bundling constraint: the hardened n8n runner rejected export helpers using &lt;code&gt;Object.defineProperty&lt;/code&gt;. The build now emits a plain bundled object, and a regression test exercises that restriction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat failure paths as report behavior
&lt;/h2&gt;

&lt;p&gt;The request loop allows at most three attempts per request. It honors Retry-After seconds and HTTP dates. An excessive wait stops the run instead of retrying earlier than the server requested. Authentication failures and redirects do not retry.&lt;/p&gt;

&lt;p&gt;All Conta requests are GET-only and restricted to the configured Conta gateway and endpoint paths. Credentials stay in n8n credentials. This restriction does &lt;strong&gt;not&lt;/strong&gt; make the API key itself read-only: Conta keys inherit their user's privileges.&lt;/p&gt;

&lt;p&gt;An INCOMPLETE report can be the output of a successful n8n execution. Operators must inspect both the execution status and the report status. A missing report after a host or runner failure is also not a valid result.&lt;/p&gt;

&lt;p&gt;Ledger candidates are conservative. Suggestions require an explicitly confirmed shared invoice reference, uniqueness on each side, opposite equal amounts and dates within the configured window. Local voucher IDs are not shared matching keys. Duplicates, split settlements, reversals and corrections remain review items.&lt;/p&gt;

&lt;h2&gt;
  
  
  What has actually been tested
&lt;/h2&gt;

&lt;p&gt;As of September 17, 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;53 deterministic accounting/workflow tests passed.&lt;/li&gt;
&lt;li&gt;17 scenarios passed through actual self-hosted n8n 2.39.6 execution on Windows with Node 24.13.1, synthetic credentials and a loopback fixture server.&lt;/li&gt;
&lt;li&gt;Those scenarios covered both credential branches, multiple accounts, Retry-After seconds/date, exhausted retries, three real 30-second timeouts, 401/403 responses, malformed and empty bodies, missing accounts, inconsistent movements, changing balances, large IDs and redirects.&lt;/li&gt;
&lt;li&gt;A real local Schedule Trigger generated a saved synthetic report; HTML, CSV and JSON were read back from execution storage.&lt;/li&gt;
&lt;li&gt;n8n's automatic pruning removed a disposable copy of that execution and its inline reports. This did not test Cloud retention, external binary stores, backups or physical secure erasure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://github.com/KevinBjorv/conta-intercompany-checker/blob/039d2efb30d974f99daee0dc7ae029cd62440042/release/n8n-smoke-results.json" rel="noopener noreferrer"&gt;runtime record&lt;/a&gt; includes workflow hashes and separates execution success from report completeness.&lt;/p&gt;

&lt;p&gt;These tests establish the behavior of the tested implementation and fixtures. They do not establish Conta's live date, omission or correction semantics. Those checks remain explicit release gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce the synthetic example
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/KevinBjorv/conta-intercompany-checker" rel="noopener noreferrer"&gt;MIT-licensed repository&lt;/a&gt; contains the modules, fixtures, tests and inactive workflow exports.&lt;/p&gt;

&lt;p&gt;With Node 22.18 or newer, run the local deterministic checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/KevinBjorv/conta-intercompany-checker.git
&lt;span class="nb"&gt;cd &lt;/span&gt;conta-intercompany-checker
npm ci
npm run check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To try the n8n demo, import &lt;code&gt;workflows/conta-synthetic-demo.json&lt;/code&gt;, run &lt;strong&gt;Manual demo&lt;/strong&gt;, and download the three files from &lt;strong&gt;Private reports&lt;/strong&gt;. That workflow makes no network requests and needs no credentials.&lt;/p&gt;

&lt;p&gt;The fixed example contains 20 lines, a NOK 25,000 closing residual, nine candidate pairs and two unresolved lines. You can inspect the &lt;a href="https://bjorvand.ai/workflow-assets/conta-intercompany/rapport.html" rel="noopener noreferrer"&gt;Norwegian sample report&lt;/a&gt; or the &lt;a href="https://bjorvand.ai/workflow-assets/conta-intercompany/conta-demonstrasjon.mp4" rel="noopener noreferrer"&gt;90-second silent Norwegian demonstration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The separate live template stays inactive and reports INCOMPLETE until its operator has documented the required report validation. Balance agreement remains evidence for review, never automatic accountant approval.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;AI disclosure:&lt;/strong&gt; This article was written by an AI assistant from the project's source code and recorded test evidence. All company examples are synthetic. The checker itself uses deterministic accounting logic, not an LLM.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>n8n</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Checking Xero supplier statements with n8n and deterministic TypeScript</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Wed, 16 Sep 2026 13:23:33 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/checking-xero-supplier-statements-with-n8n-and-deterministic-typescript-29h</link>
      <guid>https://dev.to/kevinbjorv/checking-xero-supplier-statements-with-n8n-and-deterministic-typescript-29h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Forlij37lq8g08loj8vn8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Forlij37lq8g08loj8vn8.jpg" alt="Xero Supplier Statement Checker: read-only n8n workflow by Bjorvand AI" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A reference match is not the same thing as a safe amount comparison. A supplier statement might show the invoice's original total, the remaining balance after a payment, or an unclear amount column. Treating all three as the same value can produce a convincing report with the wrong conclusion.&lt;/p&gt;

&lt;p&gt;The open-source &lt;strong&gt;Xero Supplier Statement Checker&lt;/strong&gt; uses n8n for orchestration and TypeScript for deterministic checking. This article explains three choices behind it: explicit amount meanings, complete retrieval and evidence-preserving operator review.&lt;/p&gt;

&lt;p&gt;The project is a preview. Synthetic tests and local n8n runs have passed; live Xero and n8n Cloud verification are still pending. All examples here are fictional.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Separate references from amounts
&lt;/h2&gt;

&lt;p&gt;The operator selects a supplier from the configured Xero organization's contacts. The checker only considers bills within that supplier and currency. It normalizes references using Unicode NFC, outer-whitespace trimming and ASCII case changes. It preserves punctuation, internal spaces and leading zeros.&lt;/p&gt;

&lt;p&gt;It does not use amounts, dates or fuzzy similarity to establish a match. Xero's purchase-bill &lt;code&gt;InvoiceNumber&lt;/code&gt; is the primary reference; the separate &lt;code&gt;Reference&lt;/code&gt; field is supporting evidence. Multiple candidates stay visible for review.&lt;/p&gt;

&lt;p&gt;Only after one eligible reference candidate exists can the checker compare tax-inclusive original totals. The checked-in fixture includes these two cases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reference&lt;/th&gt;
&lt;th&gt;Statement&lt;/th&gt;
&lt;th&gt;Xero&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;INV-101&lt;/td&gt;
&lt;td&gt;Original 250.00 GBP&lt;/td&gt;
&lt;td&gt;Original 245.00 GBP&lt;/td&gt;
&lt;td&gt;Amount difference: 5.00 GBP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INV-107&lt;/td&gt;
&lt;td&gt;Outstanding 45.00 GBP, no original total&lt;/td&gt;
&lt;td&gt;Reference candidate found&lt;/td&gt;
&lt;td&gt;Review required; no automatic comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Public contracts keep monetary values as decimal strings. Calculations use integer minor units, based on a checked-in currency table. Excess non-zero fractional digits are flagged instead of silently rounded. Xero JSON is parsed losslessly before converting its numeric values.&lt;/p&gt;

&lt;p&gt;Credits, partial payments, duplicate statement references and unsafe bill statuses also require review. A fully paid bill can still match its original total; the report displays its current paid status separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. A later failed page invalidates the retrieval
&lt;/h2&gt;

&lt;p&gt;"Not found" is a statement about the searched data. If page one succeeds and page two fails, there is no sound basis for declaring an invoice absent.&lt;/p&gt;

&lt;p&gt;The workflow uses HTTP Request nodes outside the Code nodes, sequential pages and explicit page sizes. It records requested pages, returned IDs, counts and the retrieval interval. The checking interface validates that evidence rather than trusting a caller's &lt;code&gt;success: true&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;Repeated pages, duplicate IDs, inconsistent counts, missing pages, malformed responses or exhausted retries stop the check. Rate limits use the provider's &lt;code&gt;Retry-After&lt;/code&gt; delay within a bounded retry policy. There is no date lookback or outstanding-balance filter that quietly omits old or paid bills.&lt;/p&gt;

&lt;p&gt;The interrupted-retrieval fixture fails on page two with a 401. Its report has zero matches, zero amount differences and zero not-found conclusions. Available statement rows remain review-required, and no follow-up draft is produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Let AI extract; keep the operator and rules in control
&lt;/h2&gt;

&lt;p&gt;CSV uses no AI. The operator maps columns and explicitly identifies original totals and outstanding balances. Invoice references stay strings, including leading zeros, and quoted multiline fields retain their source record numbers.&lt;/p&gt;

&lt;p&gt;For optional text-PDF extraction, n8n extracts pages separately. The code assigns page numbers and verifies page coverage. OpenAI receives page-labelled text with a strict output schema, no tools and &lt;code&gt;store: false&lt;/code&gt;. Returned evidence excerpts must exist in the supplied page text. Xero bill data is not included in that request.&lt;/p&gt;

&lt;p&gt;The review form shows extracted rows, source references and warnings. Operators can correct a canonical CSV representation and must confirm supplier, currency, amount meanings and statement coverage. Initial extraction and corrections stay in the evidence. The AI never chooses a supplier or decides a match.&lt;/p&gt;

&lt;p&gt;This does not eliminate extraction risk. Scanned, encrypted or partly unreadable PDFs are rejected, and the operator must check the original document for omitted rows. Provider retention is separate from the &lt;code&gt;store: false&lt;/code&gt; setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the synthetic example
&lt;/h2&gt;

&lt;p&gt;With Node.js 24 or later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/KevinBjorv/xero-supplier-statement-checker.git
&lt;span class="nb"&gt;cd &lt;/span&gt;xero-supplier-statement-checker
npm ci
npm run demo
npm run check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;output/demo/report.html&lt;/code&gt;. The ten-line fixture produces two matched rows, one amount difference, one not found and six requiring review. No credentials are needed. The repository also includes an importable n8n synthetic form workflow.&lt;/p&gt;

&lt;p&gt;The downloadable ZIP contains HTML, CSV and JSON, plus an optional unsent draft. HTML is escaped; CSV formula-like values are protected; exact originals remain in JSON. Limits stop processing at 10 MiB, 50 PDF pages or 1,000 rows rather than truncating data.&lt;/p&gt;

&lt;p&gt;The checker supports statement review. It does not reconcile supplier balances, convert currencies, post accounting entries or send email. A current Xero fetch is not a historical or atomic snapshot at the statement date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source and implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/KevinBjorv/xero-supplier-statement-checker" rel="noopener noreferrer"&gt;MIT source, fixtures, tests and verification status&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bjorvand.ai/en/workflows/xero-supplier-statement-checker?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=xero_statement_checker" rel="noopener noreferrer"&gt;See the sample report and implementation options at Bjorvand AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: this is a Bjorvand AI project. The workflow is free; installation and customization are separate paid services. This article was prepared with AI assistance and checked against the source and synthetic fixture results.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>automation</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Automatically Generate Third-Party Notices in Unity</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Tue, 10 Mar 2026 14:54:41 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/automatically-generate-third-party-notices-in-unity-25gm</link>
      <guid>https://dev.to/kevinbjorv/automatically-generate-third-party-notices-in-unity-25gm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1is232e1xordqeg4u87v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1is232e1xordqeg4u87v.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;# Automatically Generate Third-Party Notices in Unity&lt;/p&gt;

&lt;h3&gt;
  
  
  A simple way to stay compliant when shipping games
&lt;/h3&gt;

&lt;p&gt;If you ship games using Unity, you are almost certainly using &lt;strong&gt;third-party software&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asset Store packages
&lt;/li&gt;
&lt;li&gt;open-source libraries
&lt;/li&gt;
&lt;li&gt;plugins or SDKs
&lt;/li&gt;
&lt;li&gt;copied utility scripts
&lt;/li&gt;
&lt;li&gt;packages from GitHub
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these may come with &lt;strong&gt;license requirements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many licenses require that you include a &lt;strong&gt;Third-Party Notices file&lt;/strong&gt; or credit the authors somewhere in your build.&lt;/p&gt;

&lt;p&gt;The problem is that this step is often overlooked.&lt;/p&gt;

&lt;p&gt;Not because developers want to ignore licenses, but because tracking every dependency manually becomes difficult as projects grow.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why third-party notices matter
&lt;/h1&gt;

&lt;p&gt;Many open-source licenses require attribution.&lt;/p&gt;

&lt;p&gt;Common licenses such as MIT, BSD, and Apache typically require that the license text and copyright notice are included when distributing software.&lt;/p&gt;

&lt;p&gt;In practice this usually means adding a file such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;THIRD_PARTY_NOTICES.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or including license credits somewhere accessible in your application.&lt;/p&gt;

&lt;p&gt;If those notices are missing, your distribution may technically violate the license terms.&lt;/p&gt;

&lt;p&gt;For most indie developers this is not intentional. It simply happens because dependencies accumulate over time.&lt;/p&gt;




&lt;h1&gt;
  
  
  The hidden complexity of Unity projects
&lt;/h1&gt;

&lt;p&gt;Unity projects often pull in dependencies from several sources.&lt;/p&gt;

&lt;p&gt;A typical project may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asset Store packages
&lt;/li&gt;
&lt;li&gt;UPM packages
&lt;/li&gt;
&lt;li&gt;plugins bundled with assets
&lt;/li&gt;
&lt;li&gt;third-party SDKs
&lt;/li&gt;
&lt;li&gt;custom scripts copied from repositories
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these may contain its own licenses.&lt;/p&gt;

&lt;p&gt;Because many assets include their dependencies internally, developers may not even realize which libraries are being used.&lt;/p&gt;

&lt;p&gt;By the time a game is ready to ship, the project might contain &lt;strong&gt;dozens of different licenses&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Trying to manually audit these files can take hours.&lt;/p&gt;




&lt;h1&gt;
  
  
  A common late-stage problem
&lt;/h1&gt;

&lt;p&gt;Many teams only think about licenses right before release.&lt;/p&gt;

&lt;p&gt;At that point the questions start appearing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What open-source libraries are included in this project?
&lt;/li&gt;
&lt;li&gt;Which licenses require attribution?
&lt;/li&gt;
&lt;li&gt;Where should the notices file be generated?
&lt;/li&gt;
&lt;li&gt;Did we miss anything?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately this usually happens during the &lt;strong&gt;final release phase&lt;/strong&gt;, when developers are already dealing with builds, store submissions, and bug fixes.&lt;/p&gt;

&lt;p&gt;Compliance work becomes another unexpected task at the worst possible moment.&lt;/p&gt;




&lt;h1&gt;
  
  
  Introducing Third-Party Notices Generator
&lt;/h1&gt;

&lt;p&gt;To simplify this process I built a small Unity editor tool called &lt;strong&gt;Third-Party Notices Generator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is straightforward.&lt;/p&gt;

&lt;p&gt;Instead of manually searching through packages and asset folders, the tool scans your project and generates a structured notices file automatically.&lt;/p&gt;

&lt;p&gt;This provides a clear overview of third-party licenses used in the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  How the workflow works
&lt;/h1&gt;

&lt;p&gt;The process is intentionally simple.&lt;/p&gt;

&lt;p&gt;You open the tool inside the Unity editor and run a project scan.&lt;/p&gt;

&lt;p&gt;The tool looks through project dependencies and identifies license information where available.&lt;/p&gt;

&lt;p&gt;It then generates output files that can be included directly in your project.&lt;/p&gt;

&lt;p&gt;Typical outputs include files such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;THIRD_PARTY_NOTICES.txt&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CREDITS.md&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;structured manifests for documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These files provide a clear list of dependencies and their associated license information.&lt;/p&gt;

&lt;p&gt;Because the files are deterministic, they can also be tracked in version control.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why automated license tracking helps
&lt;/h1&gt;

&lt;p&gt;Automating license notices has several benefits.&lt;/p&gt;

&lt;p&gt;First, it reduces the chance that dependencies will be forgotten during release.&lt;/p&gt;

&lt;p&gt;Second, it makes compliance work faster. Instead of manually reading every license file, developers can generate a structured list automatically.&lt;/p&gt;

&lt;p&gt;Third, it makes updates easier. When new packages are added to the project, the notices file can simply be regenerated.&lt;/p&gt;

&lt;p&gt;This keeps the project documentation accurate over time.&lt;/p&gt;




&lt;h1&gt;
  
  
  When developers should think about license compliance
&lt;/h1&gt;

&lt;p&gt;License compliance is usually not the most exciting part of development.&lt;/p&gt;

&lt;p&gt;But it becomes important when projects reach the stage where they are distributed publicly.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Steam releases
&lt;/li&gt;
&lt;li&gt;mobile store submissions
&lt;/li&gt;
&lt;li&gt;web builds
&lt;/li&gt;
&lt;li&gt;open-source project distribution
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point it is useful to have a clear record of which third-party components are included in the project.&lt;/p&gt;

&lt;p&gt;Having that information organized early can prevent unnecessary stress close to release.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;Modern game development relies heavily on shared tools, libraries, and open-source software.&lt;/p&gt;

&lt;p&gt;That ecosystem allows developers to build games faster than ever before.&lt;/p&gt;

&lt;p&gt;But it also means that projects often contain many different licenses.&lt;/p&gt;

&lt;p&gt;Keeping track of those dependencies manually can become tedious.&lt;/p&gt;

&lt;p&gt;Automating the process with tools like &lt;strong&gt;&lt;a href="https://assetstore.unity.com/packages/slug/358432" rel="noopener noreferrer"&gt;Third-Party Notices Generator&lt;/a&gt;&lt;/strong&gt; makes it easier to stay organized and compliant when shipping games.&lt;/p&gt;

&lt;p&gt;Sometimes the most useful tools are the ones that quietly take care of the small but important details behind the scenes.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>game</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Stop Unity Build Size Regressions Before They Ship</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Wed, 18 Feb 2026 20:52:03 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/stop-unity-build-size-regressions-before-they-ship-olg</link>
      <guid>https://dev.to/kevinbjorv/stop-unity-build-size-regressions-before-they-ship-olg</guid>
      <description>&lt;p&gt;Unity build size rarely explodes overnight. It grows slowly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A few new 4K textures
&lt;/li&gt;
&lt;li&gt;An uncompressed audio file
&lt;/li&gt;
&lt;li&gt;A plugin update
&lt;/li&gt;
&lt;li&gt;An Addressables change
&lt;/li&gt;
&lt;li&gt;A scene pulling unintended dependencies
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then one day your APK, AAB, or build folder is 120 MB larger and no one knows why.&lt;/p&gt;

&lt;p&gt;The real problem is not build size.&lt;br&gt;&lt;br&gt;
It is lack of &lt;strong&gt;regression control&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Question You Should Be Asking
&lt;/h2&gt;

&lt;p&gt;Most developers ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What is my build size right now?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The correct question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What changed compared to my last good build?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You cannot answer that without structured snapshots and deterministic diffs.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Practical System for Controlling Unity Build Size
&lt;/h2&gt;

&lt;p&gt;To prevent regressions, you need three things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Automatic Build Snapshots
&lt;/h3&gt;

&lt;p&gt;Every successful build should record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build target (Android, iOS, Windows)&lt;/li&gt;
&lt;li&gt;Total build size&lt;/li&gt;
&lt;li&gt;Contributor breakdown&lt;/li&gt;
&lt;li&gt;Category grouping (textures, audio, meshes, shaders, plugins)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Store this as JSON so it works with version control and CI artifacts.&lt;/p&gt;

&lt;p&gt;No snapshot = no baseline.&lt;br&gt;&lt;br&gt;
No baseline = no regression detection.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Deterministic Snapshot Comparison
&lt;/h3&gt;

&lt;p&gt;When a build grows, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total delta in bytes and percent&lt;/li&gt;
&lt;li&gt;Top increases&lt;/li&gt;
&lt;li&gt;Top decreases&lt;/li&gt;
&lt;li&gt;New assets&lt;/li&gt;
&lt;li&gt;Removed assets&lt;/li&gt;
&lt;li&gt;Category distribution shifts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives you immediate root cause visibility instead of guesswork.&lt;/p&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;+42 MB textures
&lt;/li&gt;
&lt;li&gt;+18 MB new Addressables bundle
&lt;/li&gt;
&lt;li&gt;+9 MB plugin update
&lt;/li&gt;
&lt;li&gt;+6 MB scene dependency pull
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you are debugging facts.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Enforced Size Budgets
&lt;/h3&gt;

&lt;p&gt;Visibility is not enough.&lt;/p&gt;

&lt;p&gt;You should define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum total build size per platform
&lt;/li&gt;
&lt;li&gt;Maximum allowed regression vs baseline
&lt;/li&gt;
&lt;li&gt;Optional category budgets
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If violated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local builds warn or fail
&lt;/li&gt;
&lt;li&gt;CI exits non-zero
&lt;/li&gt;
&lt;li&gt;A clear report explains what exceeded and by how much
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns build size into a hard constraint instead of a suggestion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why CI Enforcement Matters
&lt;/h2&gt;

&lt;p&gt;Manual review fails at scale.&lt;/p&gt;

&lt;p&gt;In real projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple branches ship in parallel
&lt;/li&gt;
&lt;li&gt;Different team members commit large assets
&lt;/li&gt;
&lt;li&gt;Nightly builds accumulate silent growth
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A proper batchmode workflow should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load a baseline snapshot
&lt;/li&gt;
&lt;li&gt;Compare against current
&lt;/li&gt;
&lt;li&gt;Evaluate budgets
&lt;/li&gt;
&lt;li&gt;Print a human-readable summary
&lt;/li&gt;
&lt;li&gt;Output JSON for automation
&lt;/li&gt;
&lt;li&gt;Return a non-zero exit code on failure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is how you prevent accidental regressions from reaching production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Build Size Guard
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Build Size Guard&lt;/strong&gt; specifically for regression control, not just reporting.&lt;/p&gt;

&lt;p&gt;It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically records build size snapshots
&lt;/li&gt;
&lt;li&gt;Compares any two builds
&lt;/li&gt;
&lt;li&gt;Highlights top increases and new contributors
&lt;/li&gt;
&lt;li&gt;Groups by folder and category
&lt;/li&gt;
&lt;li&gt;Enforces size budgets locally and in CI
&lt;/li&gt;
&lt;li&gt;Generates JSON and Markdown reports
&lt;/li&gt;
&lt;li&gt;Has zero runtime footprint
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is designed for serious Unity developers shipping on Android, iOS, and Windows.&lt;/p&gt;




&lt;h2&gt;
  
  
  If You Care About
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;APK size
&lt;/li&gt;
&lt;li&gt;AAB size
&lt;/li&gt;
&lt;li&gt;IPA size
&lt;/li&gt;
&lt;li&gt;Patch size
&lt;/li&gt;
&lt;li&gt;Store limits
&lt;/li&gt;
&lt;li&gt;Preventing last-minute build surprises
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This workflow solves that problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Available Now
&lt;/h2&gt;

&lt;p&gt;🎮 Itch.io&lt;br&gt;&lt;br&gt;
&lt;a href="https://kevindevelopment.itch.io/buildsizeguard" rel="noopener noreferrer"&gt;https://kevindevelopment.itch.io/buildsizeguard&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;🧰 Unity Asset Store&lt;br&gt;&lt;br&gt;
&lt;a href="https://assetstore.unity.com/packages/slug/361332" rel="noopener noreferrer"&gt;https://assetstore.unity.com/packages/slug/361332&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;If you treat build size as a tracked metric instead of an afterthought, regressions become predictable and preventable.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>videogames</category>
      <category>resources</category>
    </item>
    <item>
      <title>How to generate THIRD_PARTY_NOTICES.txt and CREDITS.md in Unity (Game Compliance Pack quickstart)</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Tue, 10 Feb 2026 11:01:22 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/how-to-generate-thirdpartynoticestxt-and-creditsmd-in-unity-game-compliance-pack-quickstart-1m39</link>
      <guid>https://dev.to/kevinbjorv/how-to-generate-thirdpartynoticestxt-and-creditsmd-in-unity-game-compliance-pack-quickstart-1m39</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1tpvoul3r3zbiy3c3ey.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1tpvoul3r3zbiy3c3ey.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shipping a Unity game often means shipping third-party software too: Unity Package Manager (UPM) dependencies, Asset Store plugins, embedded DLLs, native plugins, copied utilities, and random folders someone dragged into &lt;code&gt;Assets/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At release time, this turns into the same panic checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What third-party did we ship?&lt;/li&gt;
&lt;li&gt;What are the license obligations?&lt;/li&gt;
&lt;li&gt;Where is our third-party notices file?&lt;/li&gt;
&lt;li&gt;Did we forget something?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post shows a practical workflow using &lt;strong&gt;Third-Party Notices &amp;amp; Credits: License Compliance for Unity (Game Compliance Pack)&lt;/strong&gt; to generate release-ready compliance artifacts directly from your Unity project.&lt;/p&gt;

&lt;p&gt;Tool link (copy/paste):&lt;br&gt;
&lt;code&gt;https://kevindevelopment.itch.io/compliance&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the tool generates (release-ready outputs)
&lt;/h2&gt;

&lt;p&gt;From your Unity project, it can export:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;THIRD_PARTY_NOTICES.txt&lt;/code&gt; (full attributions plus license text when available)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CREDITS.md&lt;/code&gt; (short, human-friendly credits block)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compliance-manifest.json&lt;/code&gt; (machine-readable source of truth for diffs and repeatable builds)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key design goal is &lt;strong&gt;deterministic outputs&lt;/strong&gt; you can commit to version control so diffs stay meaningful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow (scan, review UNKNOWN, export)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Import the package into your Unity project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Purchase and download the Unity package&lt;/li&gt;
&lt;li&gt;Import it into the project (like any other &lt;code&gt;.unitypackage&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Reopen the project if Unity does not immediately compile editor scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Run a scan for third-party components
&lt;/h3&gt;

&lt;p&gt;In the tool window, run the scan. The scanner is designed to pick up the most common sources of third-party software in Unity projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UPM dependencies&lt;/strong&gt; (direct and transitive)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Asset Store imports&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded folders&lt;/strong&gt; (common “ThirdParty” style locations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native plugins and binaries&lt;/strong&gt; (DLLs and platform libs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the scan, you should see a component list with evidence for where each item came from.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Treat UNKNOWN as a feature, not a bug
&lt;/h3&gt;

&lt;p&gt;If a license cannot be identified with high confidence, the tool marks it &lt;strong&gt;UNKNOWN&lt;/strong&gt; instead of guessing.&lt;/p&gt;

&lt;p&gt;This is exactly what you want for real compliance work: unknowns become visible, reviewable tasks, not silent risk.&lt;/p&gt;

&lt;p&gt;Practical rule: do not export and ship until your UNKNOWN items are handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Resolve UNKNOWN items using overrides (the real work)
&lt;/h3&gt;

&lt;p&gt;UNKNOWNs are expected. The fast path is to resolve them once and store the decisions in source control so everyone on the team shares the same results.&lt;/p&gt;

&lt;p&gt;Typical resolution steps per UNKNOWN component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm what the component is (where it lives in the project, what it is used for)&lt;/li&gt;
&lt;li&gt;Locate license evidence (LICENSE, NOTICE, COPYING, vendor docs, repo metadata)&lt;/li&gt;
&lt;li&gt;Fill in attribution fields (name, author/publisher, URL if applicable)&lt;/li&gt;
&lt;li&gt;Set the license identifier and include license text when required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tool supports &lt;strong&gt;JSON overrides&lt;/strong&gt; and &lt;strong&gt;manual components&lt;/strong&gt; so the final attribution data reflects what you actually ship.&lt;/p&gt;

&lt;p&gt;Example override shape (illustrative, check the tool docs for exact fields):&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
json
{
  "overrides": [
    {
      "key": "com.vendor.component",
      "licenseId": "MIT",
      "attribution": "Component Name by Vendor Name",
      "url": "https://example.com",
      "licenseText": "..."
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>automation</category>
      <category>gamedev</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Escape Tutorial Hell (As a Beginner Game Dev) Without Becoming a “Framework Collector"</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Tue, 30 Dec 2025 18:21:31 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/how-to-escape-tutorial-hell-as-a-beginner-game-dev-without-becoming-a-framework-collector-42jk</link>
      <guid>https://dev.to/kevinbjorv/how-to-escape-tutorial-hell-as-a-beginner-game-dev-without-becoming-a-framework-collector-42jk</guid>
      <description>&lt;p&gt;If you’ve ever done the classic move where you finish a tutorial, feel productive, then open your own project and instantly forget what to do… welcome. You’re not broken. You just haven’t trained the part of the brain that &lt;em&gt;generates&lt;/em&gt; solutions.&lt;/p&gt;

&lt;p&gt;dev.to has a lot of smart people, but beginners still get stuck in the same trap: &lt;strong&gt;passive learning feels like progress&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is a practical, engine-agnostic post (Unity/Godot/Unreal all fine) on how to escape tutorial hell with a loop you can repeat forever.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real issue: you’re optimizing for “recognition”, not “creation”
&lt;/h2&gt;

&lt;p&gt;Tutorials train recognition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Yeah, I’ve seen this before”&lt;/li&gt;
&lt;li&gt;“I remember that menu”&lt;/li&gt;
&lt;li&gt;“I know that line of code”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But building games requires creation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“What do I do next?”&lt;/li&gt;
&lt;li&gt;“Why did this break?”&lt;/li&gt;
&lt;li&gt;“How do I simplify this?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So your learning method has to force creation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The system: Struggle → Build → Repeat
&lt;/h2&gt;

&lt;p&gt;This is the loop:&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Struggle&lt;/strong&gt;: try without help (short and controlled)&lt;br&gt;
2) &lt;strong&gt;Build&lt;/strong&gt;: implement the smallest version that works&lt;br&gt;
3) &lt;strong&gt;Repeat&lt;/strong&gt;: rebuild from memory + change one thing&lt;/p&gt;

&lt;p&gt;The goal is not to “finish the tutorial”. The goal is to build the &lt;em&gt;skill&lt;/em&gt; of moving forward without a guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Struggle (but don’t cosplay as a genius)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule:&lt;/strong&gt; You must attempt for &lt;strong&gt;15 minutes&lt;/strong&gt; before searching.&lt;/p&gt;

&lt;p&gt;Why?&lt;br&gt;
Because the struggle creates a &lt;em&gt;map&lt;/em&gt; of what you don’t know. Without that map, searching becomes random doomscrolling.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to do during those 15 minutes (simple routine)
&lt;/h3&gt;

&lt;p&gt;Open a scratch note and write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal&lt;/strong&gt;: “Player can jump”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My guess&lt;/strong&gt;: “I need gravity + input + velocity”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try&lt;/strong&gt;: implement your best attempt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result&lt;/strong&gt;: what happened?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next guess&lt;/strong&gt;: one adjustment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns confusion into a process.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you still fail after 15 minutes
&lt;/h3&gt;

&lt;p&gt;Good. Now you earn the right to search, but with a constraint:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for one missing piece, not the whole solution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bad search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“how to make a platformer movement system”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“how to detect grounded in 2d”&lt;/li&gt;
&lt;li&gt;“difference between AddForce and setting velocity”&lt;/li&gt;
&lt;li&gt;“how to clamp camera movement”&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2: Build the smallest working version (embarrassingly small)
&lt;/h2&gt;

&lt;p&gt;Beginners try to build “a real game” too early. That creates complexity and kills momentum.&lt;/p&gt;

&lt;p&gt;You want &lt;strong&gt;minimum playable mechanics&lt;/strong&gt;, not minimum viable product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: “Top-down movement”
&lt;/h3&gt;

&lt;p&gt;Smallest version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WASD moves a square&lt;/li&gt;
&lt;li&gt;no animations&lt;/li&gt;
&lt;li&gt;no fancy camera&lt;/li&gt;
&lt;li&gt;no sprint, no stamina, no diagonals handling beyond normalization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you ship the learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  A constraint that helps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;One mechanic at a time. One file if possible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your “movement” requires 9 scripts and a state machine, you are building a cathedral, not learning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Repeat (this is where the learning actually locks in)
&lt;/h2&gt;

&lt;p&gt;This is the most important step and the one almost nobody does.&lt;/p&gt;

&lt;p&gt;Once you get the thing working, do this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Repeat Protocol
&lt;/h3&gt;

&lt;p&gt;1) Delete it (or start a new empty project)&lt;br&gt;
2) Rebuild it &lt;strong&gt;from memory&lt;/strong&gt;&lt;br&gt;
3) Only after you rebuild it, compare with a reference&lt;br&gt;
4) Then change &lt;strong&gt;one variable&lt;/strong&gt; and rebuild again&lt;/p&gt;

&lt;p&gt;This is how you move from “I watched it” to “I own it”.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical mini-projects that kill tutorial hell (pick one)
&lt;/h2&gt;

&lt;p&gt;These are designed to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small enough to finish&lt;/li&gt;
&lt;li&gt;easy to debug&lt;/li&gt;
&lt;li&gt;easy to repeat with variations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1) Dodge Arena (2 hours)
&lt;/h3&gt;

&lt;p&gt;Goal: survive 30 seconds&lt;/p&gt;

&lt;p&gt;Mechanics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;player moves&lt;/li&gt;
&lt;li&gt;enemies (or hazards) move toward player&lt;/li&gt;
&lt;li&gt;collisions reset the timer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Variations for repeats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add invincibility frames&lt;/li&gt;
&lt;li&gt;add dash cooldown&lt;/li&gt;
&lt;li&gt;add random spawn waves&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) One-Button Jump Game (2 to 4 hours)
&lt;/h3&gt;

&lt;p&gt;Goal: jump over obstacles and score points&lt;/p&gt;

&lt;p&gt;Mechanics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jump&lt;/li&gt;
&lt;li&gt;obstacles spawn&lt;/li&gt;
&lt;li&gt;game over on hit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Variations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;variable jump height&lt;/li&gt;
&lt;li&gt;speed increases over time&lt;/li&gt;
&lt;li&gt;“perfect jump” bonus&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3) Collect + Return (3 to 6 hours)
&lt;/h3&gt;

&lt;p&gt;Goal: collect 3 items then return to exit&lt;/p&gt;

&lt;p&gt;Mechanics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;player movement&lt;/li&gt;
&lt;li&gt;pickups&lt;/li&gt;
&lt;li&gt;UI counter&lt;/li&gt;
&lt;li&gt;exit unlock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Variations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a timer&lt;/li&gt;
&lt;li&gt;add a “wrong pickup” penalty&lt;/li&gt;
&lt;li&gt;add fog of war&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4) Simple Horror Loop (3 to 6 hours)
&lt;/h3&gt;

&lt;p&gt;Goal: find key, escape, avoid enemy&lt;/p&gt;

&lt;p&gt;Mechanics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flashlight cone (fake is fine)&lt;/li&gt;
&lt;li&gt;key pickup&lt;/li&gt;
&lt;li&gt;enemy patrol/chase (basic)&lt;/li&gt;
&lt;li&gt;win/lose state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Variations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sound lure mechanic&lt;/li&gt;
&lt;li&gt;hiding spot&lt;/li&gt;
&lt;li&gt;random key location&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you finish any of these, you are already ahead of 90% of beginners.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to use tutorials without getting trapped (rules that actually work)
&lt;/h2&gt;

&lt;p&gt;Tutorials are not evil. Your &lt;em&gt;usage pattern&lt;/em&gt; is.&lt;/p&gt;

&lt;h3&gt;
  
  
  The “30/70 rule”
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;30%&lt;/strong&gt;: watching/reading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;70%&lt;/strong&gt;: building/testing/changing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are doing the reverse, you are training comfort, not skill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Never follow a tutorial twice
&lt;/h3&gt;

&lt;p&gt;If you need it twice, you did not learn it. You consumed it.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rebuild from memory&lt;/li&gt;
&lt;li&gt;then look up the one missing piece&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Force a change immediately
&lt;/h3&gt;

&lt;p&gt;When you do use a tutorial, you must change one thing &lt;em&gt;before you close it&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;different control scheme&lt;/li&gt;
&lt;li&gt;different movement speed curve&lt;/li&gt;
&lt;li&gt;different enemy behavior&lt;/li&gt;
&lt;li&gt;different UI layout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No change = no learning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Debugging mindset for beginners (so you stop rage-quitting)
&lt;/h2&gt;

&lt;p&gt;When something breaks, beginners think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m bad at this”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Better thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“My mental model is missing one piece”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use this micro checklist:&lt;/p&gt;

&lt;p&gt;1) What did I expect to happen?&lt;br&gt;
2) What actually happened?&lt;br&gt;
3) What is one possible cause?&lt;br&gt;
4) What is the smallest test I can run?&lt;/p&gt;

&lt;p&gt;Your goal is not to “fix it fast”. Your goal is to tighten the loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  A simple weekly plan for busy beginners (realistic)
&lt;/h2&gt;

&lt;p&gt;If you only have 30 to 60 minutes a day, do this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Week 1
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Day 1: pick one mini-project + define win condition&lt;/li&gt;
&lt;li&gt;Day 2: build core movement&lt;/li&gt;
&lt;li&gt;Day 3: add one obstacle/enemy&lt;/li&gt;
&lt;li&gt;Day 4: add win/lose state&lt;/li&gt;
&lt;li&gt;Day 5: rebuild from memory (Repeat Protocol)&lt;/li&gt;
&lt;li&gt;Day 6: variation #1&lt;/li&gt;
&lt;li&gt;Day 7: variation #2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This looks small because it is small. That’s the point. Finishing tiny things builds the identity: “I finish games”.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you want a structured path (engine agnostic)
&lt;/h2&gt;

&lt;p&gt;If you want more content like this (and the full channel + program behind it), I’ve put everything here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://smartindie.dev" rel="noopener noreferrer"&gt;https://smartindie.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s focused on helping beginner solo devs stop bouncing between tutorials and unfinished projects, and actually finish and release a first game with simple systems.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>learning</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding the sizeof Operator in C++: A Comprehensive Guide</title>
      <dc:creator>Kevin Bjorvand</dc:creator>
      <pubDate>Tue, 09 Jul 2024 17:45:39 +0000</pubDate>
      <link>https://dev.to/kevinbjorv/understanding-the-sizeof-operator-in-c-a-comprehensive-guide-58nl</link>
      <guid>https://dev.to/kevinbjorv/understanding-the-sizeof-operator-in-c-a-comprehensive-guide-58nl</guid>
      <description>&lt;p&gt;Wassup guys!&lt;/p&gt;

&lt;p&gt;I recently published a YouTube tutorial on the sizeof operator in C++, and I wanted to share some insights and gems from the video here. You can watch the full tutorial &lt;a href="https://www.youtube.com/watch?v=DuiCjk2ksfc&amp;amp;t=4s" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is the sizeof Operator?&lt;br&gt;
The sizeof operator in C++ is a compile-time operator that returns the size of a variable or data type in bytes. This can be incredibly useful for understanding how much memory your variables and structures are consuming.&lt;/p&gt;

&lt;p&gt;Key Points Covered in the Tutorial:&lt;br&gt;
Basic Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`int a;
std::cout &amp;lt;&amp;lt; "Size of int: " &amp;lt;&amp;lt; sizeof(a) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
This prints the size of an integer variable.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using sizeof with Data Types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`std::cout &amp;lt;&amp;lt; "Size of double: " &amp;lt;&amp;lt; sizeof(double) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
You can directly use sizeof with data types to get their size.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays and sizeof:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`int arr[10];
std::cout &amp;lt;&amp;lt; "Size of array: " &amp;lt;&amp;lt; sizeof(arr) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
This returns the total size of the array (number of elements multiplied by the size of each element).`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pointers vs. Arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`int* ptr;
std::cout &amp;lt;&amp;lt; "Size of pointer: " &amp;lt;&amp;lt; sizeof(ptr) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
It's crucial to understand the difference in size between pointers and the arrays they may point to.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best Practices:&lt;br&gt;
Using sizeof with Structs and Classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`struct MyStruct {
    int a;
    double b;
    char c;
};
std::cout &amp;lt;&amp;lt; "Size of MyStruct: " &amp;lt;&amp;lt; sizeof(MyStruct) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps you understand the memory layout of your custom data types, which is critical for performance tuning and debugging.&lt;/p&gt;

&lt;p&gt;Alignment and Padding:&lt;br&gt;
The sizeof operator reveals the effects of alignment and padding on the size of structs and classes. Understanding this can help optimize memory usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`struct MyPackedStruct {
    char a;
    int b;
} __attribute__((packed));
std::cout &amp;lt;&amp;lt; "Size of MyPackedStruct: " &amp;lt;&amp;lt; sizeof(MyPackedStruct) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using sizeof with Dynamic Memory:&lt;br&gt;
Be cautious when using sizeof with dynamically allocated memory, as it only returns the size of the pointer, not the allocated memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`int* dynamicArray = new int[10];
std::cout &amp;lt;&amp;lt; "Size of dynamicArray pointer: " &amp;lt;&amp;lt; sizeof(dynamicArray) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common Pitfalls:&lt;br&gt;
Misunderstanding sizeof with Functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`void func(int arr[10]) {
    std::cout &amp;lt;&amp;lt; "Size of arr inside function: " &amp;lt;&amp;lt; sizeof(arr) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside functions, arrays decay to pointers, so sizeof will not return the size of the original array.&lt;/p&gt;

&lt;p&gt;Using sizeof with Expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;std::cout &amp;lt;&amp;lt; "Size of expression: " &amp;lt;&amp;lt; sizeof(1 + 2.0) &amp;lt;&amp;lt; " bytes" &amp;lt;&amp;lt; std::endl;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return the size of the resulting type of the expression.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Understanding the sizeof operator is fundamental for mastering C++. It not only helps in efficient memory management but also deepens your understanding of how C++ manages data. For a detailed explanation and more examples, check out my YouTube tutorial.&lt;/p&gt;

&lt;p&gt;Feel free to leave comments and questions below. Happy coding!&lt;/p&gt;

&lt;p&gt;Check out my full video here: &lt;a href="https://www.youtube.com/watch?v=DuiCjk2ksfc&amp;amp;t=4s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=DuiCjk2ksfc&amp;amp;t=4s&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>c</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
