diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..075b254 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/.quarto/idx/about.qmd.json b/.quarto/idx/about.qmd.json index 5456266..547069d 100644 --- a/.quarto/idx/about.qmd.json +++ b/.quarto/idx/about.qmd.json @@ -1 +1 @@ -{"title":"About","markdown":{"yaml":{"title":"About"},"containsRefs":false,"markdown":"\n\nAbout this site\n","srcMarkdownNoYaml":"\n\nAbout this site\n"},"formats":{"html":{"identifier":{"display-name":"HTML","target-format":"html","base-format":"html"},"execute":{"fig-width":7,"fig-height":5,"fig-format":"retina","fig-dpi":96,"df-print":"default","error":false,"eval":true,"cache":null,"freeze":false,"echo":true,"output":true,"warning":true,"include":true,"keep-md":false,"keep-ipynb":false,"ipynb":null,"enabled":null,"daemon":null,"daemon-restart":false,"debug":false,"ipynb-filters":[],"ipynb-shell-interactivity":null,"plotly-connected":true,"engine":"markdown"},"render":{"keep-tex":false,"keep-typ":false,"keep-source":false,"keep-hidden":false,"prefer-html":false,"output-divs":true,"output-ext":"html","fig-align":"default","fig-pos":null,"fig-env":null,"code-fold":"none","code-overflow":"scroll","code-link":false,"code-line-numbers":false,"code-tools":false,"tbl-colwidths":"auto","merge-includes":true,"inline-includes":false,"preserve-yaml":false,"latex-auto-mk":true,"latex-auto-install":true,"latex-clean":true,"latex-min-runs":1,"latex-max-runs":10,"latex-makeindex":"makeindex","latex-makeindex-opts":[],"latex-tlmgr-opts":[],"latex-input-paths":[],"latex-output-dir":null,"link-external-icon":false,"link-external-newwindow":false,"self-contained-math":false,"format-resources":[],"notebook-links":true},"pandoc":{"standalone":true,"wrap":"none","default-image-extension":"png","to":"html","css":["styles.css"],"toc":true,"output-file":"about.html"},"language":{"toc-title-document":"Table of contents","toc-title-website":"On this page","related-formats-title":"Other Formats","related-notebooks-title":"Notebooks","source-notebooks-prefix":"Source","other-links-title":"Other Links","code-links-title":"Code Links","launch-dev-container-title":"Launch Dev Container","launch-binder-title":"Launch Binder","article-notebook-label":"Article Notebook","notebook-preview-download":"Download Notebook","notebook-preview-download-src":"Download Source","notebook-preview-back":"Back to Article","manuscript-meca-bundle":"MECA Bundle","section-title-abstract":"Abstract","section-title-appendices":"Appendices","section-title-footnotes":"Footnotes","section-title-references":"References","section-title-reuse":"Reuse","section-title-copyright":"Copyright","section-title-citation":"Citation","appendix-attribution-cite-as":"For attribution, please cite this work as:","appendix-attribution-bibtex":"BibTeX citation:","appendix-view-license":"View License","title-block-author-single":"Author","title-block-author-plural":"Authors","title-block-affiliation-single":"Affiliation","title-block-affiliation-plural":"Affiliations","title-block-published":"Published","title-block-modified":"Modified","title-block-keywords":"Keywords","callout-tip-title":"Tip","callout-note-title":"Note","callout-warning-title":"Warning","callout-important-title":"Important","callout-caution-title":"Caution","code-summary":"Code","code-tools-menu-caption":"Code","code-tools-show-all-code":"Show All Code","code-tools-hide-all-code":"Hide All Code","code-tools-view-source":"View Source","code-tools-source-code":"Source Code","tools-share":"Share","tools-download":"Download","code-line":"Line","code-lines":"Lines","copy-button-tooltip":"Copy to Clipboard","copy-button-tooltip-success":"Copied!","repo-action-links-edit":"Edit this page","repo-action-links-source":"View source","repo-action-links-issue":"Report an issue","back-to-top":"Back to top","search-no-results-text":"No results","search-matching-documents-text":"matching documents","search-copy-link-title":"Copy link to search","search-hide-matches-text":"Hide additional matches","search-more-match-text":"more match in this document","search-more-matches-text":"more matches in this document","search-clear-button-title":"Clear","search-text-placeholder":"","search-detached-cancel-button-title":"Cancel","search-submit-button-title":"Submit","search-label":"Search","toggle-section":"Toggle section","toggle-sidebar":"Toggle sidebar navigation","toggle-dark-mode":"Toggle dark mode","toggle-reader-mode":"Toggle reader mode","toggle-navigation":"Toggle navigation","crossref-fig-title":"Figure","crossref-tbl-title":"Table","crossref-lst-title":"Listing","crossref-thm-title":"Theorem","crossref-lem-title":"Lemma","crossref-cor-title":"Corollary","crossref-prp-title":"Proposition","crossref-cnj-title":"Conjecture","crossref-def-title":"Definition","crossref-exm-title":"Example","crossref-exr-title":"Exercise","crossref-ch-prefix":"Chapter","crossref-apx-prefix":"Appendix","crossref-sec-prefix":"Section","crossref-eq-prefix":"Equation","crossref-lof-title":"List of Figures","crossref-lot-title":"List of Tables","crossref-lol-title":"List of Listings","environment-proof-title":"Proof","environment-remark-title":"Remark","environment-solution-title":"Solution","listing-page-order-by":"Order By","listing-page-order-by-default":"Default","listing-page-order-by-date-asc":"Oldest","listing-page-order-by-date-desc":"Newest","listing-page-order-by-number-desc":"High to Low","listing-page-order-by-number-asc":"Low to High","listing-page-field-date":"Date","listing-page-field-title":"Title","listing-page-field-description":"Description","listing-page-field-author":"Author","listing-page-field-filename":"File Name","listing-page-field-filemodified":"Modified","listing-page-field-subtitle":"Subtitle","listing-page-field-readingtime":"Reading Time","listing-page-field-wordcount":"Word Count","listing-page-field-categories":"Categories","listing-page-minutes-compact":"{0} min","listing-page-category-all":"All","listing-page-no-matches":"No matching items","listing-page-words":"{0} words","listing-page-filter":"Filter","draft":"Draft"},"metadata":{"lang":"en","fig-responsive":true,"quarto-version":"1.7.21","theme":["cosmo","brand"],"title":"About"},"extensions":{"book":{"multiFile":true}}}},"projectFormats":["html"]} \ No newline at end of file +{"title":"About","markdown":{"yaml":{"title":"About"},"containsRefs":false,"markdown":"\n\nAbout this site\n","srcMarkdownNoYaml":"\n\nAbout this site\n"},"formats":{"html":{"identifier":{"display-name":"HTML","target-format":"html","base-format":"html"},"execute":{"fig-width":7,"fig-height":5,"fig-format":"retina","fig-dpi":96,"df-print":"default","error":false,"eval":true,"cache":null,"freeze":false,"echo":true,"output":true,"warning":true,"include":true,"keep-md":false,"keep-ipynb":false,"ipynb":null,"enabled":null,"daemon":null,"daemon-restart":false,"debug":false,"ipynb-filters":[],"ipynb-shell-interactivity":null,"plotly-connected":true,"engine":"markdown"},"render":{"keep-tex":false,"keep-typ":false,"keep-source":false,"keep-hidden":false,"prefer-html":false,"output-divs":true,"output-ext":"html","fig-align":"default","fig-pos":null,"fig-env":null,"code-fold":"none","code-overflow":"scroll","code-link":false,"code-line-numbers":false,"code-tools":false,"tbl-colwidths":"auto","merge-includes":true,"inline-includes":false,"preserve-yaml":false,"latex-auto-mk":true,"latex-auto-install":true,"latex-clean":true,"latex-min-runs":1,"latex-max-runs":10,"latex-makeindex":"makeindex","latex-makeindex-opts":[],"latex-tlmgr-opts":[],"latex-input-paths":[],"latex-output-dir":null,"link-external-icon":false,"link-external-newwindow":false,"self-contained-math":false,"format-resources":[],"notebook-links":true},"pandoc":{"standalone":true,"wrap":"none","default-image-extension":"png","to":"html","toc":true,"output-file":"about.html"},"language":{"toc-title-document":"Table of contents","toc-title-website":"On this page","related-formats-title":"Other Formats","related-notebooks-title":"Notebooks","source-notebooks-prefix":"Source","other-links-title":"Other Links","code-links-title":"Code Links","launch-dev-container-title":"Launch Dev Container","launch-binder-title":"Launch Binder","article-notebook-label":"Article Notebook","notebook-preview-download":"Download Notebook","notebook-preview-download-src":"Download Source","notebook-preview-back":"Back to Article","manuscript-meca-bundle":"MECA Bundle","section-title-abstract":"Abstract","section-title-appendices":"Appendices","section-title-footnotes":"Footnotes","section-title-references":"References","section-title-reuse":"Reuse","section-title-copyright":"Copyright","section-title-citation":"Citation","appendix-attribution-cite-as":"For attribution, please cite this work as:","appendix-attribution-bibtex":"BibTeX citation:","appendix-view-license":"View License","title-block-author-single":"Author","title-block-author-plural":"Authors","title-block-affiliation-single":"Affiliation","title-block-affiliation-plural":"Affiliations","title-block-published":"Published","title-block-modified":"Modified","title-block-keywords":"Keywords","callout-tip-title":"Tip","callout-note-title":"Note","callout-warning-title":"Warning","callout-important-title":"Important","callout-caution-title":"Caution","code-summary":"Code","code-tools-menu-caption":"Code","code-tools-show-all-code":"Show All Code","code-tools-hide-all-code":"Hide All Code","code-tools-view-source":"View Source","code-tools-source-code":"Source Code","tools-share":"Share","tools-download":"Download","code-line":"Line","code-lines":"Lines","copy-button-tooltip":"Copy to Clipboard","copy-button-tooltip-success":"Copied!","repo-action-links-edit":"Edit this page","repo-action-links-source":"View source","repo-action-links-issue":"Report an issue","back-to-top":"Back to top","search-no-results-text":"No results","search-matching-documents-text":"matching documents","search-copy-link-title":"Copy link to search","search-hide-matches-text":"Hide additional matches","search-more-match-text":"more match in this document","search-more-matches-text":"more matches in this document","search-clear-button-title":"Clear","search-text-placeholder":"","search-detached-cancel-button-title":"Cancel","search-submit-button-title":"Submit","search-label":"Search","toggle-section":"Toggle section","toggle-sidebar":"Toggle sidebar navigation","toggle-dark-mode":"Toggle dark mode","toggle-reader-mode":"Toggle reader mode","toggle-navigation":"Toggle navigation","crossref-fig-title":"Figure","crossref-tbl-title":"Table","crossref-lst-title":"Listing","crossref-thm-title":"Theorem","crossref-lem-title":"Lemma","crossref-cor-title":"Corollary","crossref-prp-title":"Proposition","crossref-cnj-title":"Conjecture","crossref-def-title":"Definition","crossref-exm-title":"Example","crossref-exr-title":"Exercise","crossref-ch-prefix":"Chapter","crossref-apx-prefix":"Appendix","crossref-sec-prefix":"Section","crossref-eq-prefix":"Equation","crossref-lof-title":"List of Figures","crossref-lot-title":"List of Tables","crossref-lol-title":"List of Listings","environment-proof-title":"Proof","environment-remark-title":"Remark","environment-solution-title":"Solution","listing-page-order-by":"Order By","listing-page-order-by-default":"Default","listing-page-order-by-date-asc":"Oldest","listing-page-order-by-date-desc":"Newest","listing-page-order-by-number-desc":"High to Low","listing-page-order-by-number-asc":"Low to High","listing-page-field-date":"Date","listing-page-field-title":"Title","listing-page-field-description":"Description","listing-page-field-author":"Author","listing-page-field-filename":"File Name","listing-page-field-filemodified":"Modified","listing-page-field-subtitle":"Subtitle","listing-page-field-readingtime":"Reading Time","listing-page-field-wordcount":"Word Count","listing-page-field-categories":"Categories","listing-page-minutes-compact":"{0} min","listing-page-category-all":"All","listing-page-no-matches":"No matching items","listing-page-words":"{0} words","listing-page-filter":"Filter","draft":"Draft"},"metadata":{"lang":"en","fig-responsive":true,"quarto-version":"1.6.43","theme":["Zephyr","theme.scss"],"logo":"logo.png","output-dir":"_site","grid":{"margin-width":"350px"},"title":"About"},"extensions":{"book":{"multiFile":true}}}},"projectFormats":["html"]} \ No newline at end of file diff --git a/.quarto/idx/index.qmd.json b/.quarto/idx/index.qmd.json index 068334f..ed90e03 100644 --- a/.quarto/idx/index.qmd.json +++ b/.quarto/idx/index.qmd.json @@ -1 +1 @@ -{"title":"VIRTUOS WORLD Documentation","markdown":{"yaml":{"title":"VIRTUOS WORLD Documentation"},"containsRefs":false,"markdown":"\n\nThis is a Quarto website.\n\nTo learn more about Quarto websites visit .\n","srcMarkdownNoYaml":"\n\nThis is a Quarto website.\n\nTo learn more about Quarto websites visit .\n"},"formats":{"html":{"identifier":{"display-name":"HTML","target-format":"html","base-format":"html"},"execute":{"fig-width":7,"fig-height":5,"fig-format":"retina","fig-dpi":96,"df-print":"default","error":false,"eval":true,"cache":null,"freeze":false,"echo":true,"output":true,"warning":true,"include":true,"keep-md":false,"keep-ipynb":false,"ipynb":null,"enabled":null,"daemon":null,"daemon-restart":false,"debug":false,"ipynb-filters":[],"ipynb-shell-interactivity":null,"plotly-connected":true,"engine":"markdown"},"render":{"keep-tex":false,"keep-typ":false,"keep-source":false,"keep-hidden":false,"prefer-html":false,"output-divs":true,"output-ext":"html","fig-align":"default","fig-pos":null,"fig-env":null,"code-fold":"none","code-overflow":"scroll","code-link":false,"code-line-numbers":false,"code-tools":false,"tbl-colwidths":"auto","merge-includes":true,"inline-includes":false,"preserve-yaml":false,"latex-auto-mk":true,"latex-auto-install":true,"latex-clean":true,"latex-min-runs":1,"latex-max-runs":10,"latex-makeindex":"makeindex","latex-makeindex-opts":[],"latex-tlmgr-opts":[],"latex-input-paths":[],"latex-output-dir":null,"link-external-icon":false,"link-external-newwindow":false,"self-contained-math":false,"format-resources":[],"notebook-links":true},"pandoc":{"standalone":true,"wrap":"none","default-image-extension":"png","to":"html","css":["styles.css"],"toc":true,"output-file":"index.html"},"language":{"toc-title-document":"Table of contents","toc-title-website":"On this page","related-formats-title":"Other Formats","related-notebooks-title":"Notebooks","source-notebooks-prefix":"Source","other-links-title":"Other Links","code-links-title":"Code Links","launch-dev-container-title":"Launch Dev Container","launch-binder-title":"Launch Binder","article-notebook-label":"Article Notebook","notebook-preview-download":"Download Notebook","notebook-preview-download-src":"Download Source","notebook-preview-back":"Back to Article","manuscript-meca-bundle":"MECA Bundle","section-title-abstract":"Abstract","section-title-appendices":"Appendices","section-title-footnotes":"Footnotes","section-title-references":"References","section-title-reuse":"Reuse","section-title-copyright":"Copyright","section-title-citation":"Citation","appendix-attribution-cite-as":"For attribution, please cite this work as:","appendix-attribution-bibtex":"BibTeX citation:","appendix-view-license":"View License","title-block-author-single":"Author","title-block-author-plural":"Authors","title-block-affiliation-single":"Affiliation","title-block-affiliation-plural":"Affiliations","title-block-published":"Published","title-block-modified":"Modified","title-block-keywords":"Keywords","callout-tip-title":"Tip","callout-note-title":"Note","callout-warning-title":"Warning","callout-important-title":"Important","callout-caution-title":"Caution","code-summary":"Code","code-tools-menu-caption":"Code","code-tools-show-all-code":"Show All Code","code-tools-hide-all-code":"Hide All Code","code-tools-view-source":"View Source","code-tools-source-code":"Source Code","tools-share":"Share","tools-download":"Download","code-line":"Line","code-lines":"Lines","copy-button-tooltip":"Copy to Clipboard","copy-button-tooltip-success":"Copied!","repo-action-links-edit":"Edit this page","repo-action-links-source":"View source","repo-action-links-issue":"Report an issue","back-to-top":"Back to top","search-no-results-text":"No results","search-matching-documents-text":"matching documents","search-copy-link-title":"Copy link to search","search-hide-matches-text":"Hide additional matches","search-more-match-text":"more match in this document","search-more-matches-text":"more matches in this document","search-clear-button-title":"Clear","search-text-placeholder":"","search-detached-cancel-button-title":"Cancel","search-submit-button-title":"Submit","search-label":"Search","toggle-section":"Toggle section","toggle-sidebar":"Toggle sidebar navigation","toggle-dark-mode":"Toggle dark mode","toggle-reader-mode":"Toggle reader mode","toggle-navigation":"Toggle navigation","crossref-fig-title":"Figure","crossref-tbl-title":"Table","crossref-lst-title":"Listing","crossref-thm-title":"Theorem","crossref-lem-title":"Lemma","crossref-cor-title":"Corollary","crossref-prp-title":"Proposition","crossref-cnj-title":"Conjecture","crossref-def-title":"Definition","crossref-exm-title":"Example","crossref-exr-title":"Exercise","crossref-ch-prefix":"Chapter","crossref-apx-prefix":"Appendix","crossref-sec-prefix":"Section","crossref-eq-prefix":"Equation","crossref-lof-title":"List of Figures","crossref-lot-title":"List of Tables","crossref-lol-title":"List of Listings","environment-proof-title":"Proof","environment-remark-title":"Remark","environment-solution-title":"Solution","listing-page-order-by":"Order By","listing-page-order-by-default":"Default","listing-page-order-by-date-asc":"Oldest","listing-page-order-by-date-desc":"Newest","listing-page-order-by-number-desc":"High to Low","listing-page-order-by-number-asc":"Low to High","listing-page-field-date":"Date","listing-page-field-title":"Title","listing-page-field-description":"Description","listing-page-field-author":"Author","listing-page-field-filename":"File Name","listing-page-field-filemodified":"Modified","listing-page-field-subtitle":"Subtitle","listing-page-field-readingtime":"Reading Time","listing-page-field-wordcount":"Word Count","listing-page-field-categories":"Categories","listing-page-minutes-compact":"{0} min","listing-page-category-all":"All","listing-page-no-matches":"No matching items","listing-page-words":"{0} words","listing-page-filter":"Filter","draft":"Draft"},"metadata":{"lang":"en","fig-responsive":true,"quarto-version":"1.7.21","theme":["cosmo","brand"],"title":"VIRTUOS WORLD Documentation"},"extensions":{"book":{"multiFile":true}}}},"projectFormats":["html"]} \ No newline at end of file +{"title":"Home","markdown":{"yaml":{"title":"Home"},"headingText":"Welcome to the Documentation!","containsRefs":false,"markdown":"\n\n\nThis is the main page of your documentation. You can add more sections or documentation as you need.\n\n## Features\n\n- Easy setup\n- User-friendly interface\n- Rich documentation\n\nFor more details, refer to the Getting Started section in the sidebar.\n","srcMarkdownNoYaml":"\n\n# Welcome to the Documentation!\n\nThis is the main page of your documentation. You can add more sections or documentation as you need.\n\n## Features\n\n- Easy setup\n- User-friendly interface\n- Rich documentation\n\nFor more details, refer to the Getting Started section in the sidebar.\n"},"formats":{"html":{"identifier":{"display-name":"HTML","target-format":"html","base-format":"html"},"execute":{"fig-width":7,"fig-height":5,"fig-format":"retina","fig-dpi":96,"df-print":"default","error":false,"eval":true,"cache":null,"freeze":false,"echo":true,"output":true,"warning":true,"include":true,"keep-md":false,"keep-ipynb":false,"ipynb":null,"enabled":null,"daemon":null,"daemon-restart":false,"debug":false,"ipynb-filters":[],"ipynb-shell-interactivity":null,"plotly-connected":true,"engine":"markdown"},"render":{"keep-tex":false,"keep-typ":false,"keep-source":false,"keep-hidden":false,"prefer-html":false,"output-divs":true,"output-ext":"html","fig-align":"default","fig-pos":null,"fig-env":null,"code-fold":"none","code-overflow":"scroll","code-link":false,"code-line-numbers":false,"code-tools":false,"tbl-colwidths":"auto","merge-includes":true,"inline-includes":false,"preserve-yaml":false,"latex-auto-mk":true,"latex-auto-install":true,"latex-clean":true,"latex-min-runs":1,"latex-max-runs":10,"latex-makeindex":"makeindex","latex-makeindex-opts":[],"latex-tlmgr-opts":[],"latex-input-paths":[],"latex-output-dir":null,"link-external-icon":false,"link-external-newwindow":false,"self-contained-math":false,"format-resources":[],"notebook-links":true},"pandoc":{"standalone":true,"wrap":"none","default-image-extension":"png","to":"html","toc":true,"output-file":"index.html"},"language":{"toc-title-document":"Table of contents","toc-title-website":"On this page","related-formats-title":"Other Formats","related-notebooks-title":"Notebooks","source-notebooks-prefix":"Source","other-links-title":"Other Links","code-links-title":"Code Links","launch-dev-container-title":"Launch Dev Container","launch-binder-title":"Launch Binder","article-notebook-label":"Article Notebook","notebook-preview-download":"Download Notebook","notebook-preview-download-src":"Download Source","notebook-preview-back":"Back to Article","manuscript-meca-bundle":"MECA Bundle","section-title-abstract":"Abstract","section-title-appendices":"Appendices","section-title-footnotes":"Footnotes","section-title-references":"References","section-title-reuse":"Reuse","section-title-copyright":"Copyright","section-title-citation":"Citation","appendix-attribution-cite-as":"For attribution, please cite this work as:","appendix-attribution-bibtex":"BibTeX citation:","appendix-view-license":"View License","title-block-author-single":"Author","title-block-author-plural":"Authors","title-block-affiliation-single":"Affiliation","title-block-affiliation-plural":"Affiliations","title-block-published":"Published","title-block-modified":"Modified","title-block-keywords":"Keywords","callout-tip-title":"Tip","callout-note-title":"Note","callout-warning-title":"Warning","callout-important-title":"Important","callout-caution-title":"Caution","code-summary":"Code","code-tools-menu-caption":"Code","code-tools-show-all-code":"Show All Code","code-tools-hide-all-code":"Hide All Code","code-tools-view-source":"View Source","code-tools-source-code":"Source Code","tools-share":"Share","tools-download":"Download","code-line":"Line","code-lines":"Lines","copy-button-tooltip":"Copy to Clipboard","copy-button-tooltip-success":"Copied!","repo-action-links-edit":"Edit this page","repo-action-links-source":"View source","repo-action-links-issue":"Report an issue","back-to-top":"Back to top","search-no-results-text":"No results","search-matching-documents-text":"matching documents","search-copy-link-title":"Copy link to search","search-hide-matches-text":"Hide additional matches","search-more-match-text":"more match in this document","search-more-matches-text":"more matches in this document","search-clear-button-title":"Clear","search-text-placeholder":"","search-detached-cancel-button-title":"Cancel","search-submit-button-title":"Submit","search-label":"Search","toggle-section":"Toggle section","toggle-sidebar":"Toggle sidebar navigation","toggle-dark-mode":"Toggle dark mode","toggle-reader-mode":"Toggle reader mode","toggle-navigation":"Toggle navigation","crossref-fig-title":"Figure","crossref-tbl-title":"Table","crossref-lst-title":"Listing","crossref-thm-title":"Theorem","crossref-lem-title":"Lemma","crossref-cor-title":"Corollary","crossref-prp-title":"Proposition","crossref-cnj-title":"Conjecture","crossref-def-title":"Definition","crossref-exm-title":"Example","crossref-exr-title":"Exercise","crossref-ch-prefix":"Chapter","crossref-apx-prefix":"Appendix","crossref-sec-prefix":"Section","crossref-eq-prefix":"Equation","crossref-lof-title":"List of Figures","crossref-lot-title":"List of Tables","crossref-lol-title":"List of Listings","environment-proof-title":"Proof","environment-remark-title":"Remark","environment-solution-title":"Solution","listing-page-order-by":"Order By","listing-page-order-by-default":"Default","listing-page-order-by-date-asc":"Oldest","listing-page-order-by-date-desc":"Newest","listing-page-order-by-number-desc":"High to Low","listing-page-order-by-number-asc":"Low to High","listing-page-field-date":"Date","listing-page-field-title":"Title","listing-page-field-description":"Description","listing-page-field-author":"Author","listing-page-field-filename":"File Name","listing-page-field-filemodified":"Modified","listing-page-field-subtitle":"Subtitle","listing-page-field-readingtime":"Reading Time","listing-page-field-wordcount":"Word Count","listing-page-field-categories":"Categories","listing-page-minutes-compact":"{0} min","listing-page-category-all":"All","listing-page-no-matches":"No matching items","listing-page-words":"{0} words","listing-page-filter":"Filter","draft":"Draft"},"metadata":{"lang":"en","fig-responsive":true,"quarto-version":"1.6.43","theme":["Zephyr","theme.scss"],"logo":"logo.png","output-dir":"_site","grid":{"margin-width":"350px"},"title":"Home"},"extensions":{"book":{"multiFile":true}}}},"projectFormats":["html"]} \ No newline at end of file diff --git a/.quarto/xref/INDEX b/.quarto/xref/INDEX index 6c62be6..a7c2434 100644 --- a/.quarto/xref/INDEX +++ b/.quarto/xref/INDEX @@ -1,8 +1,27 @@ { "index.qmd": { - "index.html": "d99f7c3a" + "index.html": "d99f7c3a", + "index.tex": "2767060a" }, "about.qmd": { - "about.html": "67271bd5" + "about.html": "67271bd5", + "about.tex": "213452bd" + }, + "sites/introduction.qmd": { + "introduction.html": "7be58818" + }, + "sites/styleguide.qmd": { + "styleguide.html": "09b1328c", + "styleguide.tex": "772a8301" + }, + "sites/webservices.qmd": { + "webservices.html": "2bb00f73", + "webservices.tex": "db01438b" + }, + "sites/getstarted.qmd": { + "getstarted.html": "58d9f35c" + }, + "sites/overview.qmd": { + "overview.html": "a690ee7d" } } \ No newline at end of file diff --git a/.quarto/xref/d99f7c3a b/.quarto/xref/d99f7c3a index 208374b..a14039c 100644 --- a/.quarto/xref/d99f7c3a +++ b/.quarto/xref/d99f7c3a @@ -1 +1 @@ -{"entries":[],"headings":[]} \ No newline at end of file +{"entries":[],"headings":["welcome-to-the-documentation","features"]} \ No newline at end of file diff --git a/_quarto.yml b/_quarto.yml index 91ddf1e..643b070 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -2,20 +2,53 @@ project: type: website website: - title: "VIRTUOS WORLD Documentation" + title: "DOCS" navbar: left: - - href: index.qmd - text: Home - - about.qmd + - text: "Homepage" + href: https://virtuos.world + sidebar: + style: "docked" + search: true + contents: + - section: "Overview" + href: sites/overview.qmd + - section: "Styleguide" + href: sites/styleguide.qmd + contents: + - layout.qmd + - layout-knitr.qmd + - layout-jupyter.qmd + - section: "Webservices" + href: sites/webservices.qmd + contents: + - layout.qmd + - layout-knitr.qmd + - layout-jupyter.qmd + - section: "Getting Started" + href: sites/getstarted.qmd -format: + page-footer: + left: "Copyright 2025, Simeon Wallrath" + right: + - icon: github + href: https://github.com/ + - icon: mastodon + href: https://twitter.com/ + reader-mode: true + + +theme: + - Zephyr + - theme.scss + +# Set the logo for the header +logo: "logo.png" + +output-dir: "_site" + +format: html: - theme: - - cosmo - - brand - css: styles.css toc: true - - - + grid: + margin-width: 350px \ No newline at end of file diff --git a/_site/about.html b/_site/about.html index d7d9270..4b863e7 100644 --- a/_site/about.html +++ b/_site/about.html @@ -2,12 +2,12 @@ - + -About – VIRTUOS WORLD Documentation +About – DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Getting Started

+
+ + + +
+ + + + +
+ + + +
+ + +

If you want to take a look inside a project, there are currently three important repositories:

+
    +
  • VIRTUOS_Playground: The repository contains the Unreal Engine Project
  • +
  • VIRTUOS_Assets: Contains all Project related assets like 3D-Models, Graphics etc.
  • +
  • VIRTUOS_Documents: Contains all written Documents
  • +
+
+

Setting up the project with UE5

+

If you’re familiar with Git, you’ll likely already know how to get the files.

+
git pull https://code.virtuos.world/VIRTUOS_WORLD/VIRTUOS_Docs.git
+

If you’re not comforatable with the command line, you can install a Git GUI like Github Desktop.

+ + + +
+ +
+ +
+
+ +
+ + + + + \ No newline at end of file diff --git a/_site/sites/overview.html b/_site/sites/overview.html new file mode 100644 index 0000000..616aa25 --- /dev/null +++ b/_site/sites/overview.html @@ -0,0 +1,649 @@ + + + + + + + + + +About – DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

About

+
+ + + +
+ + + + +
+ + + +
+ + +

About this site

+ + + +
+ +
+ + + + + \ No newline at end of file diff --git a/_site/sites/styleguide.html b/_site/sites/styleguide.html new file mode 100644 index 0000000..e4dfc20 --- /dev/null +++ b/_site/sites/styleguide.html @@ -0,0 +1,2892 @@ + + + + + + + + + +Styleguide – DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Styleguide

+
+ + + +
+ + + + +
+ + + +
+ + +

This Styleguiade is adapted by Gamemakin UE5 Styleguide.

+
+

Important Terminology

+

+
+
Levels/Maps
+

The word ‘map’ generally refers to what the average person calls a ‘level’ and may be used interchangeably. See this term’s history here.

+
+
+
Identifiers
+

An Identifier is anything that resembles or serves as a “name”. For example, the name of an asset, or the name of a material later, or a blueprint property, a variable, or a folder name, or for a data table row name, etc…

+

+
+
+
Cases
+

There are a few different ways you can CaseWordsWhenNaming. Here are some common casing types:

+
+
PascalCase
+

Capitalize every word and remove all spaces, e.g. DesertEagle, StyleGuide, ASeriesOfWords.

+
camelCase
+

The first letter is always lowercase but every following word starts with uppercase, e.g. desertEagle, styleGuide, aSeriesOfWords.

+
Snake_case
+

Words can arbitrarily start upper or lowercase but words are separated by an underscore, e.g. desert_Eagle, Style_Guide, a_Series_of_Words.

+
+

+
+
+
Variables / Properties
+

The words ‘variable’ and ‘property’ in most contexts are interchangable. If they are both used together in the same context however:

+

+
+
Property
+

Usually refers to a variable defined in a class. For example, if BP_Barrel had a variable bExploded, bExploded may be referred to as a property of BP_Barrel.

+

When in the context of a class, it is often used to imply accessing previously defined data.

+

+
+
+
Variable
+

Usually refers to a variable defined as a function argument or a local variable inside a function.

+

When in the context of a class, it is often used to convey discussion about its definition and what it will hold.

+

+
+
+
+
+

0. Principles

+

These principles have been adapted from idomatic.js style guide.

+

+
+

0.1 If your UE4 project already has a style guide, you should follow it.

+

If you are working on a project or with a team that has a pre-existing style guide, it should be respected. Any inconsistency between an existing style guide and this guide should defer to the existing.

+

Style guides should be living documents. You should propose style guide changes to an existing style guide as well as this guide if you feel the change benefits all usages.

+
+

“Arguments over style are pointless. There should be a style guide, and you should follow it.”

+

Rebecca Murphey

+
+

+
+
+

0.2 All structure, assets, and code in any Unreal Engine 4 project should look like a single person created it, no matter how many people contributed.

+

Moving from one project to another should not cause a re-learning of style and structure. Conforming to a style guide removes unneeded guesswork and ambiguities.

+

It also allows for more productive creation and maintenance as one does not need to think about style. Simply follow the instructions. This style guide is written with best practices in mind, meaning that by following this style guide you will also minimize hard to track issues.

+

+
+
+

0.3 Friends do not let friends have bad style.

+

If you see someone working either against a style guide or no style guide, try to correct them.

+

When working within a team or discussing within a community such as Unreal Slackers, it is far easier to help and to ask for help when people are consistent. Nobody likes to help untangle someone’s Blueprint spaghetti or deal with assets that have names they can’t understand.

+

If you are helping someone whose work conforms to a different but consistent and sane style guide, you should be able to adapt to it. If they do not conform to any style guide, please direct them here.

+

+
+
+

0.4 A team without a style guide is no team of mine.

+

When joining an Unreal Engine 4 team, one of your first questions should be “Do you have a style guide?”. If the answer is no, you should be skeptical about their ability to work as a team.

+

+
+
+

0.5 Don’t Break The Law

+

Gamemakin LLC is not a lawyer, but please don’t introduce illegal actions and behavior to a project, including but not limited to:

+
    +
  • Don’t distribute content you don’t have the rights to distribute
  • +
  • Don’t infringe on someone else’s copyrighted or trademark material
  • +
  • Don’t steal content
  • +
  • Follow licensing restrictions on content, e.g. attribute when attributions are needed
  • +
+

+
+
+
+

00. Globally Enforced Opinions

+

@TODO: Make this section 1 and update this document accordingly. Or maybe we don’t?

+

+
+

00.1 Forbidden Characters

+
+

Identifiers

+

In any Identifier of any kind, never use the following unless absolutely forced to:

+
    +
  • White space of any kind
  • +
  • Backward slashes \
  • +
  • Symbols i.e. #!@$%
  • +
  • Any Unicode character
  • +
+

Any Identifier should strive to only have the following characters when possible (the [A-Za-z0-9_]+)

+
    +
  • ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • +
  • abcdefghijklmnopqrstuvwxyz
  • +
  • 1234567890
  • +
  • _ (sparingly)
  • +
+

The reasoning for this is this will ensure the greatest compatibility of all data across all platforms across all tools, and help prevent downtime due to potentially bad character handling for identifiers in code you don’t control.

+

+
+
+
+
+

Table of Contents

+
+
    +
  1. Asset Naming Conventions
  2. +
  3. Directory Structure
  4. +
  5. Blueprints
  6. +
  7. Static Meshes
  8. +
  9. Particle Systems
  10. +
  11. Levels / Maps
  12. +
  13. Textures
  14. +
+
+

+

+
+
+

1. Asset Naming Conventions

+

Naming conventions should be treated as law. A project that conforms to a naming convention is able to have its assets managed, searched, parsed, and maintained with incredible ease.

+

Most things are prefixed with prefixes being generally an acronym of the asset type followed by an underscore.

+

+

+
+

1.1 Base Asset Name - Prefix_BaseAssetName_Variant_Suffix

+

All assets should have a Base Asset Name. A Base Asset Name represents a logical grouping of related assets. Any asset that is part of this logical group should follow the standard of Prefix_BaseAssetName_Variant_Suffix.

+

Keeping the pattern Prefix_BaseAssetName_Variant_Suffix and in mind and using common sense is generally enough to warrant good asset names. Here are some detailed rules regarding each element.

+

Prefix and Suffix are to be determined by the asset type through the following Asset Name Modifier tables.

+

BaseAssetName should be determined by a short and easily recognizable name related to the context of this group of assets. For example, if you had a character named Bob, all of Bob’s assets would have the BaseAssetName of Bob.

+

For unique and specific variations of assets, Variant is either a short and easily recognizable name that represents logical grouping of assets that are a subset of an asset’s base name. For example, if Bob had multiple skins these skins should still use Bob as the BaseAssetName but include a recognizable Variant. An ‘Evil’ skin would be referred to as Bob_Evil and a ‘Retro’ skin would be referred to as Bob_Retro.

+

For unique but generic variations of assets, Variant is a two digit number starting at 01. For example, if you have an environment artist generating nondescript rocks, they would be named Rock_01, Rock_02, Rock_03, etc. Except for rare exceptions, you should never require a three digit variant number. If you have more than 100 assets, you should consider organizing them with different base names or using multiple variant names.

+

Depending on how your asset variants are made, you can chain together variant names. For example, if you are creating flooring assets for an Arch Viz project you should use the base name Flooring with chained variants such as Flooring_Marble_01, Flooring_Maple_01, Flooring_Tile_Squares_01.

+

+
+

1.1 Examples

+
+
1.1e1 Bob
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypeAsset Name
Skeletal MeshSK_Bob
MaterialM_Bob
Texture (Diffuse/Albedo)T_Bob_D
Texture (Normal)T_Bob_N
Texture (Evil Diffuse)T_Bob_Evil_D
+
+
+
1.1e2 Rocks
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypeAsset Name
Static Mesh (01)S_Rock_01
Static Mesh (02)S_Rock_02
Static Mesh (03)S_Rock_03
MaterialM_Rock
Material Instance (Snow)MI_Rock_Snow
+

+

+
+
+
+
+

1.2 Asset Name Modifiers

+

When naming an asset, use these tables to determine the prefix and suffix to use with an asset’s Base Asset Name.

+
+

Sections

+
+

1.2.1 Most Common

+
+
+

1.2.2 Animations

+
+
+

1.2.3 Artificial Intelligence

+
+
+

1.2.4 Blueprints

+
+
+

1.2.5 Materials

+
+
+

1.2.6 Textures

+
+
+

1.2.7 Miscellaneous

+
+
+

1.2.8 Paper 2D

+
+
+

1.2.9 Physics

+
+
+

1.2.10 Sound

+
+
+

1.2.11 User Interface

+
+
+

1.2.12 Effects

+
+

+

+
+
+

1.2.1 Most Common

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Level / MapShould be in a folder called Maps.
Level (Persistent)_P
Level (Audio)_Audio
Level (Lighting)_Lighting
Level (Geometry)_Geo
Level (Gameplay)_Gameplay
BlueprintBP_
MaterialM_
Static MeshS_Many use SM_. We use S_.
Skeletal MeshSK_
TextureT__?See Textures
Particle SystemPS_
Widget BlueprintWBP_
+

+

+
+
+

1.2.2 Animations

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Aim OffsetAO_
Aim Offset 1DAO_
Animation BlueprintABP_
Animation CompositeAC_
Animation MontageAM_
Animation SequenceA_
Blend SpaceBS_
Blend Space 1DBS_
Level SequenceLS_
Morph TargetMT_
Paper FlipbookPFB_
RigRig_
Control RigCR_
Skeletal MeshSK_
SkeletonSKEL_
+

+

+
+
+
+

1.2.3 Artificial Intelligence

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
AI ControllerAIC_
Behavior TreeBT_
BlackboardBB_
DecoratorBTDecorator_
ServiceBTService_
TaskBTTask_
Environment QueryEQS_
EnvQueryContextEQS_Context
+

+

+
+
+

1.2.4 Blueprints

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
BlueprintBP_
Blueprint ComponentBP_ComponentI.e. BP_InventoryComponent
Blueprint Function LibraryBPFL_
Blueprint InterfaceBPI_
Blueprint Macro LibraryBPML_Do not use macro libraries if possible.
EnumerationENo underscore.
StructureF or SNo underscore.
Tutorial BlueprintTBP_
Widget BlueprintWBP_
+

+

+
+
+

1.2.5 Materials

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
MaterialM_
Material (Post Process)PP_
Material FunctionMF_
Material InstanceMI_
Material Parameter CollectionMPC_
Subsurface ProfileSP_
Physical MaterialsPM_
DecalM_, MI__Decal
+

+

+
+
+

1.2.6 Textures

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
TextureT_
Texture (Diffuse/Albedo/Base Color)T__D
Texture (Normal)T__N
Texture (Roughness)T__R
Texture (Alpha/Opacity)T__A
Texture (Ambient Occlusion)T__O
Texture (Bump)T__B
Texture (Emissive)T__E
Texture (Mask)T__M
Texture (Specular)T__S
Texture (Metallic)T__M
Texture (Packed)T__*See notes below about packing.
Texture CubeTC_
Media TextureMT_
Render TargetRT_
Cube Render TargetRTC_
Texture Light ProfileTLP
+

+

+
+

1.2.6.1 Texture Packing

+

It is common practice to pack multiple layers of texture data into one texture. An example of this is packing Emissive, Roughness, Ambient Occlusion together as the Red, Green, and Blue channels of a texture respectively. To determine the suffix, simply stack the given suffix letters from above together, e.g. _ERO.

+
+

It is generally acceptable to include an Alpha/Opacity layer in your Diffuse/Albedo’s alpha channel and as this is common practice, adding A to the _D suffix is optional.

+
+

Packing 4 channels of data into a texture (RGBA) is not recommended except for an Alpha/Opacity mask in the Diffuse/Albedo’s alpha channel as a texture with an alpha channel incurs more overhead than one without.

+

+

+
+
+
+

1.2.7 Miscellaneous

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Animated Vector FieldVFA_
Camera AnimCA_
Color CurveCurve__Color
Curve TableCurve__Table
Data Asset*_Prefix should be based on class.
Data TableDT_
Float CurveCurve__Float
Foliage TypeFT_
Force Feedback EffectFFE_
Landscape Grass TypeLG_
Landscape LayerLL_
Matinee DataMatinee_
Media PlayerMP_
Object LibraryOL_
RedirectorThese should be fixed up ASAP.
Sprite SheetSS_
Static Vector FieldVF_
Substance Graph InstanceSGI_
Substance Instance FactorySIF_
Touch Interface SetupTI_
Vector CurveCurve__Vector
+

+

+
+
+

1.2.8 Paper 2D

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Paper FlipbookPFB_
SpriteSPR_
Sprite Atlas GroupSPRG_
Tile MapTM_
Tile SetTS_
+

+

+
+
+

1.2.9 Physics

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Physical MaterialPM_
Physics AssetPHYS_
Destructible MeshDM_
+

+

+
+
+

1.2.10 Sounds

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Dialogue VoiceDV_
Dialogue WaveDW_
Media Sound WaveMSW_
Reverb EffectReverb_
Sound AttenuationATT_
Sound ClassNo prefix/suffix. Should be put in a folder called SoundClasses
Sound Concurrency_SCShould be named after a SoundClass
Sound CueA__Cue
Sound MixMix_
Sound WaveA_
+

+

+
+
+

1.2.11 User Interface

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
FontFont_
Slate BrushBrush_
Slate Widget StyleStyle_
Widget BlueprintWBP_
+

+

+
+
+

1.2.12 Effects

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + +
Asset TypePrefixSuffixNotes
Particle SystemPS_
Material (Post Process)PP_
+

⬆ Back to Top

+

+

+
+
+
+

2. Content Directory Structure

+

Equally important as asset names, the directory structure style of a project should be considered law. Asset naming conventions and content directory structure go hand in hand, and a violation of either causes unneeded chaos.

+

There are multiple ways to lay out the content of a UE4 project. In this style, we will be using a structure that relies more on filtering and search abilities of the Content Browser for those working with assets to find assets of a specific type instead of another common structure that groups asset types with folders.

+
+

If you are using the prefix naming convention above, using folders to contain assets of similar types such as Meshes, Textures, and Materials is a redundant practice as asset types are already both sorted by prefix as well as able to be filtered in the content browser.

+
+ ### 2e1 Example Project Content Structure +
|-- Content
+    |-- GenericShooter
+
+        |-- Art
+        |   |-- Industrial
+        |   |   |-- Ambient
+        |   |   |-- Machinery
+        |   |   |-- Pipes
+        |   |-- Nature
+        |   |   |-- Ambient
+        |   |   |-- Foliage
+        |   |   |-- Rocks
+        |   |   |-- Trees
+        |   |-- Office
+        |-- Characters
+        |   |-- Bob
+        |   |-- Common
+        |   |   |-- Animations
+
+        |   |   |-- Audio
+        |   |-- Jack
+        |   |-- Steve
+        |   |-- Zoe
+
+        |-- Core
+
+        |   |-- Characters
+        |   |-- Engine
+        |   |-- GameModes
+
+        |   |-- Interactables
+        |   |-- Pickups
+        |   |-- Weapons
+        |-- Effects
+        |   |-- Electrical
+        |   |-- Fire
+        |   |-- Weather
+        |-- Maps
+
+        |   |-- Campaign1
+        |   |-- Campaign2
+        |-- MaterialLibrary
+
+        |   |-- Debug
+        |   |-- Metal
+        |   |-- Paint
+        |   |-- Utility
+        |   |-- Weathering
+        |-- Placeables
+        |   |-- Pickups
+        |-- Weapons
+            |-- Common
+            |-- Pistols
+            |   |-- DesertEagle
+            |   |-- RocketPistol
+            |-- Rifles
+
+

The reasons for this structure are listed in the following sub-sections.

+
+

Sections

+
+

2.1 Folder Names

+
+
+

2.2 Top-Level Folders

+
+
+

2.3 Developer Folders

+
+
+

2.4 Maps

+
+
+

2.5 Core

+
+
+

2.6 Assets and AssetTypes

+
+
+

2.7 Large Sets

+
+
+

2.8 Material Library

+
+

+

### 2.1 Folder Names

+

These are common rules for naming any folder in the content structure.

+

+
+

2.1.1 Always Use PascalCase*

+

PascalCase refers to starting a name with a capital letter and then instead of using spaces, every following word also starts with a capital letter. For example, DesertEagle, RocketPistol, and ASeriesOfWords.

+

See Cases.

+

+
+
+

2.1.2 Never Use Spaces

+

Re-enforcing 2.1.1, never use spaces. Spaces can cause various engineering tools and batch processes to fail. Ideally, your project’s root also contains no spaces and is located somewhere such as D:\Project instead of C:\Users\My Name\My Documents\Unreal Projects.

+

+
+
+

2.1.3 Never Use Unicode Characters And Other Symbols

+

If one of your game characters is named ‘Zoë’, its folder name should be Zoe. Unicode characters can be worse than Spaces for engineering tool and some parts of UE4 don’t support Unicode characters in paths either.

+

Related to this, if your project has unexplained issues and your computer’s user name has a Unicode character (i.e. your name is Zoë), any project located in your My Documents folder will suffer from this issue. Often simply moving your project to something like D:\Project will fix these mysterious issues.

+

Using other characters outside a-z, A-Z, and 0-9 such as @, -, _, ,, *, and # can also lead to unexpected and hard to track issues on other platforms, source control, and weaker engineering tools.

+

+

### 2.2 Use A Top Level Folder For Project Specific Assets

+

All of a project’s assets should exist in a folder named after the project. For example, if your project is named ‘Generic Shooter’, all of it’s content should exist in Content/GenericShooter.

+
+

The Developers folder is not for assets that your project relies on and therefore is not project specific. See Developer Folders for details about this.

+
+

There are multiple reasons for this approach.

+

+
+
+

2.2.1 No Global Assets

+

Often in code style guides it is written that you should not pollute the global namespace and this follows the same principle. When assets are allowed to exist outside of a project folder, it often becomes much harder to enforce a strict structure layout as assets not in a folder encourages the bad behavior of not having to organize assets.

+

Every asset should have a purpose, otherwise it does not belong in a project. If an asset is an experimental test and shouldn’t be used by the project it should be put in a Developer folder.

+

+
+
+

2.2.2 Reduce Migration Conflicts

+

When working on multiple projects it is common for a team to copy assets from one project to another if they have made something useful for both. When this occurs, the easiest way to perform the copy is to use the Content Browser’s Migrate functionality as it will copy over not just the selected asset but all of its dependencies.

+

These dependencies are what can easily get you into trouble. If two project’s assets do not have a top level folder and they happen to have similarly named or already previously migrated assets, a new migration can accidentally wipe any changes to the existing assets.

+

This is also the primary reason why Epic’s Marketplace staff enforces the same policy for submitted assets.

+

After a migration, safe merging of assets can be done using the ‘Replace References’ tool in the content browser with the added clarity of assets not belonging to a project’s top level folder are clearly pending a merge. Once assets are merged and fully migrated, there shouldn’t be another top level folder in your Content tree. This method is 100% guaranteed to make any migrations that occur completely safe.

+

+
+
2.2.2e1 Master Material Example
+

For example, say you created a master material in one project that you would like to use in another project so you migrated that asset over. If this asset is not in a top level folder, it may have a name like Content/MaterialLibrary/M_Master. If the target project doesn’t have a master material already, this should work without issue.

+

As work on one or both projects progress, their respective master materials may change to be tailored for their specific projects due to the course of normal development.

+

The issue comes when, for example, an artist for one project created a nice generic modular set of static meshes and someone wants to include that set of static meshes in the second project. If the artist who created the assets used material instances based on Content/MaterialLibrary/M_Master as they’re instructed to, when a migration is performed there is a great chance of conflict for the previously migrated Content/MaterialLibrary/M_Master asset.

+

This issue can be hard to predict and hard to account for. The person migrating the static meshes may not be the same person who is familiar with the development of both project’s master material, and they may not be even aware that the static meshes in question rely on material instances which then rely on the master material. The Migrate tool requires the entire chain of dependencies to work however, and so it will be forced to grab Content/MaterialLibrary/M_Master when it copies these assets to the other project and it will overwrite the existing asset.

+

It is at this point where if the master materials for both projects are incompatible in any way, you risk breaking possibly the entire material library for a project as well as any other dependencies that may have already been migrated, simply because assets were not stored in a top level folder. The simple migration of static meshes now becomes a very ugly task.

+

+
+
+
+

2.2.3 Samples, Templates, and Marketplace Content Are Risk-Free

+

An extension to 2.2.2, if a team member decides to add sample content, template files, or assets they bought from the marketplace, it is guaranteed, as long your project’s top-level folder is uniquely named,that these new assets will not interfere with your project.

+

You can not trust marketplace content to fully conform to the top level folder rule. There exists many assets that have the majority of their content in a top level folder but also have possibly modified Epic sample content as well as level files polluting the global Content folder.

+

When adhering to 2.2, the worst marketplace conflict you can have is if two marketplace assets both have the same Epic sample content. If all your assets are in a project specific folder, including sample content you may have moved into your folder, your project will never break.

+
+
+

2.2.4 DLC, Sub-Projects, and Patches Are Easily Maintained

+

If your project plans to release DLC or has multiple sub-projects associated with it that may either be migrated out or simply not cooked in a build, assets relating to these projects should have their own separate top level content folder. This make cooking DLC separate from main project content far easier. Sub-projects can also be migrated in and out with minimal effort. If you need to change a material of an asset or add some very specific asset override behavior in a patch, you can easily put these changes in a patch folder and work safely without the chance of breaking the core project.

+

+

+
+
+
+

2.3 Use Developers Folder For Local Testing

+

During a project’s development, it is very common for team members to have a sort of ‘sandbox’ where they can experiment freely without risking the core project. Because this work may be ongoing, these team members may wish to put their assets on a project’s source control server. Not all teams require use of Developer folders, but ones that do use them often run into a common problem with assets submitted to source control.

+

It is very easy for a team member to accidentally use assets that are not ready for use, which will cause issues once those assets are removed. For example, an artist may be iterating on a modular set of static meshes and still working on getting their sizing and grid snapping correct. If a world builder sees these assets in the main project folder, they might use them all over a level not knowing they could be subject to incredible change and/or removal. This causes massive amounts of re-working for everyone on the team to resolve.

+

If these modular assets were placed in a Developer folder, the world builder should never have had a reason to use them and the whole issue would never happen. The Content Browser has specific View Options that will hide Developer folders (they are hidden by default) making it impossible to accidentally use Developer assets under normal use.

+

Once the assets are ready for use, an artist simply has to move the assets into the project specific folder and fix up redirectors. This is essentially ‘promoting’ the assets from experimental to production.

+

+

+
+
+

2.4 All Map* Files Belong In A Folder Called Maps

+

Map files are incredibly special and it is common for every project to have its own map naming system, especially if they work with sub-levels or streaming levels. No matter what system of map organization is in place for the specific project, all levels should belong in /Content/Project/Maps.

+

Being able to tell someone to open a specific map without having to explain where it is is a great time saver and general ‘quality of life’ improvement. It is common for levels to be within sub-folders of Maps, such as Maps/Campaign1/ or Maps/Arenas, but the most important thing here is that they all exist within /Content/Project/Maps.

+

This also simplifies the job of cooking for engineers. Wrangling levels for a build process can be extremely frustrating if they have to dig through arbitrary folders for them. If a team’s maps are all in one place, it is much harder to accidentally not cook a map in a build. It also simplifies lighting build scripts as well as QA processes.

+

+

+
+
+

2.5 Use A Core Folder For Critical Blueprints And Other Assets

+

Use /Content/Project/Core folder for assets that are absolutely fundamental to a project’s workings. For example, base GameMode, Character, PlayerController, GameState, PlayerState, and related Blueprints should live here.

+

This creates a very clear “don’t touch these” message for other team members. Non-engineers should have very little reason to enter the Core folder. Following good code structure style, designers should be making their gameplay tweaks in child classes that expose functionality. World builders should be using prefab Blueprints in designated folders instead of potentially abusing base classes.

+

For example, if your project requires pickups that can be placed in a level, there should exist a base Pickup class in Core/Pickups that defines base behavior for a pickup. Specific pickups such as a Health or Ammo should exist in a folder such as /Content/Project/Placeables/Pickups/. Game designers can define and tweak pickups in this folder however they please, but they should not touch Core/Pickups as they may unintentionally break pickups project-wide.

+

+

+
+
+

2.6 Do Not Create Folders Called Assets or AssetTypes

+

+
+

2.6.1 Creating a folder named Assets is redundant.

+

All assets are assets.

+

+
+
+

2.6.2 Creating a folder named Meshes, Textures, or Materials is redundant.

+

All asset names are named with their asset type in mind. These folders offer only redundant information and the use of these folders can easily be replaced with the robust and easy to use filtering system the Content Browser provides.

+

Want to view only static mesh in Environment/Rocks/? Simply turn on the Static Mesh filter. If all assets are named correctly, they will also be sorted in alphabetical order regardless of prefixes. Want to view both static meshes and skeletal meshes? Simply turn on both filters. This eliminates the need to potentially have to Control-Click select two folders in the Content Browser’s tree view.

+
+

This also extends the full path name of an asset for very little benefit. The S_ prefix for a static mesh is only two characters, whereas Meshes/ is seven characters.

+
+

Not doing this also prevents the inevitability of someone putting a static mesh or a texture in a Materials folder.

+

+

+
+
+
+

2.7 Very Large Asset Sets Get Their Own Folder Layout

+

This can be seen as a pseudo-exception to 2.6.

+

There are certain asset types that have a huge volume of related files where each asset has a unique purpose. The two most common are Animation and Audio assets. If you find yourself having 15+ of these assets that belong together, they should be together.

+

For example, animations that are shared across multiple characters should lay in Characters/Common/Animations and may have sub-folders such as Locomotion or Cinematic.

+
+

This does not apply to assets like textures and materials. It is common for a Rocks folder to have a large amount of textures if there are a large amount of rocks, however these textures are generally only related to a few specific rocks and should be named appropriately. Even if these textures are part of a Material Library.

+
+

+

+
+
+

2.8 MaterialLibrary

+

If your project makes use of master materials, layered materials, or any form of reusable materials or textures that do not belong to any subset of assets, these assets should be located in Content/Project/MaterialLibrary.

+

This way all ‘global’ materials have a place to live and are easily located.

+
+

This also makes it incredibly easy to enforce a ‘use material instances only’ policy within a project. If all artists and assets should be using material instances, then the only regular material assets that should exist are within this folder. You can easily verify this by searching for base materials in any folder that isn’t the MaterialLibrary.

+
+

The MaterialLibrary doesn’t have to consist of purely materials. Shared utility textures, material functions, and other things of this nature should be stored here as well within folders that designate their intended purpose. For example, generic noise textures should be located in MaterialLibrary/Utility.

+

Any testing or debug materials should be within MaterialLibrary/Debug. This allows debug materials to be easily stripped from a project before shipping and makes it incredibly apparent if production assets are using them if reference errors are shown.

+

+

+
+
+

2.9 No Empty Folders

+

There simply shouldn’t be any empty folders. They clutter the content browser.

+

If you find that the content browser has an empty folder you can’t delete, you should perform the following: 1. Be sure you’re using source control. 1. Immediately run Fix Up Redirectors on your project. 1. Navigate to the folder on-disk and delete the assets inside. 1. Close the editor. 1. Make sure your source control state is in sync (i.e. if using Perforce, run a Reconcile Offline Work on your content directory) 1. Open the editor. Confirm everything still works as expected. If it doesn’t, revert, figure out what went wrong, and try again. 1. Ensure the folder is now gone. 1. Submit changes to source control.

+

⬆ Back to Top

+

+

+
+
+
+

3. Blueprints

+

This section will focus on Blueprint classes and their internals. When possible, style rules conform to Epic’s Coding Standard.

+

Remember: Blueprinting badly bears blunders, beware! (Phrase by KorkuVeren)

+
+

Sections

+
+

3.1 Compiling

+
+
+

3.2 Variables

+
+
+

3.3 Functions

+
+
+

3.4 Graphs

+
+

+

+
+
+

3.1 Compiling

+

All blueprints should compile with zero warnings and zero errors. You should fix blueprint warnings and errors immediately as they can quickly cascade into very scary unexpected behavior.

+

Do not submit broken blueprints to source control. If you must store them on source control, shelve them instead.

+

Broken blueprints can cause problems that manifest in other ways, such as broken references, unexpected behavior, cooking failures, and frequent unneeded recompilation. A broken blueprint has the power to break your entire game.

+

+

+
+
+

3.2 Variables

+

The words variable and property may be used interchangeably.

+
+

Sections

+
+

3.2.1 Naming

+
+
+

3.2.2 Editable

+
+
+

3.2.3 Categories

+
+
+

3.2.4 Access

+
+
+

3.2.5 Advanced

+
+
+

3.2.6 Transient

+
+
+

3.2.7 Config

+
+

+

+
+
+

3.2.1 Naming

+

+

+
+
3.2.1.1 Nouns
+

All non-boolean variable names must be clear, unambiguous, and descriptive nouns.

+

+

+
+
+
3.2.1.2 PascalCase
+

All non-boolean variables should be in the form of PascalCase.

+

+
+
3.2.1.2e Examples:
+
    +
  • Score
  • +
  • Kills
  • +
  • TargetPlayer
  • +
  • Range
  • +
  • CrosshairColor
  • +
  • AbilityID
  • +
+

+

+
+
+
+
3.2.1.3 Boolean b Prefix
+

All booleans should be named in PascalCase but prefixed with a lowercase b.

+

Example: Use bDead and bEvil, not Dead and Evil.

+

UE4 Blueprint editors know not to include the b in user-friendly displays of the variable.

+

+

+
+
+
3.2.1.4 Boolean Names
+

+
+
3.2.1.4.1 General And Independent State Information
+

All booleans should be named as descriptive adjectives when possible if representing general information. Do not include words that phrase the variable as a question, such as Is. This is reserved for functions.

+

Example: Use bDead and bHostile not bIsDead and bIsHostile.

+

Try to not use verbs such as bRunning. Verbs tend to lead to complex states.

+

+
+
+
3.2.1.4.2 Complex States
+

Do not to use booleans to represent complex and/or dependent states. This makes state adding and removing complex and no longer easily readable. Use an enumeration instead.

+

Example: When defining a weapon, do not use bReloading and bEquipping if a weapon can’t be both reloading and equipping. Define an enumeration named EWeaponState and use a variable with this type named WeaponState instead. This makes it far easier to add new states to weapons.

+

Example: Do not use bRunning if you also need bWalking or bSprinting. This should be defined as an enumeration with clearly defined state names.

+

+

+
+
+
+
3.2.1.5 Considered Context
+

All variable names must not be redundant with their context as all variable references in Blueprint will always have context.

+

+
+
3.2.1.5e Examples:
+

Consider a Blueprint called BP_PlayerCharacter.

+

Bad

+
    +
  • PlayerScore
  • +
  • PlayerKills
  • +
  • MyTargetPlayer
  • +
  • MyCharacterName
  • +
  • CharacterSkills
  • +
  • ChosenCharacterSkin
  • +
+

All of these variables are named redundantly. It is implied that the variable is representative of the BP_PlayerCharacter it belongs to because it is BP_PlayerCharacter that is defining these variables.

+

Good

+
    +
  • Score
  • +
  • Kills
  • +
  • TargetPlayer
  • +
  • Name
  • +
  • Skills
  • +
  • Skin
  • +
+

+

+
+
+
+
3.2.1.6 Do Not Include Atomic Type Names
+

Atomic or primitive variables are variables that represent data in their simplest form, such as booleans, integers, floats, and enumerations.

+

Strings and vectors are considered atomic in terms of style when working with Blueprints, however they are technically not atomic.

+
+

While vectors consist of three floats, vectors are often able to be manipulated as a whole, same with rotators.

+
+
+

Do not consider Text variables as atomic, they are secretly hiding localization functionality. The atomic type of a string of characters is String, not Text.

+
+

Atomic variables should not have their type name in their name.

+

Example: Use Score, Kills, and Description not ScoreFloat, FloatKills, DescriptionString.

+

The only exception to this rule is when a variable represents ‘a number of’ something to be counted and when using a name without a variable type is not easy to read.

+

Example: A fence generator needs to generate X number of posts. Store X in NumPosts or PostsCount instead of Posts as Posts may potentially read as an Array of a variable type named Post.

+

+

+
+
+
3.2.1.7 Do Include Non-Atomic Type Names
+

Non-atomic or complex variables are variables that represent data as a collection of atomic variables. Structs, Classes, Interfaces, and primitives with hidden behavior such as Text and Name all qualify under this rule.

+
+

While an Array of an atomic variable type is a list of variables, Arrays do not change the ‘atomicness’ of a variable type.

+
+

These variables should include their type name while still considering their context.

+

If a class owns an instance of a complex variable, i.e. if a BP_PlayerCharacter owns a BP_Hat, it should be stored as the variable type as without any name modifications.

+

Example: Use Hat, Flag, and Ability not MyHat, MyFlag, and PlayerAbility.

+

If a class does not own the value a complex variable represents, you should use a noun along with the variable type.

+

Example: If a BP_Turret has the ability to target a BP_PlayerCharacter, it should store its target as TargetPlayer as when in the context of BP_Turret it should be clear that it is a reference to another complex variable type that it does not own.

+

+

+
+
+
3.2.1.8 Arrays
+

Arrays follow the same naming rules as above, but should be named as a plural noun.

+

Example: Use Targets, Hats, and EnemyPlayers, not TargetList, HatArray, EnemyPlayerArray.

+

+

+
+
+
+

3.2.2 Editable Variables

+

All variables that are safe to change the value of in order to configure behavior of a blueprint should be marked as Editable.

+

Conversely, all variables that are not safe to change or should not be exposed to designers should not be marked as editable, unless for engineering reasons the variable must be marked as Expose On Spawn.

+

Do not arbitrarily mark variables as Editable.

+

+

+
+
3.2.2.1 Tooltips
+

All Editable variables, including those marked editable just so they can be marked as Expose On Spawn, should have a description in their Tooltip fields that explains how changing this value affects the behavior of the blueprint.

+

+

+
+
+
3.2.2.2 Slider And Value Ranges
+

All Editable variables should make use of slider and value ranges if there is ever a value that a variable should not be set to.

+

Example: A blueprint that generates fence posts might have an editable variable named PostsCount and a value of -1 would not make any sense. Use the range fields to mark 0 as a minimum.

+

If an editable variable is used in a Construction Script, it should have a reasonable Slider Range defined so that someone can not accidentally assign it a large value that could crash the editor.

+

A Value Range only needs to be defined if the bounds of a value are known. While a Slider Range prevents accidental large number inputs, an undefined Value Range allows a user to specify a value outside the Slider Range that may be considered ‘dangerous’ but still valid.

+

+

+
+
+
+

3.2.3 Categories

+

If a class has only a small number of variables, categories are not required.

+

If a class has a moderate amount of variables (5-10), all Editable variables should have a non-default category assigned. A common category is Config.

+

If a class has a large amount of variables, all Editable variables should be categorized into sub-categories using the category Config as the base category. Non-editable variables should be categorized into descriptive categories describing their usage.

+
+

You can define sub-categories by using the pipe character |, i.e. Config | Animations.

+
+

Example: A weapon class set of variables might be organized as:

+
|-- Config
+|   |-- Animations
+|   |-- Effects
+|   |-- Audio
+|   |-- Recoil
+|   |-- Timings
+|-- Animations
+|-- State
+|-- Visuals
+

+

+
+
+

3.2.4 Variable Access Level

+

In C++, variables have a concept of access level. Public means any code outside the class can access the variable. Protected means only the class and any child classes can access this variable internally. Private means only this class and no child classes can access this variable.

+

Blueprints do not have a defined concept of protected access currently.

+

Treat Editable variables as public variables. Treat non-editable variables as protected variables.

+

+

+
+
3.2.4.1 Private Variables
+

Unless it is known that a variable should only be accessed within the class it is defined and never a child class, do not mark variables as private. Until variables are able to be marked protected, reserve private for when you absolutely know you want to restrict child class usage.

+

+

+
+
+
+

3.2.5 Advanced Display

+

If a variable should be editable but often untouched, mark it as Advanced Display. This makes the variable hidden unless the advanced display arrow is clicked.

+

To find the Advanced Display option, it is listed as an advanced displayed variable in the variable details list.

+

+

+
+
+

3.2.6 Transient Variables

+

Transient variables are variables that do not need to have their value saved and loaded and have an initial value of zero or null. This is useful for references to other objects and actors who’s value isn’t known until run-time. This prevents the editor from ever saving a reference to it, and speeds up saving and loading of the blueprint class.

+

Because of this, all transient variables should always be initialized as zero or null. To do otherwise would result in hard to debug errors.

+

+

+
+
+

3.2.8 Config Variables

+

Do not use the Config Variable flag. This makes it harder for designers to control blueprint behavior. Config variables should only be used in C++ for rarely changed variables. Think of them as Advanced Advanced Display variables.

+

+

+
+
+
+

3.3 Functions, Events, and Event Dispatchers

+

This section describes how you should author functions, events, and event dispatchers. Everything that applies to functions also applies to events, unless otherwise noted.

+

+

+
+

3.3.1 Function Naming

+

The naming of functions, events, and event dispatchers is critically important. Based on the name alone, certain assumptions can be made about functions. For example:

+
    +
  • Is it a pure function?
  • +
  • Is it fetching state information?
  • +
  • Is it a handler?
  • +
  • Is it an RPC?
  • +
  • What is its purpose?
  • +
+

These questions and more can all be answered when functions are named appropriately.

+

+

+
+
+

3.3.1.1 All Functions Should Be Verbs

+

All functions and events perform some form of action, whether its getting info, calculating data, or causing something to explode. Therefore, all functions should all start with verbs. They should be worded in the present tense whenever possible. They should also have some context as to what they are doing.

+

OnRep functions, event handlers, and event dispatchers are an exception to this rule.

+

Good examples:

+
    +
  • Fire - Good example if in a Character / Weapon class, as it has context. Bad if in a Barrel / Grass / any ambiguous class.
  • +
  • Jump - Good example if in a Character class, otherwise, needs context.
  • +
  • Explode
  • +
  • ReceiveMessage
  • +
  • SortPlayerArray
  • +
  • GetArmOffset
  • +
  • GetCoordinates
  • +
  • UpdateTransforms
  • +
  • EnableBigHeadMode
  • +
  • IsEnemy - “Is” is a verb.
  • +
+

Bad examples:

+
    +
  • Dead - Is Dead? Will deaden?
  • +
  • Rock
  • +
  • ProcessData - Ambiguous, these words mean nothing.
  • +
  • PlayerState - Nouns are ambiguous.
  • +
  • Color - Verb with no context, or ambiguous noun.
  • +
+

+

+
+
+

3.3.1.2 Property RepNotify Functions Always OnRep_Variable

+

All functions for replicated with notification variables should have the form OnRep_Variable. This is forced by the Blueprint editor. If you are writing a C++ OnRep function however, it should also follow this convention when exposing it to Blueprints.

+

+

+
+
+

3.3.1.3 Info Functions Returning Bool Should Ask Questions

+

When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow the verb rule.

+

This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded.

+

Good examples:

+ +

Bad examples:

+
    +
  • Fire - Is on fire? Will fire? Do fire?
  • +
  • OnFire - Can be confused with event dispatcher for firing.
  • +
  • Dead - Is dead? Will deaden?
  • +
  • Visibility - Is visible? Set visibility? A description of flying conditions?
  • +
+

+

+
+
+

3.3.1.4 Event Handlers and Dispatchers Should Start With On

+

Any function that handles an event or dispatches an event should start with On and continue to follow the verb rule. The verb may move to the end however if past-tense reads better.

+

Collocations of the word On are exempt from following the verb rule.

+

Handle is not allowed. It is ‘Unreal’ to use On instead of Handle, while other frameworks may prefer to use Handle instead of On.

+

Good examples:

+
    +
  • OnDeath - Common collocation in games
  • +
  • OnPickup
  • +
  • OnReceiveMessage
  • +
  • OnMessageRecieved
  • +
  • OnTargetChanged
  • +
  • OnClick
  • +
  • OnLeave
  • +
+

Bad examples:

+
    +
  • OnData
  • +
  • OnTarget
  • +
  • HandleMessage
  • +
  • HandleDeath
  • +
+

+

+
+
+

3.3.1.5 Remote Procedure Calls Should Be Prefixed With Target

+

Any time an RPC is created, it should be prefixed with either Server, Client, or Multicast. No exceptions.

+

After the prefix, follow all other rules regarding function naming.

+

Good examples:

+
    +
  • ServerFireWeapon
  • +
  • ClientNotifyDeath
  • +
  • MulticastSpawnTracerEffect
  • +
+

Bad examples:

+
    +
  • FireWeapon - Does not indicate its an RPC of some kind.
  • +
  • ServerClientBroadcast - Confusing.
  • +
  • AllNotifyDeath - Use Multicast, never All.
  • +
  • ClientWeapon - No verb, ambiguous.
  • +
+

+

+
+
+

3.3.2 All Functions Must Have Return Nodes

+

All functions must have return nodes, no exceptions.

+

Return nodes explicitly note that a function has finished its execution. In a world where blueprints can be filled with Sequence, ForLoopWithBreak, and backwards reroute nodes, explicit execution flow is important for readability, maintenance, and easier debugging.

+

The Blueprint compiler is able to follow the flow of execution and will warn you if there is a branch of your code with an unhandled return or bad flow if you use return nodes.

+

In situations like where a programmer may add a pin to a Sequence node or add logic after a for loop completes but the loop iteration might return early, this can often result in an accidental error in code flow. The warnings the Blueprint compiler will alert everyone of these issues immediately.

+

+

+
+
+

3.3.3 No Function Should Have More Than 50 Nodes

+

Simply, no function should have more than 50 nodes. Any function this big should be broken down into smaller functions for readability and ease of maintenance.

+

The following nodes are not counted as they are deemed to not increase function complexity:

+
    +
  • Comment
  • +
  • Route
  • +
  • Cast
  • +
  • Getting a Variable
  • +
  • Breaking a Struct
  • +
  • Function Entry
  • +
  • Self
  • +
+

+

+
+
+

3.3.4 All Public Functions Should Have A Description

+

This rule applies more to public facing or marketplace blueprints, so that others can more easily navigate and consume your blueprint API.

+

Simply, any function that has an access specificer of Public should have its description filled out.

+

+

+
+
+

3.3.5 All Custom Static Plugin BlueprintCallable Functions Must Be Categorized By Plugin Name

+

If your project includes a plugin that defines static BlueprintCallable functions, they should have their category set to the plugin’s name or a subset category of the plugin’s name.

+

For example, Zed Camera Interface or Zed Camera Interface | Image Capturing.

+

+

+
+
+
+

3.4 Blueprint Graphs

+

This section covers things that apply to all Blueprint graphs.

+

+

+
+

3.4.1 No Spaghetti

+

Wires should have clear beginnings and ends. You should never have to mentally untangle wires to make sense of a graph. Many of the following sections are dedicated to reducing spaghetti.

+

+

+
+
+

3.4.2 Align Wires Not Nodes

+

Always align wires, not nodes. You can’t always control the size and pin location on a node, but you can always control the location of a node and thus control the wires. Straight wires provide clear linear flow. Wiggly wires wear wits wickedly. You can straighten wires by using the Straighten Connections command with BP nodes selected. Hotkey: Q

+

Good example: The tops of the nodes are staggered to keep a perfectly straight white exec line. Aligned By Wires

+

Bad Example: The tops of the nodes are aligned creating a wiggly white exec line. Bad

+

Acceptable Example: Certain nodes might not cooperate no matter how you use the alignment tools. In this situation, try to minimize the wiggle by bringing the node in closer. Acceptable

+

+

+
+
+

3.4.3 White Exec Lines Are Top Priority

+

If you ever have to decide between straightening a linear white exec line or straightening data lines of some kind, always straighten the white exec line.

+

+

+
+
+

3.4.4 Graphs Should Be Reasonably Commented

+

Blocks of nodes should be wrapped in comments that describe their higher-level behavior. While every function should be well named so that each individual node is easily readable and understandable, groups of nodes contributing to a purpose should have their purpose described in a comment block. If a function does not have many blocks of nodes and its clear that the nodes are serving a direct purpose in the function’s goal, then they do not need to be commented as the function name and description should suffice.

+

+

+
+
+

3.4.5 Graphs Should Handle Casting Errors Where Appropriate

+

If a function or event assumes that a cast always succeeds, it should appropriately report a failure in logic if the cast fails. This lets others know why something that is ‘supposed to work’ doesn’t. A function should also attempt a graceful recover after a failed cast if it’s known that the reference being casted could ever fail to be casted.

+

This does not mean every cast node should have its failure handled. In many cases, especially events regarding things like collisions, it is expected that execution flow terminates on a failed cast quietly.

+

+

+
+
+

3.4.6 Graphs Should Not Have Any Dangling / Loose / Dead Nodes

+

All nodes in all blueprint graphs must have a purpose. You should not leave dangling blueprint nodes around that have no purpose or are not executed.

+

⬆ Back to Top

+

+

+

+
+
+
+
+

4. Static Meshes

+

This section will focus on Static Mesh assets and their internals.

+
+

Sections

+
+

4.1 UVs

+
+
+

4.2 LODs

+
+
+

4.3 Modular Socketless Snapping

+
+
+

4.4 Must Have Collision

+
+
+

4.5 Correct Scale

+
+

+

+
+
+

4.1 Static Mesh UVs

+

If Linter is reporting bad UVs and you can’t seem to track it down, open the resulting .log file in your project’s Saved/Logs folder for exact details as to why it’s failing. I am hoping to include these messages in the Lint report in the future.

+

+

+
+

4.1.1 All Meshes Must Have UVs

+

Pretty simple. All meshes, regardless how they are to be used, should not be missing UVs.

+

+

+
+
+

4.1.2 All Meshes Must Not Have Overlapping UVs for Lightmaps

+

Pretty simple. All meshes, regardless how they are to be used, should have valid non-overlapping UVs.

+

+

+
+
+
+

4.2 LODs Should Be Set Up Correctly

+

This is a subjective check on a per-project basis, but as a general rule any mesh that can be seen at varying distances should have proper LODs.

+

+

+
+
+

4.3 Modular Socketless Assets Should Snap To The Grid Cleanly

+

This is a subjective check on a per-asset basis, however any modular socketless assets should snap together cleanly based on the project’s grid settings.

+

It is up to the project whether to snap based on a power of 2 grid or on a base 10 grid. However if you are authoring modular socketless assets for the marketplace, Epic’s requirement is that they snap cleanly when the grid is set to 10 units or bigger.

+

+

+
+
+

4.4 All Meshes Must Have Collision

+

Regardless of whether an asset is going to be used for collision in a level, all meshes should have proper collision defined. This helps the engine with things such as bounds calculations, occlusion, and lighting. Collision should also be well-formed to the asset.

+

+

+
+
+

4.5 All Meshes Should Be Scaled Correctly

+

This is a subjective check on a per-project basis, however all assets should be scaled correctly to their project. Level designers or blueprint authors should not have to tweak the scale of meshes to get them to confirm in the editor. Scaling meshes in the engine should be treated as a scale override, not a scale correction.

+

⬆ Back to Top

+

+

+

+
+
+
+

5. Niagara

+

This section will focus on Niagara assets and their internals.

+
+

Sections

+
+

5.1 Naming Rules

+
+

+

+
+
+

5.1 No Spaces, Ever

+

As mentioned in 00.1 Forbidden Identifiers, spaces and all white space characters are forbidden in identifiers. This is especially true for Niagara systems as it makes working with things significantly harder if not impossible when working with HLSL or other means of scripting within Niagara and trying to reference an identifier.

+

(Original Contribution by @dunenkoff)

+

⬆ Back to Top

+

+

+

+
+
+
+

6. Levels / Maps

+

See Terminology Note regarding “levels” vs “maps”.

+

This section will focus on Level assets and their internals.

+
+

Sections

+
+

6.1 No Errors Or Warnings

+
+
+

6.2 Lighting Should Be Built

+
+
+

6.3 No Player Visible Z Fighting

+
+
+

6.4 Marketplace Specific Rules

+
+

+

+
+
+

6.1 No Errors Or Warnings

+

All levels should load with zero errors or warnings. If a level loads with any errors or warnings, they should be fixed immediately to prevent cascading issues.

+

You can run a map check on an open level in the editor by using the console command “map check”.

+

Please note: Linter is even more strict on this than the editor is currently, and will catch load errors that the editor will resolve on its own.

+

+

+
+
+

6.2 Lighting Should Be Built

+

It is normal during development for levels to occasionally not have lighting built. When doing a test/internal/shipping build or any build that is to be distributed however, lighting should always be built.

+

+

+
+
+

6.3 No Player Visible Z Fighting

+

Levels should not have any z-fighting in all areas visible to the player.

+

+

+
+
+

6.4 Marketplace Specific Rules

+

If a project is to be sold on the UE4 Marketplace, it must follow these rules.

+

+

+
+
+

6.4.1 Overview Level

+

If your project contains assets that should be visualized or demoed, you must have a map within your project that contains the name “Overview”.

+

This overview map, if it is visualizing assets, should be set up according to Epic’s guidelines.

+

For example, InteractionComponent_Overview.

+

+

+
+
+

6.4.2 Demo Level

+

If your project contains assets that should be demoed or come with some sort of tutorial, you must have a map within your project that contains the name “Demo”. This level should also contain documentation within it in some form that illustrates how to use your project. See Epic’s Content Examples project for good examples on how to do this.

+

If your project is a gameplay mechanic or other form of system as opposed to an art pack, this can be the same as your “Overview” map.

+

For example, InteractionComponent_Overview_Demo, ExplosionKit_Demo.

+

⬆ Back to Top

+

+

+
+
+
+

7. Textures

+

This section will focus on Texture assets and their internals.

+
+

Sections

+
+

7.1 Dimensions Are Powers of 2

+
+
+

7.2 Texture Density Should Be Uniform

+
+
+

7.3 Textures Should Be No Bigger than 8192

+
+
+

7.4 Correct Texture Groups

+
+

+

+
+
+

7.1 Dimensions Are Powers of 2

+

All textures, except for UI textures, must have its dimensions in multiples of powers of 2. Textures do not have to be square.

+

For example, 128x512, 1024x1024, 2048x1024, 1024x2048, 1x512.

+

+

+
+
+

7.2 Texture Density Should Be Uniform

+

All textures should be of a size appropriate for their standard use case. Appropriate texture density varies from project to project, but all textures within that project should have a consistent density.

+

For example, if a project’s texture density is 8 pixel per 1 unit, a texture that is meant to be applied to a 100x100 unit cube should be 1024x1024, as that is the closest power of 2 that matches the project’s texture density.

+

+

+
+
+

7.3 Textures Should Be No Bigger than 8192

+

No texture should have a dimension that exceeds 8192 in size, unless you have a very explicit reason to do so. Often, using a texture this big is simply just a waste of resources.

+

+

+
+
+

7.4 Textures Should Be Grouped Correctly

+

Every texture has a Texture Group property used for LODing, and this should be set correctly based on its use. For example, all UI textures should belong in the UI texture group.

+

⬆ Back to Top

+ + +
+
+ +
+ +
+
+ +
+ + + + + \ No newline at end of file diff --git a/_site/sites/webservices.html b/_site/sites/webservices.html new file mode 100644 index 0000000..5deef6b --- /dev/null +++ b/_site/sites/webservices.html @@ -0,0 +1,996 @@ + + + + + + + + + +Websevices – DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Websevices

+
+ + + +
+ + + + +
+ + + +
+ + +
+

Forgejo

+

Forgejo is an open source source control system. As game development not only needs to track text files but large binaries (Images, Videos, Audio etc.), traditional providers like GitHub or GitLab might not scale or become quite pricey. This is why a self-hosted solution was set up.

+

The Forgejo instance is currently hosted on Hetzner Cloud cpx11. For storage, a 1tb Hetzner Storage Box is attached via CIFS. The Forgejo instance can be accessed on https://code.virtuos.world.

+
+

Installation on Ubuntu Server 22.04

+
    +
  • On a new server, add a new user that is not root:
  • +
+
adduser newusername
+usermod -aG sudo newusername
+sudo -i -u git newusername
+
    +
  • Create git user account and add it to the docker usergroup, then switch to the new user.
  • +
+
sudo adduser --system --shell /bin/bash -gecos 'Git Version Control' --group --disabled-password --home /home/git/ git
+sudo usermod -aG docker git
+
    +
  • Automount the storage box by editing /etc/fstab. Important: Use the UID and GID of the newly created git user! You can get them by typing id git.
  • +
+
sudo nano /etc/fstab
+
    +
  • Add this line
  • +
+
//<username>.your-storagebox.de/backup /mnt/<path> cifs iocharset=utf8,rw,credentials=/etc/backup-credentials.txt,uid=<system account>,gid=<system group>,file_mode=0660,dir_mode=0770 0 0
+

Create the credentials file…

+
sudo nano /etc/backup-credentials.txt
+

…and fill it with your username and password.

+
username=uXXXXXX
+password=yourpassword
+
    +
  • Install cifs-utils
  • +
+
apt install cifs-utils
+
    +
  • Mounting might result in an error regarding the iocharset, to fix that do:
  • +
+
apt install linux-generic
+apt install linux-modules-extra-$(uname -r)
+reboot
+
    +
  • Mount the storage
  • +
+
sudo mount -a
+
    +
  • Install docker-compose
  • +
+
sudo apt install docker-compose 
+
    +
  • Create docker directory
  • +
+
sudo mkdir ~/forgejo
+
    +
  • Create docker-compose file
  • +
+
sudo nano docker-compose.yml
+
    +
  • Paste the following content. This assumes your UID is 115 and your GID is 120. Use id -u <username> to find your values. It also maps the repository to use the storage box.
  • +
+
+

Edit: I removed - /mnt/source/git/repositories:/data/git/repositories as it’s slow and hooks won’t work on the Storage Box!

+
+
version: '3'
+
+networks:
+  forgejo:
+    external: false
+
+services:
+  server:
+    image: codeberg.org/forgejo/forgejo:1.20
+    container_name: forgejo
+    environment:
+      - USER_UID=115
+      - USER_GID=120
+    restart: always
+    networks:
+      - forgejo
+    volumes:
+      - ./forgejo:/data
+      - /etc/timezone:/etc/timezone:ro
+      - /etc/localtime:/etc/localtime:ro
+      - /mnt/source/git/lfs:/data/lfs
+
+    ports:
+      - '3000:3000'
+      - '222:22'
+

For some reason in my case, the app.ini pointed to /data/git/lfs instead of data/lfs. Fixing this resulted in actually using /mnt/source/git/lfs on the host.

+
    +
  • Install nginx
  • +
+
sudo apt install nginx
+
    +
  • Setup firewall
  • +
+
sudo ufw allow OpenSSH
+sudo ufw allow "Nginx Full"
+sudo ufw enable
+
    +
  • Open nginx config
  • +
+
sudo nano /etc/nginx/sites-available/forgejo
+
    +
  • Add:
  • +
+
server {
+    listen 80;
+    listen [::]:80;
+    server_name my.domain.tld;
+
+    location / {
+        client_max_body_size 4G;
+        proxy_pass http://localhost:3000;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real_IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+}
+

(This assumes you have registered a domain and added A and AAAA records.)

+
    +
  • Create symlink to actually enable the site
  • +
+
sudo ln -s /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/
+
    +
  • Install Certbot
  • +
+
sudo apt install snapd
+sudo snap install --classic certbot
+sudo ln -s /snap/bin/certbot /usr/bin/certbot
+
    +
  • Get Let’s Encrypt certificate. For testing, add --test-cert.
  • +
+
sudo certbot --nginx
+
    +
  • Run your docker compose
  • +
+
cd ~/forgejo
+sudo docker-compose up -d
+
    +
  • To redirect the homepage to the repository view:
  • +
+
server {
+    server_name code.virtuos.world;
+
+    location / {
+        client_max_body_size 4G;
+        proxy_pass http://localhost:3000;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real_IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+
+    location = / {
+        return 301 https://$host/explore/repos;
+    }
+
+    listen [::]:443 ssl ipv6only=on; # managed by Certbot
+    listen 443 ssl; # managed by Certbot
+    ssl_certificate /etc/letsencrypt/live/code.virtuos.world/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/code.virtuos.world/privkey.pem;
+    include /etc/letsencrypt/options-ssl-nginx.conf;
+    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
+}
+
+server {
+    if ($host = code.virtuos.world) {
+        return 301 https://$host$request_uri;
+    }
+
+    listen 80;
+    listen [::]:80;
+    server_name code.virtuos.world;
+    return 404;
+}
+

Thanks to KeepItTechie for this tutorial: https://www.youtube.com/watch?v=I4OQMc1rIO4

+
+
+

Customizing Forgejo/Gitea

+

On the host, the path starts from the folder with your docker-compose file, /forgejo/gitea/public/assets/

+

Paste the images with the respective names listed below:

+
    +
  • public/img/logo.svg - Used for site icon, app icon
    +
  • +
  • public/img/logo.png - Used for Open Graph
    +
  • +
  • public/img/avatar_default.png - Used as the default avatar image
    +
  • +
  • public/img/apple-touch-icon.png - Used on iOS devices for bookmarks
    +
  • +
  • public/img/favicon.svg - Used for favicon
    +
  • +
  • public/img/favicon.png - Used as fallback for browsers that don’t support SVG favicons
  • +
+
+
+
+
+

Leantime

+

Leantime is an open source project management system. The Leantime instance is hosted on Uberspace.de and can be accessed on https://manage.virtuos.world.

+
+

Installation on Uberspace

+
    +
  • Download latest release package, upload and untar:
  • +
+
tar -xf <name.tar.gz>
+
    +
  • Create an empty MySQL database:
  • +
+
mysql -e "CREATE DATABASE <username>_leantime"
+
    +
  • Point your domain to the public/ directory
    +Edit /leantime/public/.htaccess:
  • +
+
Options +SymLinksIfOwnerMatch
+RewriteEngine On
+RewriteBase /
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^ index.php [L]
+
    +
  • Get your MySQL credentials:
  • +
+
my_print_defaults client
+
    +
  • Fill in your database credentials (username, password, host, dbname) in config/sample.env
    +
  • +
  • Rename config/sample.env to config/.env
    +
  • +
  • Navigate to <yourdomain.com>/install
    +
  • +
  • Follow instructions to install database and set up first user account
  • +
+
+
+

Updating Leantime

+

Leantime comes with an update script in /leantime:

+
./updateLeantime.sh
+
+
+
+
+

Wordpress

+

Wordpress is an open source Content Management System (CMS). The Wordpress instance is hosted on Uberspace.de and can be accessed on https://virtuos.world.

+
+

Installation on Uberspace

+

The Wordpress installation is well documented on
+https://lab.uberspace.de/guide_wordpress/

+
+
+

Updating Wordpress

+

Wordpress updates itself. Plugins may need manual updating via the Wordpress Interface.

+
+
+
+
+

Wiki.js

+

Wiki.js is an open source Wiki software. The Wiki.js instance is hosted on Uberspace.de and you are currently accessing it on https://docs.virtuos.world.

+
+

Installation on Uberspace

+

The Wiki.js installation is well documented on
+https://lab.uberspace.de/guide_wiki-js/

+
+
+

Updating Wiki.js

+

An update script is available at the same location:
+https://lab.uberspace.de/guide_wiki-js/

+
+
+
+
+

Pretix

+

Pretix is an open source ticketing system. It’s currently not in use. This installation is not as easy, but well documented here:
+https://docs.pretix.eu/en/latest/admin/installation/docker_smallscale.html

+ + +
+ +
+ +
+
+ +
+ + + + + \ No newline at end of file diff --git a/_site/sites/webservices.pdf b/_site/sites/webservices.pdf new file mode 100644 index 0000000..4dacb5b Binary files /dev/null and b/_site/sites/webservices.pdf differ diff --git a/index.qmd b/index.qmd index 75a5c15..7fe969e 100644 --- a/index.qmd +++ b/index.qmd @@ -1,7 +1,16 @@ --- -title: "VIRTUOS WORLD Documentation" +title: "Home" + --- -This is a Quarto website. +# Welcome to the Documentation! -To learn more about Quarto websites visit . +This is the main page of your documentation. You can add more sections or documentation as you need. + +## Features + +- Easy setup +- User-friendly interface +- Rich documentation + +For more details, refer to the Getting Started section in the sidebar. diff --git a/sites/getstarted.qmd b/sites/getstarted.qmd new file mode 100644 index 0000000..27e1a23 --- /dev/null +++ b/sites/getstarted.qmd @@ -0,0 +1,23 @@ +--- +title: "Getting Started" +--- +If you want to take a look inside a project, there are currently three important repositories: + +- VIRTUOS_Playground: The repository contains the Unreal Engine Project +- VIRTUOS_Assets: Contains all Project related assets like 3D-Models, Graphics etc. +- VIRTUOS_Documents: Contains all written Documents + +# Setting up the project with UE5 + +If you're familiar with Git, you'll likely already know how to get the files. + +```bash +git pull https://code.virtuos.world/VIRTUOS_WORLD/VIRTUOS_Docs.git +``` + +If you're not comforatable with the command line, you can install a Git GUI like Github Desktop. + + +```{=html} + +``` \ No newline at end of file diff --git a/sites/overview.qmd b/sites/overview.qmd new file mode 100644 index 0000000..07c5e7f --- /dev/null +++ b/sites/overview.qmd @@ -0,0 +1,5 @@ +--- +title: "About" +--- + +About this site diff --git a/sites/styleguide.aux b/sites/styleguide.aux new file mode 100644 index 0000000..cb3ddad --- /dev/null +++ b/sites/styleguide.aux @@ -0,0 +1,31 @@ +\relax +\providecommand*\new@tpo@label[2]{} +\providecommand\hyper@newdestlabel[2]{} +\providecommand*\HyPL@Entry[1]{} +\HyPL@Entry{0<>} +\@writefile{toc}{\contentsline {subsection}{\nonumberline Important Terminology}{1}{subsection*.2}\protected@file@percent } +\newlabel{important-terminology}{{}{1}{Important Terminology}{subsection*.2}{}} +\@writefile{toc}{\contentsline {subparagraph}{\nonumberline Levels/Maps}{1}{subparagraph*.4}\protected@file@percent } +\newlabel{levelsmaps}{{}{1}{Levels/Maps}{subparagraph*.4}{}} +\@writefile{toc}{\contentsline {subparagraph}{\nonumberline Identifiers}{1}{subparagraph*.6}\protected@file@percent } +\newlabel{identifiers}{{}{1}{Identifiers}{subparagraph*.6}{}} +\@writefile{toc}{\contentsline {subparagraph}{\nonumberline Cases}{1}{subparagraph*.8}\protected@file@percent } +\newlabel{cases}{{}{1}{Cases}{subparagraph*.8}{}} +\@writefile{toc}{\contentsline {subparagraph}{\nonumberline Variables / Properties}{2}{subparagraph*.10}\protected@file@percent } +\newlabel{variables-properties}{{}{2}{Variables / Properties}{subparagraph*.10}{}} +\@writefile{toc}{\contentsline {subsection}{\nonumberline 0. Principles}{2}{subsection*.12}\protected@file@percent } +\newlabel{principles}{{}{2}{0. Principles}{subsection*.12}{}} +\@writefile{toc}{\contentsline {subsubsection}{\nonumberline 0.1 If your UE4 project already has a style guide, you should follow it.}{3}{subsubsection*.14}\protected@file@percent } +\newlabel{if-your-ue4-project-already-has-a-style-guide-you-should-follow-it.}{{}{3}{0.1 If your UE4 project already has a style guide, you should follow it}{subsubsection*.14}{}} +\@writefile{toc}{\contentsline {paragraph}{\nonumberline ``Arguments over style are pointless. There should be a style guide, and you should follow it.''}{3}{paragraph*.16}\protected@file@percent } +\newlabel{arguments-over-style-are-pointless.-there-should-be-a-style-guide-and-you-should-follow-it.}{{}{3}{``Arguments over style are pointless. There should be a style guide, and you should follow it.''}{paragraph*.16}{}} +\@writefile{toc}{\contentsline {subsubsection}{\nonumberline 0.2 All structure, assets, and code in any Unreal Engine 4 project should look like a single person created it, no matter how many people contributed.}{3}{subsubsection*.18}\protected@file@percent } +\newlabel{all-structure-assets-and-code-in-any-unreal-engine-4-project-should-look-like-a-single-person-created-it-no-matter-how-many-people-contributed.}{{}{3}{0.2 All structure, assets, and code in any Unreal Engine 4 project should look like a single person created it, no matter how many people contributed}{subsubsection*.18}{}} +\@writefile{toc}{\contentsline {subsubsection}{\nonumberline 0.3 Friends do not let friends have bad style.}{3}{subsubsection*.20}\protected@file@percent } +\newlabel{friends-do-not-let-friends-have-bad-style.}{{}{3}{0.3 Friends do not let friends have bad style}{subsubsection*.20}{}} +\@writefile{toc}{\contentsline {subsubsection}{\nonumberline 0.4 A team without a style guide is no team of mine.}{4}{subsubsection*.22}\protected@file@percent } +\newlabel{a-team-without-a-style-guide-is-no-team-of-mine.}{{}{4}{0.4 A team without a style guide is no team of mine}{subsubsection*.22}{}} +\@writefile{toc}{\contentsline {subsubsection}{\nonumberline 0.5 Don't Break The Law}{4}{subsubsection*.24}\protected@file@percent } +\newlabel{dont-break-the-law}{{}{4}{0.5 Don't Break The Law}{subsubsection*.24}{}} +\@writefile{toc}{\contentsline {subsection}{\nonumberline 00. Globally Enforced Opinions}{4}{subsection*.26}\protected@file@percent } +\newlabel{globally-enforced-opinions}{{}{4}{00. Globally Enforced Opinions}{subsection*.26}{}} diff --git a/sites/styleguide.log b/sites/styleguide.log new file mode 100644 index 0000000..4280c57 --- /dev/null +++ b/sites/styleguide.log @@ -0,0 +1,1125 @@ +This is XeTeX, Version 3.141592653-2.6-0.999996 (MiKTeX 24.4) (preloaded format=xelatex 2025.4.6) 6 APR 2025 21:07 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**./styleguide.tex +(styleguide.tex +LaTeX2e <2024-06-01> patch level 2 +L3 programming layer <2024-07-20> + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrartcl.cl +s +Document Class: scrartcl 2023/07/07 v3.41 KOMA-Script document class (article) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrkbase.st +y +Package: scrkbase 2023/07/07 v3.41 KOMA-Script package (KOMA-Script-dependent b +asics and keyval usage) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrbase.sty +Package: scrbase 2023/07/07 v3.41 KOMA-Script package (KOMA-Script-independent +basics and keyval usage) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrlfile.st +y +Package: scrlfile 2023/07/07 v3.41 KOMA-Script package (file load hooks) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrlfile-ho +ok.sty +Package: scrlfile-hook 2023/07/07 v3.41 KOMA-Script package (using LaTeX hooks) + + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrlogo.sty +Package: scrlogo 2023/07/07 v3.41 KOMA-Script package (logo) +))) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\keyval.sty +Package: keyval 2022/05/29 v1.15 key=value parser (DPC) +\KV@toks@=\toks17 +) +Applying: [2021/05/01] Usage of raw or classic option list on input line 252. +Already applied: [0000/00/00] Usage of raw or classic option list on input line + 368. +)) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\tocbasic.st +y +Package: tocbasic 2023/07/07 v3.41 KOMA-Script package (handling toc-files) +\scr@dte@tocline@numberwidth=\skip49 +\scr@dte@tocline@numbox=\box52 +) +Package tocbasic Info: omitting babel extension for `toc' +(tocbasic) because of feature `nobabel' available +(tocbasic) for `toc' on input line 133. +Class scrartcl Info: You've used standard option `oneside'. +(scrartcl) This is correct! +(scrartcl) Internally I'm using `twoside=false'. +(scrartcl) If you'd like to set the option with \KOMAoptions, +(scrartcl) you'd have to use `twoside=false' there +(scrartcl) instead of `oneside', too. +Class scrartcl Info: File `scrsize11pt.clo' used instead of +(scrartcl) file `scrsize11.clo' to setup font sizes on input line 244 +1. + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\scrsize11pt +.clo +File: scrsize11pt.clo 2023/07/07 v3.41 KOMA-Script font size class option (11pt +) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/koma-script\typearea.st +y +Package: typearea 2023/07/07 v3.41 KOMA-Script package (type area) +\ta@bcor=\skip50 +\ta@div=\count190 +Package typearea Info: You've used standard option `letterpaper'. +(typearea) This is correct! +(typearea) Internally I'm using `paper=letter'. +(typearea) If you'd like to set the option with \KOMAoptions, +(typearea) you'd have to use `paper=letter' there +(typearea) instead of `letterpaper', too. +Package typearea Info: You've used standard option `oneside'. +(typearea) This is correct! +(typearea) Internally I'm using `twoside=false'. +(typearea) If you'd like to set the option with \KOMAoptions, +(typearea) you'd have to use `twoside=false' there +(typearea) instead of `oneside', too. +\ta@hblk=\skip51 +\ta@vblk=\skip52 +\ta@temp=\skip53 +\footheight=\skip54 +Package typearea Info: These are the values describing the layout: +(typearea) DIV = 11 +(typearea) BCOR = 0.0pt +(typearea) \paperwidth = 614.295pt +(typearea) \textwidth = 446.76004pt +(typearea) DIV departure = -14% +(typearea) \evensidemargin = 11.49748pt +(typearea) \oddsidemargin = 11.49748pt +(typearea) \paperheight = 794.96999pt +(typearea) \textheight = 582.20026pt +(typearea) \topmargin = -37.40001pt +(typearea) \headheight = 17.0pt +(typearea) \headsep = 20.40001pt +(typearea) \topskip = 11.0pt +(typearea) \footskip = 47.6pt +(typearea) \baselineskip = 13.6pt +(typearea) on input line 1799. +) +\c@part=\count191 +\c@section=\count192 +\c@subsection=\count193 +\c@subsubsection=\count194 +\c@paragraph=\count195 +\c@subparagraph=\count196 +\scr@dte@section@maxnumwidth=\skip55 +Class scrartcl Info: using compatibility default `runin=bysign' +(scrartcl) for `\section on input line 5082. +Class scrartcl Info: using compatibility default `afterindent=bysign' +(scrartcl) for `\section on input line 5082. +\scr@dte@part@maxnumwidth=\skip56 +Class scrartcl Info: using compatibility default `afterindent=false' +(scrartcl) for `\part on input line 5090. +\scr@dte@subsection@maxnumwidth=\skip57 +Class scrartcl Info: using compatibility default `runin=bysign' +(scrartcl) for `\subsection on input line 5100. +Class scrartcl Info: using compatibility default `afterindent=bysign' +(scrartcl) for `\subsection on input line 5100. +\scr@dte@subsubsection@maxnumwidth=\skip58 +Class scrartcl Info: using compatibility default `runin=bysign' +(scrartcl) for `\subsubsection on input line 5110. +Class scrartcl Info: using compatibility default `afterindent=bysign' +(scrartcl) for `\subsubsection on input line 5110. +\scr@dte@paragraph@maxnumwidth=\skip59 +Class scrartcl Info: using compatibility default `runin=bysign' +(scrartcl) for `\paragraph on input line 5121. +Class scrartcl Info: using compatibility default `afterindent=bysign' +(scrartcl) for `\paragraph on input line 5121. +\scr@dte@subparagraph@maxnumwidth=\skip60 +Class scrartcl Info: using compatibility default `runin=bysign' +(scrartcl) for `\subparagraph on input line 5131. +Class scrartcl Info: using compatibility default `afterindent=bysign' +(scrartcl) for `\subparagraph on input line 5131. +\abovecaptionskip=\skip61 +\belowcaptionskip=\skip62 +\c@pti@nb@sid@b@x=\box53 +Package tocbasic Info: omitting babel extension for `lof' +(tocbasic) because of feature `nobabel' available +(tocbasic) for `lof' on input line 6309. +\scr@dte@figure@maxnumwidth=\skip63 +\c@figure=\count197 +Package tocbasic Info: omitting babel extension for `lot' +(tocbasic) because of feature `nobabel' available +(tocbasic) for `lot' on input line 6325. +\scr@dte@table@maxnumwidth=\skip64 +\c@table=\count198 +Class scrartcl Info: Redefining `\numberline' on input line 6495. +\bibindent=\dimen141 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsmath.sty +Package: amsmath 2024/05/23 v2.17q AMS math features +\@mathmargin=\skip65 +For additional information on amsmath, use the `?' option. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amstext.sty +Package: amstext 2021/08/26 v2.01 AMS text +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen142 +)) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen143 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsopn.sty +Package: amsopn 2022/04/08 v2.04 operator names +) +\inf@bad=\count199 +LaTeX Info: Redefining \frac on input line 233. +\uproot@=\count266 +\leftroot@=\count267 +LaTeX Info: Redefining \overline on input line 398. +LaTeX Info: Redefining \colon on input line 409. +\classnum@=\count268 +\DOTSCASE@=\count269 +LaTeX Info: Redefining \ldots on input line 495. +LaTeX Info: Redefining \dots on input line 498. +LaTeX Info: Redefining \cdots on input line 619. +\Mathstrutbox@=\box54 +\strutbox@=\box55 +LaTeX Info: Redefining \big on input line 721. +LaTeX Info: Redefining \Big on input line 722. +LaTeX Info: Redefining \bigg on input line 723. +LaTeX Info: Redefining \Bigg on input line 724. +\big@size=\dimen144 +LaTeX Font Info: Redeclaring font encoding OML on input line 742. +LaTeX Font Info: Redeclaring font encoding OMS on input line 743. +\macc@depth=\count270 +LaTeX Info: Redefining \bmod on input line 904. +LaTeX Info: Redefining \pmod on input line 909. +LaTeX Info: Redefining \smash on input line 939. +LaTeX Info: Redefining \relbar on input line 969. +LaTeX Info: Redefining \Relbar on input line 970. +\c@MaxMatrixCols=\count271 +\dotsspace@=\muskip17 +\c@parentequation=\count272 +\dspbrk@lvl=\count273 +\tag@help=\toks19 +\row@=\count274 +\column@=\count275 +\maxfields@=\count276 +\andhelp@=\toks20 +\eqnshift@=\dimen145 +\alignsep@=\dimen146 +\tagshift@=\dimen147 +\tagwidth@=\dimen148 +\totwidth@=\dimen149 +\lineht@=\dimen150 +\@envbody=\toks21 +\multlinegap=\skip66 +\multlinetaggap=\skip67 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2953. +LaTeX Info: Redefining \] on input line 2954. +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsfonts\amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsfonts\amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Redeclaring math symbol \hbar on input line 98. +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +)) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/iftex\iftex.sty +Package: iftex 2022/02/03 v1.0f TeX engine tests +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/unicode-math\unicode-ma +th.sty (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/l3kernel\expl3.s +ty +Package: expl3 2024-07-20 L3 programming layer (loader) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/l3backend\l3backend-xet +ex.def +File: l3backend-xetex.def 2024-05-08 L3 backend support: XeTeX +\g__graphics_track_int=\count277 +\l__pdf_internal_box=\box56 +\g__pdf_backend_annotation_int=\count278 +\g__pdf_backend_link_int=\count279 +)) +Package: unicode-math 2023/08/13 v0.8r Unicode maths in XeLaTeX and LuaLaTeX + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/unicode-math\unicode-ma +th-xetex.sty +Package: unicode-math-xetex 2023/08/13 v0.8r Unicode maths in XeLaTeX and LuaLa +TeX + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/l3packages/xparse\xpars +e.sty +Package: xparse 2024-05-08 L3 Experimental document command parser +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/l3packages/l3keys2e\l3k +eys2e.sty +Package: l3keys2e 2024-05-08 LaTeX2e option processing using LaTeX3 keys +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/fontspec\fontspec.sty +Package: fontspec 2024/05/11 v2.9e Font selection for XeLaTeX and LuaLaTeX + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/fontspec\fontspec-xetex +.sty +Package: fontspec-xetex 2024/05/11 v2.9e Font selection for XeLaTeX and LuaLaTe +X +\l__fontspec_script_int=\count280 +\l__fontspec_language_int=\count281 +\l__fontspec_strnum_int=\count282 +\l__fontspec_tmp_int=\count283 +\l__fontspec_tmpa_int=\count284 +\l__fontspec_tmpb_int=\count285 +\l__fontspec_tmpc_int=\count286 +\l__fontspec_em_int=\count287 +\l__fontspec_emdef_int=\count288 +\l__fontspec_strong_int=\count289 +\l__fontspec_strongdef_int=\count290 +\l__fontspec_tmpa_dim=\dimen151 +\l__fontspec_tmpb_dim=\dimen152 +\l__fontspec_tmpc_dim=\dimen153 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\fontenc.sty +Package: fontenc 2021/04/29 v2.0v Standard LaTeX package +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/fontspec\fontspec.cfg +))) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\fix-cm.sty +Package: fix-cm 2020/11/24 v1.1t fixes to LaTeX +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +LaTeX Font Info: Redeclaring font encoding TS1 on input line 47. +)) +\g__um_fam_int=\count291 +\g__um_fonts_used_int=\count292 +\l__um_primecount_int=\count293 +\g__um_primekern_muskip=\muskip18 + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/unicode-math\unicode-ma +th-table.tex))) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/lm\lmod +ern.sty +Package: lmodern 2015/05/01 v1.6.1 Latin Modern Fonts +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> OT1/lmr/m/n on input line 22. +LaTeX Font Info: Overwriting symbol font `letters' in version `normal' +(Font) OML/cmm/m/it --> OML/lmm/m/it on input line 23. +LaTeX Font Info: Overwriting symbol font `symbols' in version `normal' +(Font) OMS/cmsy/m/n --> OMS/lmsy/m/n on input line 24. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `normal' +(Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 25. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 26. +LaTeX Font Info: Overwriting symbol font `letters' in version `bold' +(Font) OML/cmm/b/it --> OML/lmm/b/it on input line 27. +LaTeX Font Info: Overwriting symbol font `symbols' in version `bold' +(Font) OMS/cmsy/b/n --> OMS/lmsy/b/n on input line 28. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold' +(Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 29. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 31. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> OT1/lmss/m/n on input line 32. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> OT1/lmr/m/it on input line 33. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 34. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 35. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> OT1/lmss/bx/n on input line 36. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> OT1/lmr/bx/it on input line 37. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 38. +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/upquote\upquote.sty +Package: upquote 2012/04/19 v1.3 upright-quote and grave-accent glyphs in verba +tim +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\textcomp.sty +Package: textcomp 2024/04/24 v2.1b Standard LaTeX package +)) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\microtype.sty +Package: microtype 2024/03/29 v3.1b Micro-typographical refinements (RS) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/etoolbox\etoolbox.sty +Package: etoolbox 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count294 +) +\MT@toks=\toks23 +\MT@tempbox=\box57 +\MT@count=\count295 +LaTeX Info: Redefining \noprotrusionifhmode on input line 1061. +LaTeX Info: Redefining \leftprotrusion on input line 1062. +\MT@prot@toks=\toks24 +LaTeX Info: Redefining \rightprotrusion on input line 1081. +LaTeX Info: Redefining \textls on input line 1392. +\MT@outer@kern=\dimen154 +LaTeX Info: Redefining \textmicrotypecontext on input line 2013. +\MT@listname@count=\count296 + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\microtype-xet +ex.def +File: microtype-xetex.def 2024/03/29 v3.1b Definitions specific to xetex (RS) +LaTeX Info: Redefining \lsstyle on input line 238. +) +Package microtype Info: Loading configuration file microtype.cfg. + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\microtype.cfg +File: microtype.cfg 2024/03/29 v3.1b microtype main configuration file (RS) +)) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/xcolor\xcolor.sty +Package: xcolor 2023/11/15 v3.01 LaTeX color extensions (UK) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics-cfg\color.cfg +File: color.cfg 2016/01/02 v1.6 sample color configuration +) +Package xcolor Info: Driver file: xetex.def on input line 274. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics-def\xetex.def +File: xetex.def 2022/09/22 v5.0n Graphics/color driver for xetex +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\mathcolor.lt +x) +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1350. +Package xcolor Info: Model `RGB' extended on input line 1366. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1368. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1369. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1370. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1371. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1372. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1373. +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\dvipsnam.def +File: dvipsnam.def 2016/06/17 v3.0m Driver-dependent file (DPC,SPQR) +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/xcolor\svgnam.def +File: svgnam.def 2023/11/15 v3.01 Predefined colors according to SVG 1.1 (UK) +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/xcolor\x11nam.def +File: x11nam.def 2023/11/15 v3.01 Predefined colors according to Unix/X11 (UK) +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/geometry\geometry.sty +Package: geometry 2020/01/02 v5.9 Page Geometry +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/iftex\ifvtex.sty +Package: ifvtex 2019/10/25 v1.7 ifvtex legacy package. Use iftex instead. +) +\Gm@cnth=\count297 +\Gm@cntv=\count298 +\c@Gm@tempcnt=\count299 +\Gm@bindingoffset=\dimen155 +\Gm@wd@mp=\dimen156 +\Gm@odd@mp=\dimen157 +\Gm@even@mp=\dimen158 +\Gm@layoutwidth=\dimen159 +\Gm@layoutheight=\dimen160 +\Gm@layouthoffset=\dimen161 +\Gm@layoutvoffset=\dimen162 +\Gm@dimlist=\toks25 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/geometry\geometry.cfg)) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/tools\longtable.sty +Package: longtable 2024-04-26 v4.20 Multi-page Table package (DPC) +\LTleft=\skip68 +\LTright=\skip69 +\LTpre=\skip70 +\LTpost=\skip71 +\LTchunksize=\count300 +\LTcapwidth=\dimen163 +\LT@head=\box58 +\LT@firsthead=\box59 +\LT@foot=\box60 +\LT@lastfoot=\box61 +\LT@gbox=\box62 +\LT@cols=\count301 +\LT@rows=\count302 +\c@LT@tables=\count303 +\c@LT@chunks=\count304 +\LT@p@ftn=\toks26 +) +Class scrartcl Info: longtable captions redefined on input line 74. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/booktabs\booktabs.sty +Package: booktabs 2020/01/12 v1.61803398 Publication quality tables +\heavyrulewidth=\dimen164 +\lightrulewidth=\dimen165 +\cmidrulewidth=\dimen166 +\belowrulesep=\dimen167 +\belowbottomsep=\dimen168 +\aboverulesep=\dimen169 +\abovetopsep=\dimen170 +\cmidrulesep=\dimen171 +\cmidrulekern=\dimen172 +\defaultaddspace=\dimen173 +\@cmidla=\count305 +\@cmidlb=\count306 +\@aboverulesep=\dimen174 +\@belowrulesep=\dimen175 +\@thisruleclass=\count307 +\@lastruleclass=\count308 +\@thisrulewidth=\dimen176 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/tools\array.sty +Package: array 2024/06/14 v2.6d Tabular extension package (FMi) +\col@sep=\dimen177 +\ar@mcellbox=\box63 +\extrarowheight=\dimen178 +\NC@list=\toks27 +\extratabsurround=\skip72 +\backup@length=\skip73 +\ar@cellbox=\box64 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/tools\calc.sty +Package: calc 2023/07/08 v4.3 Infix arithmetic (KKT,FJ) +\calc@Acount=\count309 +\calc@Bcount=\count310 +\calc@Adimen=\dimen179 +\calc@Bdimen=\dimen180 +\calc@Askip=\skip74 +\calc@Bskip=\skip75 +LaTeX Info: Redefining \setlength on input line 80. +LaTeX Info: Redefining \addtolength on input line 81. +\calc@Ccount=\count311 +\calc@Cskip=\skip76 +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/footnotehyper\footnoteh +yper.sty +Package: footnotehyper 2021/08/13 v1.1e hyperref aware footnote.sty (JFB) +\FNH@notes=\box65 +\FNH@width=\dimen181 +\FNH@toks=\toks28 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\graphicx.sty +Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\graphics.sty +Package: graphics 2024/05/23 v1.4g Standard LaTeX Graphics (DPC,SPQR) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics\trig.sty +Package: trig 2023/12/02 v1.11 sin cos tan (DPC) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/graphics-cfg\graphics.c +fg +File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration +) +Package graphics Info: Driver file: xetex.def on input line 106. +) +\Gin@req@height=\dimen182 +\Gin@req@width=\dimen183 +) +\pandoc@box=\box66 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/caption\caption.sty +Package: caption 2023/08/05 v3.6o Customizing captions (AR) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/caption\caption3.sty +Package: caption3 2023/07/31 v2.4d caption3 kernel (AR) +\caption@tempdima=\dimen184 +\captionmargin=\dimen185 +\caption@leftmargin=\dimen186 +\caption@rightmargin=\dimen187 +\caption@width=\dimen188 +\caption@indent=\dimen189 +\caption@parindent=\dimen190 +\caption@hangindent=\dimen191 +Package caption Info: KOMA-Script document class detected. + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/caption\caption-koma.st +o +File: caption-koma.sto 2023/09/08 v2.0e Adaption of the caption package to the +KOMA-Script document classes (AR) +)) +\c@caption@flags=\count312 +\c@continuedfloat=\count313 +Package caption Info: longtable package is loaded. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/caption\ltcaption.sty +Package: ltcaption 2021/01/08 v1.4c longtable captions (AR) +) +Package caption Info: KOMA-Script scrextend package detected. +\caption@addmargin@hsize=\dimen192 +\caption@addmargin@linewidth=\dimen193 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/float\float.sty +Package: float 2001/11/08 v1.3d Float enhancements (AL) +\c@float@type=\count314 +\float@exts=\toks29 +\float@box=\box67 +\@float@everytoks=\toks30 +\@floatcapt=\box68 +) +\@float@every@codelisting=\toks31 +\c@codelisting=\count315 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/caption\subcaption.sty +Package: subcaption 2023/07/28 v1.6b Sub-captions (AR) +Package caption Info: New subtype `subfigure' on input line 238. +\c@subfigure=\count316 +Package caption Info: New subtype `subtable' on input line 238. +\c@subtable=\count317 +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/sidenotes\sidenotes.sty +Package: sidenotes 2024/09/12 v1.20 Rich text in the margin for LaTeX + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/marginnote\marginnote.s +ty +Package: marginnote 2018/08/09 1.4b non floating margin notes for LaTeX +\c@mn@abspage=\count318 +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/changepage\changepage.s +ty +Package: changepage 2009/10/20 v1.0c check page and change page layout +\c@cp@cntr=\count319 +\cp@tempcnt=\count320 +) +\c@sidenote=\count321 +\@sidenotes@marginfigurebox=\box69 +\@sidenotes@margintablebox=\box70 +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/bookmark\bookmark.sty +Package: bookmark 2023-12-10 v1.31 PDF bookmarks (HO) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hyperref\hyperref.sty +Package: hyperref 2024-07-10 v7.01j Hypertext links for LaTeX + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/kvsetkeys\kvsetkeys.sty +Package: kvsetkeys 2022-10-05 v1.19 Key value parser (HO) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/kvdefinekeys\kvdefine +keys.sty +Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/pdfescape\pdfescape.s +ty +Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/ltxcmds\ltxcmds.sty +Package: ltxcmds 2023-12-04 v1.26 LaTeX kernel commands for general use (HO) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/pdftexcmds\pdftexcmds +.sty +Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO +) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/infwarerr\infwarerr.s +ty +Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO) +) +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +)) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hycolor\hycolor.sty +Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO) +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hyperref\nameref.sty +Package: nameref 2023-11-26 v2.56 Cross-referencing by name of section +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/refcount\refcount.sty +Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO) +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/gettitlestring\gettit +lestring.sty +Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/kvoptions\kvoptions.sty +Package: kvoptions 2022-06-15 v3.15 Key value format for package options (HO) +)) +\c@section@level=\count322 +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/stringenc\stringenc.s +ty +Package: stringenc 2019/11/29 v1.12 Convert strings between diff. encodings (HO +) +) +\@linkdim=\dimen194 +\Hy@linkcounter=\count323 +\Hy@pagecounter=\count324 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hyperref\pd1enc.def +File: pd1enc.def 2024-07-10 v7.01j Hyperref: PDFDocEncoding definition (HO) +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/intcalc\intcalc.sty +Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO) +) +\Hy@SavedSpaceFactor=\count325 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hyperref\puenc.def +File: puenc.def 2024-07-10 v7.01j Hyperref: PDF Unicode definition (HO) +) +Package hyperref Info: Option `unicode' set `true' on input line 4040. +Package hyperref Info: Hyper figures OFF on input line 4157. +Package hyperref Info: Link nesting OFF on input line 4162. +Package hyperref Info: Hyper index ON on input line 4165. +Package hyperref Info: Plain pages OFF on input line 4172. +Package hyperref Info: Backreferencing OFF on input line 4177. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4424. +\c@Hy@tempcnt=\count326 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/url\url.sty +\Urlmuskip=\muskip19 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 4763. +\XeTeXLinkMargin=\dimen195 +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/bitset\bitset.sty +Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO) + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/bigintcalc\bigintcalc +.sty +Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO +) +)) +\Fld@menulength=\count327 +\Field@Width=\dimen196 +\Fld@charsize=\dimen197 +Package hyperref Info: Hyper figures OFF on input line 6042. +Package hyperref Info: Link nesting OFF on input line 6047. +Package hyperref Info: Hyper index ON on input line 6050. +Package hyperref Info: backreferencing OFF on input line 6057. +Package hyperref Info: Link coloring OFF on input line 6062. +Package hyperref Info: Link coloring with OCG OFF on input line 6067. +Package hyperref Info: PDF/A mode OFF on input line 6072. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\atbegshi-ltx.sty +Package: atbegshi-ltx 2021/01/10 v1.0c Emulation of the original atbegshi +package with kernel methods +) +\Hy@abspage=\count328 +\c@Item=\count329 +\c@Hfootnote=\count330 +) +Package hyperref Info: Driver (autodetected): hxetex. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/hyperref\hxetex.def +File: hxetex.def 2024-07-10 v7.01j Hyperref driver for XeTeX +\pdfm@box=\box71 +\c@Hy@AnnotLevel=\count331 +\HyField@AnnotCount=\count332 +\Fld@listcount=\count333 +\c@bookmark@seq@number=\count334 + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/rerunfilecheck\rerunfil +echeck.sty +Package: rerunfilecheck 2022-07-10 v1.10 Rerun checks for auxiliary files (HO) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/base\atveryend-ltx.sty +Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atveryend pac +kage +with kernel methods +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/generic/uniquecounter\uniquec +ounter.sty +Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO) +) +Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 +85. +) +\Hy@SectionHShift=\skip77 +) +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/bookmark\bkm-dvipdfm.de +f +File: bkm-dvipdfm.def 2023-12-10 v1.31 bookmark driver for dvipdfm (HO) +\BKM@id=\count335 +)) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/xurl\xurl.sty +Package: xurl 2022/01/09 v 0.10 modify URL breaks +) +Package hyperref Info: Option `colorlinks' set `true' on input line 157. +No file styleguide.aux. +\openout1 = `styleguide.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for TU/lmr/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 164. +LaTeX Font Info: ... okay on input line 164. +Package scrbase Info: activating english \abstractname on input line 164. +Package scrbase Info: activating english \partname on input line 164. +Package scrbase Info: activating english \figurename on input line 164. +Package scrbase Info: activating english \tablename on input line 164. +Package scrbase Info: activating english \contentsname on input line 164. +Package scrbase Info: activating english \listfigurename on input line 164. +Package scrbase Info: activating english \listtablename on input line 164. +Package scrbase Info: activating english \refname on input line 164. +Package scrbase Info: activating english \indexname on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathrm' in version `normal' +(Font) OT1/lmr/m/n --> TU/lmr/m/n on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/lmr/m/it --> TU/lmr/m/it on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/lmr/bx/n --> TU/lmr/bx/n on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/lmss/m/n --> TU/lmss/m/n on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/lmss/bx/n --> TU/lmss/bx/n on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/lmtt/m/n --> TU/lmtt/m/n on input line 164. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/lmtt/m/n --> TU/lmtt/bx/n on input line 164. + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) Font family 'latinmodern-math.otf(0)' created for font +(fontspec) 'latinmodern-math.otf' with options +(fontspec) [Scale=MatchLowercase,BoldItalicFont={},ItalicFont={},Sm +allCapsFont={},Script=Math,BoldFont={latinmodern-math.otf}]. +(fontspec) +(fontspec) This font family consists of the following NFSS +(fontspec) series/shapes: +(fontspec) +(fontspec) - 'normal' (m/n) with NFSS spec.: +(fontspec) <->s*[0.9999967668407183]"[latinmodern-math.otf]/OT:scri +pt=math;language=dflt;" +(fontspec) - 'bold' (b/n) with NFSS spec.: +(fontspec) <->s*[0.9999967668407183]"[latinmodern-math.otf]/OT:scri +pt=math;language=dflt;" + +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(0)/m/n' will be +(Font) scaled to size 10.95pt on input line 164. + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) Font family 'latinmodern-math.otf(1)' created for font +(fontspec) 'latinmodern-math.otf' with options +(fontspec) [Scale=MatchLowercase,BoldItalicFont={},ItalicFont={},Sm +allCapsFont={},Script=Math,SizeFeatures={{Size=9.3075-},{Size=6.57-9.3075,Font= +latinmodern-math.otf,Style=MathScript},{Size=-6.57,Font=latinmodern-math.otf,St +yle=MathScriptScript}},BoldFont={latinmodern-math.otf}]. +(fontspec) +(fontspec) This font family consists of the following NFSS +(fontspec) series/shapes: +(fontspec) +(fontspec) - 'normal' (m/n) with NFSS spec.: +(fontspec) <9.3075->s*[0.9999967668407183]"[latinmodern-math.otf]/O +T:script=math;language=dflt;"<6.57-9.3075>s*[0.9999967668407183]"[latinmodern-m +ath.otf]/OT:script=math;language=dflt;+ssty=0;"<-6.57>s*[0.9999967668407183]"[l +atinmodern-math.otf]/OT:script=math;language=dflt;+ssty=1;" +(fontspec) - 'bold' (b/n) with NFSS spec.: +(fontspec) <->s*[0.9999967668407183]"[latinmodern-math.otf]/OT:scri +pt=math;language=dflt;" + +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(1)/m/n' will be +(Font) scaled to size 10.95pt on input line 164. +LaTeX Font Info: Encoding `OT1' has changed to `TU' for symbol font +(Font) `operators' in the math version `normal' on input line 164. + +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/lmr/m/n --> TU/latinmodern-math.otf(1)/m/n on input + line 164. +LaTeX Font Info: Encoding `OT1' has changed to `TU' for symbol font +(Font) `operators' in the math version `bold' on input line 164. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/lmr/bx/n --> TU/latinmodern-math.otf(1)/b/n on inpu +t line 164. + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 1.000096766517402. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 1.000096766517402. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 1.000096766517402. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 1.000096766517402. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 1.000096766517402. + + +Package fontspec Info: +(fontspec) Font family 'latinmodern-math.otf(2)' created for font +(fontspec) 'latinmodern-math.otf' with options +(fontspec) [Scale=MatchLowercase,BoldItalicFont={},ItalicFont={},Sm +allCapsFont={},Script=Math,SizeFeatures={{Size=9.3075-},{Size=6.57-9.3075,Font= +latinmodern-math.otf,Style=MathScript},{Size=-6.57,Font=latinmodern-math.otf,St +yle=MathScriptScript}},BoldFont={latinmodern-math.otf},ScaleAgain=1.0001,FontAd +justment={\fontdimen +(fontspec) 8\font =7.41315pt\relax \fontdimen 9\font +(fontspec) =4.3143pt\relax \fontdimen 10\font =4.8618pt\relax +(fontspec) \fontdimen 11\font =7.5117pt\relax \fontdimen 12\font +(fontspec) =3.77776pt\relax \fontdimen 13\font =3.97485pt\relax +(fontspec) \fontdimen 14\font =3.97485pt\relax \fontdimen 15\font +(fontspec) =3.16455pt\relax \fontdimen 16\font =2.70465pt\relax +(fontspec) \fontdimen 17\font =2.70465pt\relax \fontdimen 18\font +(fontspec) =2.7375pt\relax \fontdimen 19\font =2.19pt\relax +(fontspec) \fontdimen 22\font =2.7375pt\relax \fontdimen 20\font +(fontspec) =0pt\relax \fontdimen 21\font =0pt\relax }]. +(fontspec) +(fontspec) This font family consists of the following NFSS +(fontspec) series/shapes: +(fontspec) +(fontspec) - 'normal' (m/n) with NFSS spec.: +(fontspec) <9.3075->s*[1.000096766517402]"[latinmodern-math.otf]/OT +:script=math;language=dflt;"<6.57-9.3075>s*[1.000096766517402]"[latinmodern-mat +h.otf]/OT:script=math;language=dflt;+ssty=0;"<-6.57>s*[1.000096766517402]"[lati +nmodern-math.otf]/OT:script=math;language=dflt;+ssty=1;" +(fontspec) - 'bold' (b/n) with NFSS spec.: +(fontspec) <->s*[1.000096766517402]"[latinmodern-math.otf]/OT:scrip +t=math;language=dflt;" + +LaTeX Font Info: Encoding `OMS' has changed to `TU' for symbol font +(Font) `symbols' in the math version `normal' on input line 164. +LaTeX Font Info: Overwriting symbol font `symbols' in version `normal' +(Font) OMS/lmsy/m/n --> TU/latinmodern-math.otf(2)/m/n on inpu +t line 164. +LaTeX Font Info: Encoding `OMS' has changed to `TU' for symbol font +(Font) `symbols' in the math version `bold' on input line 164. +LaTeX Font Info: Overwriting symbol font `symbols' in version `bold' +(Font) OMS/lmsy/b/n --> TU/latinmodern-math.otf(2)/b/n on inpu +t line 164. + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9998967671640342. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9998967671640342. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9998967671640342. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9998967671640342. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9999967668407183. + + +Package fontspec Info: +(fontspec) latinmodern-math scale = 0.9998967671640342. + + +Package fontspec Info: +(fontspec) Font family 'latinmodern-math.otf(3)' created for font +(fontspec) 'latinmodern-math.otf' with options +(fontspec) [Scale=MatchLowercase,BoldItalicFont={},ItalicFont={},Sm +allCapsFont={},Script=Math,SizeFeatures={{Size=9.3075-},{Size=6.57-9.3075,Font= +latinmodern-math.otf,Style=MathScript},{Size=-6.57,Font=latinmodern-math.otf,St +yle=MathScriptScript}},BoldFont={latinmodern-math.otf},ScaleAgain=0.9999,FontAd +justment={\fontdimen +(fontspec) 8\font =0.438pt\relax \fontdimen 9\font =2.19pt\relax +(fontspec) \fontdimen 10\font =1.82864pt\relax \fontdimen 11\font +(fontspec) =1.21545pt\relax \fontdimen 12\font =6.56999pt\relax +(fontspec) \fontdimen 13\font =0pt\relax }]. +(fontspec) +(fontspec) This font family consists of the following NFSS +(fontspec) series/shapes: +(fontspec) +(fontspec) - 'normal' (m/n) with NFSS spec.: +(fontspec) <9.3075->s*[0.9998967671640342]"[latinmodern-math.otf]/O +T:script=math;language=dflt;"<6.57-9.3075>s*[0.9998967671640342]"[latinmodern-m +ath.otf]/OT:script=math;language=dflt;+ssty=0;"<-6.57>s*[0.9998967671640342]"[l +atinmodern-math.otf]/OT:script=math;language=dflt;+ssty=1;" +(fontspec) - 'bold' (b/n) with NFSS spec.: +(fontspec) <->s*[0.9998967671640342]"[latinmodern-math.otf]/OT:scri +pt=math;language=dflt;" + +LaTeX Font Info: Encoding `OMX' has changed to `TU' for symbol font +(Font) `largesymbols' in the math version `normal' on input line 1 +64. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `normal' +(Font) OMX/lmex/m/n --> TU/latinmodern-math.otf(3)/m/n on inpu +t line 164. +LaTeX Font Info: Encoding `OMX' has changed to `TU' for symbol font +(Font) `largesymbols' in the math version `bold' on input line 164 +. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold' +(Font) OMX/lmex/m/n --> TU/latinmodern-math.otf(3)/b/n on inpu +t line 164. +LaTeX Info: Redefining \microtypecontext on input line 164. +Package microtype Info: Applying patch `item' on input line 164. +Package microtype Info: Applying patch `toc' on input line 164. +Package microtype Info: Applying patch `eqnum' on input line 164. +Package microtype Info: Applying patch `footnote' on input line 164. +Package microtype Info: Applying patch `verbatim' on input line 164. +Package microtype Info: Character protrusion enabled (level 2). +Package microtype Info: Using protrusion set `basicmath'. +Package microtype Info: No adjustment of tracking. +Package microtype Info: No adjustment of spacing. +Package microtype Info: No adjustment of kerning. + +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\mt-LatinModer +nRoman.cfg +File: mt-LatinModernRoman.cfg 2021/02/21 v1.1 microtype config. file: Latin Mod +ern Roman (RS) +) +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: letterpaper +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 298.71585pt, 243.30916pt) +* v-part:(T,H,B)=(95.39737pt, 556.47656pt, 143.09605pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=298.71585pt +* \textheight=556.47656pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-14.27263pt +* \headheight=17.0pt +* \headsep=20.40001pt +* \topskip=11.0pt +* \footskip=47.6pt +* \marginparwidth=149.35793pt +* \marginparsep=21.68121pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +Package caption Info: Begin \AtBeginDocument code. +Package caption Info: changepage package is loaded. +\caption@adjustwidth@hsize=\dimen198 +\caption@adjustwidth@linewidth=\dimen199 +Package caption Info: float package is loaded. +Package caption Info: hyperref package is loaded. +Package caption Info: End \AtBeginDocument code. +\@sidenotes@extrawidth=\skip78 +Package hyperref Info: Link coloring ON on input line 164. + +Package hyperref Warning: Rerun to get /PageLabels entry. + +Package microtype Info: Loading generic protrusion settings for font family +(microtype) `lmss' (encoding: TU). +(microtype) For optimal results, create family-specific settings. +(microtype) See the microtype manual for details. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(1)/m/n' will be +(Font) scaled to size 14.4pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(1)/m/n' will be +(Font) scaled to size 10.0pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(1)/m/n' will be +(Font) scaled to size 7.0pt on input line 166. +LaTeX Font Info: Trying to load font information for OML+lmm on input line 1 +66. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/lm\omllmm.fd +File: omllmm.fd 2015/05/01 v1.6.1 Font defs for Latin Modern +) +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(2)/m/n' will be +(Font) scaled to size 14.4013pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(2)/m/n' will be +(Font) scaled to size 10.00092pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(2)/m/n' will be +(Font) scaled to size 7.00064pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(3)/m/n' will be +(Font) scaled to size 14.39845pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(3)/m/n' will be +(Font) scaled to size 9.99893pt on input line 166. +LaTeX Font Info: Font shape `TU/latinmodern-math.otf(3)/m/n' will be +(Font) scaled to size 6.99925pt on input line 166. +LaTeX Font Info: Trying to load font information for U+msa on input line 166 +. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsfonts\umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\mt-msa.cfg +File: mt-msa.cfg 2006/02/04 v1.1 microtype config. file: AMS symbols (a) (RS) +) +LaTeX Font Info: Trying to load font information for U+msb on input line 166 +. +(C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/amsfonts\umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) (C:\Users\Waldo\AppData\Local\Programs\MiKTeX\tex/latex/microtype\mt-msb.cfg +File: mt-msb.cfg 2005/06/01 v1.0 microtype config. file: AMS symbols (b) (RS) +) +Underfull \hbox (badness 2245) in paragraph at lines 193--195 +[]\TU/lmr/m/n/10.95 Capitalize every word and remove all spaces, + [] + + + +[1 + + +] +Underfull \hbox (badness 10000) in paragraph at lines 204--207 +[]\TU/lmr/m/n/10.95 Words can arbitrarily start upper or low- + [] + + +Underfull \hbox (badness 5345) in paragraph at lines 204--207 +\TU/lmr/m/n/10.95 ercase but words are separated by an un- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 204--207 +\TU/lmr/m/n/10.95 derscore, e.g. \TU/lmtt/m/n/10.95 desert_Eagle\TU/lmr/m/n/10. +95 , \TU/lmtt/m/n/10.95 Style_Guide\TU/lmr/m/n/10.95 , + [] + + + +[2] + +[3] + +[4] +! Undefined control sequence. +l.341 characters when possible (the \n + \texttt{{[}A-Za-z0-9\_{]}+}) +Here is how much of TeX's memory you used: + 23919 strings out of 409029 + 453591 string characters out of 5756742 + 1927612 words of memory out of 5000000 + 46343 multiletter control sequences out of 15000+600000 + 561665 words of font info for 69 fonts, out of 8000000 for 9000 + 1348 hyphenation exceptions out of 8191 + 108i,8n,123p,10907b,430s stack positions out of 10000i,1000n,20000p,200000b,200000s + +Output written on styleguide.pdf (4 pages). diff --git a/sites/styleguide.pdf b/sites/styleguide.pdf new file mode 100644 index 0000000..009284e Binary files /dev/null and b/sites/styleguide.pdf differ diff --git a/sites/styleguide.qmd b/sites/styleguide.qmd new file mode 100644 index 0000000..45c15d9 --- /dev/null +++ b/sites/styleguide.qmd @@ -0,0 +1,1638 @@ +--- +title: "Styleguide" +--- +This Styleguiade is adapted by Gamemakin UE5 Styleguide. + +## Important Terminology + + + + +##### Levels/Maps + +The word 'map' generally refers to what the average person calls a 'level' and may be used interchangeably. See this term's history [here](https://en.wikipedia.org/wiki/Level_(video_gaming)). + +##### Identifiers +An `Identifier` is anything that resembles or serves as a "name". For example, the name of an asset, or the name of a material later, or a blueprint property, a variable, or a folder name, or for a data table row name, etc... + + + + +##### Cases + +There are a few different ways you can `CaseWordsWhenNaming`. Here are some common casing types: + +> ###### PascalCase +> +> Capitalize every word and remove all spaces, e.g. `DesertEagle`, `StyleGuide`, `ASeriesOfWords`. +> +> ###### camelCase +> +> The first letter is always lowercase but every following word starts with uppercase, e.g. `desertEagle`, `styleGuide`, `aSeriesOfWords`. +> +> ###### Snake_case +> +> Words can arbitrarily start upper or lowercase but words are separated by an underscore, e.g. `desert_Eagle`, `Style_Guide`, `a_Series_of_Words`. + + + + +##### Variables / Properties + +The words 'variable' and 'property' in most contexts are interchangable. If they are both used together in the same context however: + + + + +###### Property +Usually refers to a variable defined in a class. For example, if `BP_Barrel` had a variable `bExploded`, `bExploded` may be referred to as a property of `BP_Barrel`. + +When in the context of a class, it is often used to imply accessing previously defined data. + + + + +###### Variable +Usually refers to a variable defined as a function argument or a local variable inside a function. + +When in the context of a class, it is often used to convey discussion about its definition and what it will hold. + + + + +## 0. Principles + +These principles have been adapted from [idomatic.js style guide](https://github.com/rwaldron/idiomatic.js/). + + + + +### 0.1 If your UE4 project already has a style guide, you should follow it. + +If you are working on a project or with a team that has a pre-existing style guide, it should be respected. Any inconsistency between an existing style guide and this guide should defer to the existing. + +Style guides should be living documents. You should propose style guide changes to an existing style guide as well as this guide if you feel the change benefits all usages. + +> #### "Arguments over style are pointless. There should be a style guide, and you should follow it." +> [_Rebecca Murphey_](https://rmurphey.com) + + + + +### 0.2 All structure, assets, and code in any Unreal Engine 4 project should look like a single person created it, no matter how many people contributed. + +Moving from one project to another should not cause a re-learning of style and structure. Conforming to a style guide removes unneeded guesswork and ambiguities. + +It also allows for more productive creation and maintenance as one does not need to think about style. Simply follow the instructions. This style guide is written with best practices in mind, meaning that by following this style guide you will also minimize hard to track issues. + + + + +### 0.3 Friends do not let friends have bad style. + +If you see someone working either against a style guide or no style guide, try to correct them. + +When working within a team or discussing within a community such as [Unreal Slackers](http://join.unrealslackers.org/), it is far easier to help and to ask for help when people are consistent. Nobody likes to help untangle someone's Blueprint spaghetti or deal with assets that have names they can't understand. + +If you are helping someone whose work conforms to a different but consistent and sane style guide, you should be able to adapt to it. If they do not conform to any style guide, please direct them here. + + + + +### 0.4 A team without a style guide is no team of mine. + +When joining an Unreal Engine 4 team, one of your first questions should be "Do you have a style guide?". If the answer is no, you should be skeptical about their ability to work as a team. + + + + +### 0.5 Don't Break The Law + +Gamemakin LLC is not a lawyer, but please don't introduce illegal actions and behavior to a project, including but not limited to: + +* Don't distribute content you don't have the rights to distribute +* Don't infringe on someone else's copyrighted or trademark material +* Don't steal content +* Follow licensing restrictions on content, e.g. attribute when attributions are needed + + + + +## 00. Globally Enforced Opinions + +@TODO: Make this section 1 and update this document accordingly. Or maybe we don't? + + + + +### 00.1 Forbidden Characters + +#### Identifiers + +In any `Identifier` of any kind, **never** use the following unless absolutely forced to: + +* White space of any kind +* Backward slashes `\` +* Symbols i.e. `#!@$%` +* Any Unicode character + +Any `Identifier` should strive to only have the following characters when possible (the +\n `[A-Za-z0-9_]+`) + +* ABCDEFGHIJKLMNOPQRSTUVWXYZ +* abcdefghijklmnopqrstuvwxyz +* 1234567890 +* _ (sparingly) + + +The reasoning for this is this will ensure the greatest compatibility of all data across all platforms across all tools, and help prevent downtime due to potentially bad character handling for identifiers in code you don't control. + + + +## Table of Contents + +> 1. [Asset Naming Conventions](#anc) +> 1. [Directory Structure](#structure) +> 1. [Blueprints](#bp) +> 1. [Static Meshes](#s) +> 1. [Particle Systems](#ps) +> 1. [Levels / Maps](#levels) +> 1. [Textures](#textures) + + + + + +## 1. Asset Naming Conventions + +Naming conventions should be treated as law. A project that conforms to a naming convention is able to have its assets managed, searched, parsed, and maintained with incredible ease. + +Most things are prefixed with prefixes being generally an acronym of the asset type followed by an underscore. + + + + + + +### 1.1 Base Asset Name - `Prefix_BaseAssetName_Variant_Suffix` + +All assets should have a _Base Asset Name_. A Base Asset Name represents a logical grouping of related assets. Any asset that is part of this logical group should follow the standard of `Prefix_BaseAssetName_Variant_Suffix`. + +Keeping the pattern `Prefix_BaseAssetName_Variant_Suffix` and in mind and using common sense is generally enough to warrant good asset names. Here are some detailed rules regarding each element. + +`Prefix` and `Suffix` are to be determined by the asset type through the following [Asset Name Modifier](#asset-name-modifiers) tables. + +`BaseAssetName` should be determined by a short and easily recognizable name related to the context of this group of assets. For example, if you had a character named Bob, all of Bob's assets would have the `BaseAssetName` of `Bob`. + +For unique and specific variations of assets, `Variant` is either a short and easily recognizable name that represents logical grouping of assets that are a subset of an asset's base name. For example, if Bob had multiple skins these skins should still use `Bob` as the `BaseAssetName` but include a recognizable `Variant`. An 'Evil' skin would be referred to as `Bob_Evil` and a 'Retro' skin would be referred to as `Bob_Retro`. + +For unique but generic variations of assets, `Variant` is a two digit number starting at `01`. For example, if you have an environment artist generating nondescript rocks, they would be named `Rock_01`, `Rock_02`, `Rock_03`, etc. Except for rare exceptions, you should never require a three digit variant number. If you have more than 100 assets, you should consider organizing them with different base names or using multiple variant names. + +Depending on how your asset variants are made, you can chain together variant names. For example, if you are creating flooring assets for an Arch Viz project you should use the base name `Flooring` with chained variants such as `Flooring_Marble_01`, `Flooring_Maple_01`, `Flooring_Tile_Squares_01`. + + + + +#### 1.1 Examples + +##### 1.1e1 Bob + +| Asset Type | Asset Name | +| ----------------------- | ---------------------------------------------------------- | +| Skeletal Mesh | SK_Bob | +| Material | M_Bob | +| Texture (Diffuse/Albedo)| T_Bob_D | +| Texture (Normal) | T_Bob_N | +| Texture (Evil Diffuse) | T_Bob_Evil_D | + +##### 1.1e2 Rocks + +| Asset Type | Asset Name | +| ----------------------- | ---------------------------------------------------------- | +| Static Mesh (01) | S_Rock_01 | +| Static Mesh (02) | S_Rock_02 | +| Static Mesh (03) | S_Rock_03 | +| Material | M_Rock | +| Material Instance (Snow)| MI_Rock_Snow | + + + + + + +### 1.2 Asset Name Modifiers + +When naming an asset, use these tables to determine the prefix and suffix to use with an asset's [Base Asset Name](#base-asset-name). + +#### Sections + +> 1.2.1 [Most Common](#anc-common) + +> 1.2.2 [Animations](#anc-animations) + +> 1.2.3 [Artificial Intelligence](#anc-ai) + +> 1.2.4 [Blueprints](#anc-bp) + +> 1.2.5 [Materials](#anc-materials) + +> 1.2.6 [Textures](#anc-textures) + +> 1.2.7 [Miscellaneous](#anc-misc) + +> 1.2.8 [Paper 2D](#anc-paper2d) + +> 1.2.9 [Physics](#anc-physics) + +> 1.2.10 [Sound](#anc-sounds) + +> 1.2.11 [User Interface](#anc-ui) + +> 1.2.12 [Effects](#anc-effects) + + + + + + + +#### 1.2.1 Most Common + + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Level / Map | | | [Should be in a folder called Maps.](#2.4) | +| Level (Persistent) | | _P | | +| Level (Audio) | | _Audio | | +| Level (Lighting) | | _Lighting | | +| Level (Geometry) | | _Geo | | +| Level (Gameplay) | | _Gameplay | | +| Blueprint | BP_ | | | +| Material | M_ | | | +| Static Mesh | S_ | | Many use SM_. We use S_. | +| Skeletal Mesh | SK_ | | | +| Texture | T_ | _? | See [Textures](#anc-textures) | +| Particle System | PS_ | | | +| Widget Blueprint | WBP_ | | | + + + + + +#### 1.2.2 Animations + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Aim Offset | AO_ | | | +| Aim Offset 1D | AO_ | | | +| Animation Blueprint | ABP_ | | | +| Animation Composite | AC_ | | | +| Animation Montage | AM_ | | | +| Animation Sequence | A_ | | | +| Blend Space | BS_ | | | +| Blend Space 1D | BS_ | | | +| Level Sequence | LS_ | | | +| Morph Target | MT_ | | | +| Paper Flipbook | PFB_ | | | +| Rig | Rig_ | | | +| Control Rig | CR_ | | | +| Skeletal Mesh | SK_ | | | +| Skeleton | SKEL_ | | | + + + + + + +### 1.2.3 Artificial Intelligence + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| AI Controller | AIC_ | | | +| Behavior Tree | BT_ | | | +| Blackboard | BB_ | | | +| Decorator | BTDecorator_ | | | +| Service | BTService_ | | | +| Task | BTTask_ | | | +| Environment Query | EQS_ | | | +| EnvQueryContext | EQS_ | Context | | + + + + + + +### 1.2.4 Blueprints + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Blueprint | BP_ | | | +| Blueprint Component | BP_ | Component | I.e. BP_InventoryComponent | +| Blueprint Function Library | BPFL_ | | | +| Blueprint Interface | BPI_ | | | +| Blueprint Macro Library | BPML_ | | Do not use macro libraries if possible. | +| Enumeration | E | | No underscore. | +| Structure | F or S | | No underscore. | +| Tutorial Blueprint | TBP_ | | | +| Widget Blueprint | WBP_ | | | + + + + + +### 1.2.5 Materials + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------------- | ---------- | ---------- | -------------------------------- | +| Material | M_ | | | +| Material (Post Process) | PP_ | | | +| Material Function | MF_ | | | +| Material Instance | MI_ | | | +| Material Parameter Collection | MPC_ | | | +| Subsurface Profile | SP_ | | | +| Physical Materials | PM_ | | | +| Decal | M_, MI_ | _Decal | | + + + + + +### 1.2.6 Textures + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Texture | T_ | | | +| Texture (Diffuse/Albedo/Base Color)| T_ | _D | | +| Texture (Normal) | T_ | _N | | +| Texture (Roughness) | T_ | _R | | +| Texture (Alpha/Opacity) | T_ | _A | | +| Texture (Ambient Occlusion) | T_ | _O | | +| Texture (Bump) | T_ | _B | | +| Texture (Emissive) | T_ | _E | | +| Texture (Mask) | T_ | _M | | +| Texture (Specular) | T_ | _S | | +| Texture (Metallic) | T_ | _M | | +| Texture (Packed) | T_ | _* | See notes below about [packing](#anc-textures-packing). | +| Texture Cube | TC_ | | | +| Media Texture | MT_ | | | +| Render Target | RT_ | | | +| Cube Render Target | RTC_ | | | +| Texture Light Profile | TLP | | | + + + + + +#### 1.2.6.1 Texture Packing +It is common practice to pack multiple layers of texture data into one texture. An example of this is packing Emissive, Roughness, Ambient Occlusion together as the Red, Green, and Blue channels of a texture respectively. To determine the suffix, simply stack the given suffix letters from above together, e.g. `_ERO`. + +> It is generally acceptable to include an Alpha/Opacity layer in your Diffuse/Albedo's alpha channel and as this is common practice, adding `A` to the `_D` suffix is optional. + +Packing 4 channels of data into a texture (RGBA) is not recommended except for an Alpha/Opacity mask in the Diffuse/Albedo's alpha channel as a texture with an alpha channel incurs more overhead than one without. + + + + + +### 1.2.7 Miscellaneous + +| Asset Type | Prefix | Suffix | Notes | +| -------------------------- | ---------- | ---------- | -------------------------------- | +| Animated Vector Field | VFA_ | | | +| Camera Anim | CA_ | | | +| Color Curve | Curve_ | _Color | | +| Curve Table | Curve_ | _Table | | +| Data Asset | *_ | | Prefix should be based on class. | +| Data Table | DT_ | | | +| Float Curve | Curve_ | _Float | | +| Foliage Type | FT_ | | | +| Force Feedback Effect | FFE_ | | | +| Landscape Grass Type | LG_ | | | +| Landscape Layer | LL_ | | | +| Matinee Data | Matinee_ | | | +| Media Player | MP_ | | | +| Object Library | OL_ | | | +| Redirector | | | These should be fixed up ASAP. | +| Sprite Sheet | SS_ | | | +| Static Vector Field | VF_ | | | +| Substance Graph Instance | SGI_ | | | +| Substance Instance Factory | SIF_ | | | +| Touch Interface Setup | TI_ | | | +| Vector Curve | Curve_ | _Vector | | + + + + + +### 1.2.8 Paper 2D + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Paper Flipbook | PFB_ | | | +| Sprite | SPR_ | | | +| Sprite Atlas Group | SPRG_ | | | +| Tile Map | TM_ | | | +| Tile Set | TS_ | | | + + + + + +### 1.2.9 Physics + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Physical Material | PM_ | | | +| Physics Asset | PHYS_ | | | +| Destructible Mesh | DM_ | | | + + + + + +### 1.2.10 Sounds + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Dialogue Voice | DV_ | | | +| Dialogue Wave | DW_ | | | +| Media Sound Wave | MSW_ | | | +| Reverb Effect | Reverb_ | | | +| Sound Attenuation | ATT_ | | | +| Sound Class | | | No prefix/suffix. Should be put in a folder called SoundClasses | +| Sound Concurrency | | _SC | Should be named after a SoundClass | +| Sound Cue | A_ | _Cue | | +| Sound Mix | Mix_ | | | +| Sound Wave | A_ | | | + + + + + +### 1.2.11 User Interface + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Font | Font_ | | | +| Slate Brush | Brush_ | | | +| Slate Widget Style | Style_ | | | +| Widget Blueprint | WBP_ | | | + + + + + +### 1.2.12 Effects + +| Asset Type | Prefix | Suffix | Notes | +| ----------------------- | ---------- | ---------- | -------------------------------- | +| Particle System | PS_ | | | +| Material (Post Process) | PP_ | | | + +**[⬆ Back to Top](#table-of-contents)** + + + + + + +## 2. Content Directory Structure + +Equally important as asset names, the directory structure style of a project should be considered law. Asset naming conventions and content directory structure go hand in hand, and a violation of either causes unneeded chaos. + +There are multiple ways to lay out the content of a UE4 project. In this style, we will be using a structure that relies more on filtering and search abilities of the Content Browser for those working with assets to find assets of a specific type instead of another common structure that groups asset types with folders. + +> If you are using the prefix [naming convention](#1.2) above, using folders to contain assets of similar types such as `Meshes`, `Textures`, and `Materials` is a redundant practice as asset types are already both sorted by prefix as well as able to be filtered in the content browser. + + +### 2e1 Example Project Content Structure +
+|-- Content
+    |-- GenericShooter
+
+        |-- Art
+        |   |-- Industrial
+        |   |   |-- Ambient
+        |   |   |-- Machinery
+        |   |   |-- Pipes
+        |   |-- Nature
+        |   |   |-- Ambient
+        |   |   |-- Foliage
+        |   |   |-- Rocks
+        |   |   |-- Trees
+        |   |-- Office
+        |-- Characters
+        |   |-- Bob
+        |   |-- Common
+        |   |   |-- Animations
+
+        |   |   |-- Audio
+        |   |-- Jack
+        |   |-- Steve
+        |   |-- Zoe
+
+        |-- Core
+
+        |   |-- Characters
+        |   |-- Engine
+        |   |-- GameModes
+
+        |   |-- Interactables
+        |   |-- Pickups
+        |   |-- Weapons
+        |-- Effects
+        |   |-- Electrical
+        |   |-- Fire
+        |   |-- Weather
+        |-- Maps
+
+        |   |-- Campaign1
+        |   |-- Campaign2
+        |-- MaterialLibrary
+
+        |   |-- Debug
+        |   |-- Metal
+        |   |-- Paint
+        |   |-- Utility
+        |   |-- Weathering
+        |-- Placeables
+        |   |-- Pickups
+        |-- Weapons
+            |-- Common
+            |-- Pistols
+            |   |-- DesertEagle
+            |   |-- RocketPistol
+            |-- Rifles
+
+ +The reasons for this structure are listed in the following sub-sections. + +### Sections + +> 2.1 [Folder Names](#structure-folder-names) + +> 2.2 [Top-Level Folders](#structure-top-level) + +> 2.3 [Developer Folders](#structure-developers) + +> 2.4 [Maps](#structure-maps) + +> 2.5 [Core](#structure-core) + +> 2.6 [`Assets` and `AssetTypes`](#structure-assettypes) + +> 2.7 [Large Sets](#structure-large-sets) + +> 2.8 [Material Library](#structure-material-library) + + + + + +### 2.1 Folder Names + +These are common rules for naming any folder in the content structure. + + + +#### 2.1.1 Always Use PascalCase[*](#terms-cases) + +PascalCase refers to starting a name with a capital letter and then instead of using spaces, every following word also starts with a capital letter. For example, `DesertEagle`, `RocketPistol`, and `ASeriesOfWords`. + +See [Cases](#terms-cases). + + + +#### 2.1.2 Never Use Spaces + +Re-enforcing [2.1.1](#2.1.1), never use spaces. Spaces can cause various engineering tools and batch processes to fail. Ideally, your project's root also contains no spaces and is located somewhere such as `D:\Project` instead of `C:\Users\My Name\My Documents\Unreal Projects`. + + + +#### 2.1.3 Never Use Unicode Characters And Other Symbols + +If one of your game characters is named 'Zoë', its folder name should be `Zoe`. Unicode characters can be worse than [Spaces](#2.1.2) for engineering tool and some parts of UE4 don't support Unicode characters in paths either. + +Related to this, if your project has [unexplained issues](https://answers.unrealengine.com/questions/101207/undefined.html) and your computer's user name has a Unicode character (i.e. your name is `Zoë`), any project located in your `My Documents` folder will suffer from this issue. Often simply moving your project to something like `D:\Project` will fix these mysterious issues. + +Using other characters outside `a-z`, `A-Z`, and `0-9` such as `@`, `-`, `_`, `,`, `*`, and `#` can also lead to unexpected and hard to track issues on other platforms, source control, and weaker engineering tools. + + + + +### 2.2 Use A Top Level Folder For Project Specific Assets + +All of a project's assets should exist in a folder named after the project. For example, if your project is named 'Generic Shooter', _all_ of it's content should exist in `Content/GenericShooter`. + +> The `Developers` folder is not for assets that your project relies on and therefore is not project specific. See [Developer Folders](#2.3) for details about this. + +There are multiple reasons for this approach. + + + +#### 2.2.1 No Global Assets + +Often in code style guides it is written that you should not pollute the global namespace and this follows the same principle. When assets are allowed to exist outside of a project folder, it often becomes much harder to enforce a strict structure layout as assets not in a folder encourages the bad behavior of not having to organize assets. + +Every asset should have a purpose, otherwise it does not belong in a project. If an asset is an experimental test and shouldn't be used by the project it should be put in a [`Developer`](#2.3) folder. + + + +#### 2.2.2 Reduce Migration Conflicts + +When working on multiple projects it is common for a team to copy assets from one project to another if they have made something useful for both. When this occurs, the easiest way to perform the copy is to use the Content Browser's Migrate functionality as it will copy over not just the selected asset but all of its dependencies. + +These dependencies are what can easily get you into trouble. If two project's assets do not have a top level folder and they happen to have similarly named or already previously migrated assets, a new migration can accidentally wipe any changes to the existing assets. + +This is also the primary reason why Epic's Marketplace staff enforces the same policy for submitted assets. + +After a migration, safe merging of assets can be done using the 'Replace References' tool in the content browser with the added clarity of assets not belonging to a project's top level folder are clearly pending a merge. Once assets are merged and fully migrated, there shouldn't be another top level folder in your Content tree. This method is _100%_ guaranteed to make any migrations that occur completely safe. + + + +##### 2.2.2e1 Master Material Example + +For example, say you created a master material in one project that you would like to use in another project so you migrated that asset over. If this asset is not in a top level folder, it may have a name like `Content/MaterialLibrary/M_Master`. If the target project doesn't have a master material already, this should work without issue. + +As work on one or both projects progress, their respective master materials may change to be tailored for their specific projects due to the course of normal development. + +The issue comes when, for example, an artist for one project created a nice generic modular set of static meshes and someone wants to include that set of static meshes in the second project. If the artist who created the assets used material instances based on `Content/MaterialLibrary/M_Master` as they're instructed to, when a migration is performed there is a great chance of conflict for the previously migrated `Content/MaterialLibrary/M_Master` asset. + +This issue can be hard to predict and hard to account for. The person migrating the static meshes may not be the same person who is familiar with the development of both project's master material, and they may not be even aware that the static meshes in question rely on material instances which then rely on the master material. The Migrate tool requires the entire chain of dependencies to work however, and so it will be forced to grab `Content/MaterialLibrary/M_Master` when it copies these assets to the other project and it will overwrite the existing asset. + +It is at this point where if the master materials for both projects are incompatible in _any way_, you risk breaking possibly the entire material library for a project as well as any other dependencies that may have already been migrated, simply because assets were not stored in a top level folder. The simple migration of static meshes now becomes a very ugly task. + + + +#### 2.2.3 Samples, Templates, and Marketplace Content Are Risk-Free + +An extension to [2.2.2](#2.2.2), if a team member decides to add sample content, template files, or assets they bought from the marketplace, it is guaranteed, as long your project's top-level folder is uniquely named,that these new assets will not interfere with your project. + +You can not trust marketplace content to fully conform to the [top level folder rule](#2.2). There exists many assets that have the majority of their content in a top level folder but also have possibly modified Epic sample content as well as level files polluting the global `Content` folder. + +When adhering to [2.2](#2.2), the worst marketplace conflict you can have is if two marketplace assets both have the same Epic sample content. If all your assets are in a project specific folder, including sample content you may have moved into your folder, your project will never break. + +#### 2.2.4 DLC, Sub-Projects, and Patches Are Easily Maintained + +If your project plans to release DLC or has multiple sub-projects associated with it that may either be migrated out or simply not cooked in a build, assets relating to these projects should have their own separate top level content folder. This make cooking DLC separate from main project content far easier. Sub-projects can also be migrated in and out with minimal effort. If you need to change a material of an asset or add some very specific asset override behavior in a patch, you can easily put these changes in a patch folder and work safely without the chance of breaking the core project. + + + + + +### 2.3 Use Developers Folder For Local Testing + +During a project's development, it is very common for team members to have a sort of 'sandbox' where they can experiment freely without risking the core project. Because this work may be ongoing, these team members may wish to put their assets on a project's source control server. Not all teams require use of Developer folders, but ones that do use them often run into a common problem with assets submitted to source control. + +It is very easy for a team member to accidentally use assets that are not ready for use, which will cause issues once those assets are removed. For example, an artist may be iterating on a modular set of static meshes and still working on getting their sizing and grid snapping correct. If a world builder sees these assets in the main project folder, they might use them all over a level not knowing they could be subject to incredible change and/or removal. This causes massive amounts of re-working for everyone on the team to resolve. + +If these modular assets were placed in a Developer folder, the world builder should never have had a reason to use them and the whole issue would never happen. The Content Browser has specific View Options that will hide Developer folders (they are hidden by default) making it impossible to accidentally use Developer assets under normal use. + +Once the assets are ready for use, an artist simply has to move the assets into the project specific folder and fix up redirectors. This is essentially 'promoting' the assets from experimental to production. + + + + + +### 2.4 All Map[*](#terms-level-map) Files Belong In A Folder Called Maps + +Map files are incredibly special and it is common for every project to have its own map naming system, especially if they work with sub-levels or streaming levels. No matter what system of map organization is in place for the specific project, all levels should belong in `/Content/Project/Maps`. + +Being able to tell someone to open a specific map without having to explain where it is is a great time saver and general 'quality of life' improvement. It is common for levels to be within sub-folders of `Maps`, such as `Maps/Campaign1/` or `Maps/Arenas`, but the most important thing here is that they all exist within `/Content/Project/Maps`. + +This also simplifies the job of cooking for engineers. Wrangling levels for a build process can be extremely frustrating if they have to dig through arbitrary folders for them. If a team's maps are all in one place, it is much harder to accidentally not cook a map in a build. It also simplifies lighting build scripts as well as QA processes. + + + + + + + +### 2.5 Use A `Core` Folder For Critical Blueprints And Other Assets + +Use `/Content/Project/Core` folder for assets that are absolutely fundamental to a project's workings. For example, base `GameMode`, `Character`, `PlayerController`, `GameState`, `PlayerState`, and related Blueprints should live here. + +This creates a very clear "don't touch these" message for other team members. Non-engineers should have very little reason to enter the `Core` folder. Following good code structure style, designers should be making their gameplay tweaks in child classes that expose functionality. World builders should be using prefab Blueprints in designated folders instead of potentially abusing base classes. + +For example, if your project requires pickups that can be placed in a level, there should exist a base Pickup class in `Core/Pickups` that defines base behavior for a pickup. Specific pickups such as a Health or Ammo should exist in a folder such as `/Content/Project/Placeables/Pickups/`. Game designers can define and tweak pickups in this folder however they please, but they should not touch `Core/Pickups` as they may unintentionally break pickups project-wide. + + + + + + + +### 2.6 Do Not Create Folders Called `Assets` or `AssetTypes` + + + +#### 2.6.1 Creating a folder named `Assets` is redundant. + +All assets are assets. + + + +#### 2.6.2 Creating a folder named `Meshes`, `Textures`, or `Materials` is redundant. + +All asset names are named with their asset type in mind. These folders offer only redundant information and the use of these folders can easily be replaced with the robust and easy to use filtering system the Content Browser provides. + +Want to view only static mesh in `Environment/Rocks/`? Simply turn on the Static Mesh filter. If all assets are named correctly, they will also be sorted in alphabetical order regardless of prefixes. Want to view both static meshes and skeletal meshes? Simply turn on both filters. This eliminates the need to potentially have to `Control-Click` select two folders in the Content Browser's tree view. + +> This also extends the full path name of an asset for very little benefit. The `S_` prefix for a static mesh is only two characters, whereas `Meshes/` is seven characters. + +Not doing this also prevents the inevitability of someone putting a static mesh or a texture in a `Materials` folder. + + + + + +### 2.7 Very Large Asset Sets Get Their Own Folder Layout + +This can be seen as a pseudo-exception to [2.6](#2.6). + +There are certain asset types that have a huge volume of related files where each asset has a unique purpose. The two most common are Animation and Audio assets. If you find yourself having 15+ of these assets that belong together, they should be together. + +For example, animations that are shared across multiple characters should lay in `Characters/Common/Animations` and may have sub-folders such as `Locomotion` or `Cinematic`. + +> This does not apply to assets like textures and materials. It is common for a `Rocks` folder to have a large amount of textures if there are a large amount of rocks, however these textures are generally only related to a few specific rocks and should be named appropriately. Even if these textures are part of a [Material Library](#2.8). + + + + + +### 2.8 `MaterialLibrary` + +If your project makes use of master materials, layered materials, or any form of reusable materials or textures that do not belong to any subset of assets, these assets should be located in `Content/Project/MaterialLibrary`. + +This way all 'global' materials have a place to live and are easily located. + +> This also makes it incredibly easy to enforce a 'use material instances only' policy within a project. If all artists and assets should be using material instances, then the only regular material assets that should exist are within this folder. You can easily verify this by searching for base materials in any folder that isn't the `MaterialLibrary`. + +The `MaterialLibrary` doesn't have to consist of purely materials. Shared utility textures, material functions, and other things of this nature should be stored here as well within folders that designate their intended purpose. For example, generic noise textures should be located in `MaterialLibrary/Utility`. + +Any testing or debug materials should be within `MaterialLibrary/Debug`. This allows debug materials to be easily stripped from a project before shipping and makes it incredibly apparent if production assets are using them if reference errors are shown. + + + + + +### 2.9 No Empty Folders + +There simply shouldn't be any empty folders. They clutter the content browser. + +If you find that the content browser has an empty folder you can't delete, you should perform the following: +1. Be sure you're using source control. +1. Immediately run Fix Up Redirectors on your project. +1. Navigate to the folder on-disk and delete the assets inside. +1. Close the editor. +1. Make sure your source control state is in sync (i.e. if using Perforce, run a Reconcile Offline Work on your content directory) +1. Open the editor. Confirm everything still works as expected. If it doesn't, revert, figure out what went wrong, and try again. +1. Ensure the folder is now gone. +1. Submit changes to source control. + +**[⬆ Back to Top](#table-of-contents)** + + + + + + +## 3. Blueprints + +This section will focus on Blueprint classes and their internals. When possible, style rules conform to [Epic's Coding Standard](https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard). + +Remember: Blueprinting badly bears blunders, beware! (Phrase by [KorkuVeren](http://github.com/KorkuVeren)) + +### Sections + +> 3.1 [Compiling](#bp-compiling) + +> 3.2 [Variables](#bp-vars) + +> 3.3 [Functions](#bp-functions) + +> 3.4 [Graphs](#bp-graphs) + + + + + +### 3.1 Compiling + +All blueprints should compile with zero warnings and zero errors. You should fix blueprint warnings and errors immediately as they can quickly cascade into very scary unexpected behavior. + +Do *not* submit broken blueprints to source control. If you must store them on source control, shelve them instead. + +Broken blueprints can cause problems that manifest in other ways, such as broken references, unexpected behavior, cooking failures, and frequent unneeded recompilation. A broken blueprint has the power to break your entire game. + + + + + +### 3.2 Variables + +The words `variable` and `property` may be used interchangeably. + +#### Sections + +> 3.2.1 [Naming](#bp-vars) + +> 3.2.2 [Editable](#bp-vars-editable) + +> 3.2.3 [Categories](#bp-vars-categories) + +> 3.2.4 [Access](#bp-vars-access) + +> 3.2.5 [Advanced](#bp-vars-advanced) + +> 3.2.6 [Transient](#bp-vars-transient) + +> 3.2.7 [Config](#bp-vars-config) + + + + + +#### 3.2.1 Naming + + + + + +##### 3.2.1.1 Nouns + +All non-boolean variable names must be clear, unambiguous, and descriptive nouns. + + + + + +##### 3.2.1.2 PascalCase + +All non-boolean variables should be in the form of [PascalCase](#terms-cases). + + + +###### 3.2.1.2e Examples: + +* `Score` +* `Kills` +* `TargetPlayer` +* `Range` +* `CrosshairColor` +* `AbilityID` + + + + + +##### 3.2.1.3 Boolean `b` Prefix + +All booleans should be named in PascalCase but prefixed with a lowercase `b`. + +Example: Use `bDead` and `bEvil`, **not** `Dead` and `Evil`. + +UE4 Blueprint editors know not to include the `b` in user-friendly displays of the variable. + + + + + +##### 3.2.1.4 Boolean Names + + + +###### 3.2.1.4.1 General And Independent State Information + +All booleans should be named as descriptive adjectives when possible if representing general information. Do not include words that phrase the variable as a question, such as `Is`. This is reserved for functions. + +Example: Use `bDead` and `bHostile` **not** `bIsDead` and `bIsHostile`. + +Try to not use verbs such as `bRunning`. Verbs tend to lead to complex states. + + + +###### 3.2.1.4.2 Complex States + +Do not to use booleans to represent complex and/or dependent states. This makes state adding and removing complex and no longer easily readable. Use an enumeration instead. + +Example: When defining a weapon, do **not** use `bReloading` and `bEquipping` if a weapon can't be both reloading and equipping. Define an enumeration named `EWeaponState` and use a variable with this type named `WeaponState` instead. This makes it far easier to add new states to weapons. + +Example: Do **not** use `bRunning` if you also need `bWalking` or `bSprinting`. This should be defined as an enumeration with clearly defined state names. + + + + + +##### 3.2.1.5 Considered Context + +All variable names must not be redundant with their context as all variable references in Blueprint will always have context. + + + +###### 3.2.1.5e Examples: + +Consider a Blueprint called `BP_PlayerCharacter`. + +**Bad** + +* `PlayerScore` +* `PlayerKills` +* `MyTargetPlayer` +* `MyCharacterName` +* `CharacterSkills` +* `ChosenCharacterSkin` + +All of these variables are named redundantly. It is implied that the variable is representative of the `BP_PlayerCharacter` it belongs to because it is `BP_PlayerCharacter` that is defining these variables. + +**Good** + +* `Score` +* `Kills` +* `TargetPlayer` +* `Name` +* `Skills` +* `Skin` + + + + + +##### 3.2.1.6 Do _Not_ Include Atomic Type Names + +Atomic or primitive variables are variables that represent data in their simplest form, such as booleans, integers, floats, and enumerations. + +Strings and vectors are considered atomic in terms of style when working with Blueprints, however they are technically not atomic. + +> While vectors consist of three floats, vectors are often able to be manipulated as a whole, same with rotators. + +> Do _not_ consider Text variables as atomic, they are secretly hiding localization functionality. The atomic type of a string of characters is `String`, not `Text`. + +Atomic variables should not have their type name in their name. + +Example: Use `Score`, `Kills`, and `Description` **not** `ScoreFloat`, `FloatKills`, `DescriptionString`. + +The only exception to this rule is when a variable represents 'a number of' something to be counted _and_ when using a name without a variable type is not easy to read. + +Example: A fence generator needs to generate X number of posts. Store X in `NumPosts` or `PostsCount` instead of `Posts` as `Posts` may potentially read as an Array of a variable type named `Post`. + + + + + +##### 3.2.1.7 Do Include Non-Atomic Type Names + +Non-atomic or complex variables are variables that represent data as a collection of atomic variables. Structs, Classes, Interfaces, and primitives with hidden behavior such as `Text` and `Name` all qualify under this rule. + +> While an Array of an atomic variable type is a list of variables, Arrays do not change the 'atomicness' of a variable type. + +These variables should include their type name while still considering their context. + +If a class owns an instance of a complex variable, i.e. if a `BP_PlayerCharacter` owns a `BP_Hat`, it should be stored as the variable type as without any name modifications. + +Example: Use `Hat`, `Flag`, and `Ability` **not** `MyHat`, `MyFlag`, and `PlayerAbility`. + +If a class does not own the value a complex variable represents, you should use a noun along with the variable type. + +Example: If a `BP_Turret` has the ability to target a `BP_PlayerCharacter`, it should store its target as `TargetPlayer` as when in the context of `BP_Turret` it should be clear that it is a reference to another complex variable type that it does not own. + + + + + + +##### 3.2.1.8 Arrays + +Arrays follow the same naming rules as above, but should be named as a plural noun. + +Example: Use `Targets`, `Hats`, and `EnemyPlayers`, **not** `TargetList`, `HatArray`, `EnemyPlayerArray`. + + + + + + +#### 3.2.2 Editable Variables + +All variables that are safe to change the value of in order to configure behavior of a blueprint should be marked as `Editable`. + +Conversely, all variables that are not safe to change or should not be exposed to designers should _not_ be marked as editable, unless for engineering reasons the variable must be marked as `Expose On Spawn`. + +Do not arbitrarily mark variables as `Editable`. + + + + + +##### 3.2.2.1 Tooltips + +All `Editable` variables, including those marked editable just so they can be marked as `Expose On Spawn`, should have a description in their `Tooltip` fields that explains how changing this value affects the behavior of the blueprint. + + + + + +##### 3.2.2.2 Slider And Value Ranges + +All `Editable` variables should make use of slider and value ranges if there is ever a value that a variable should _not_ be set to. + +Example: A blueprint that generates fence posts might have an editable variable named `PostsCount` and a value of -1 would not make any sense. Use the range fields to mark 0 as a minimum. + +If an editable variable is used in a Construction Script, it should have a reasonable Slider Range defined so that someone can not accidentally assign it a large value that could crash the editor. + +A Value Range only needs to be defined if the bounds of a value are known. While a Slider Range prevents accidental large number inputs, an undefined Value Range allows a user to specify a value outside the Slider Range that may be considered 'dangerous' but still valid. + + + + + +#### 3.2.3 Categories + +If a class has only a small number of variables, categories are not required. + +If a class has a moderate amount of variables (5-10), all `Editable` variables should have a non-default category assigned. A common category is `Config`. + +If a class has a large amount of variables, all `Editable` variables should be categorized into sub-categories using the category `Config` as the base category. Non-editable variables should be categorized into descriptive categories describing their usage. + +> You can define sub-categories by using the pipe character `|`, i.e. `Config | Animations`. + +Example: A weapon class set of variables might be organized as: + + |-- Config + | |-- Animations + | |-- Effects + | |-- Audio + | |-- Recoil + | |-- Timings + |-- Animations + |-- State + |-- Visuals + + + + + +#### 3.2.4 Variable Access Level + +In C++, variables have a concept of access level. Public means any code outside the class can access the variable. Protected means only the class and any child classes can access this variable internally. Private means only this class and no child classes can access this variable. + +Blueprints do not have a defined concept of protected access currently. + +Treat `Editable` variables as public variables. Treat non-editable variables as protected variables. + + + + + +##### 3.2.4.1 Private Variables + +Unless it is known that a variable should only be accessed within the class it is defined and never a child class, do not mark variables as private. Until variables are able to be marked `protected`, reserve private for when you absolutely know you want to restrict child class usage. + + + + + +#### 3.2.5 Advanced Display + +If a variable should be editable but often untouched, mark it as `Advanced Display`. This makes the variable hidden unless the advanced display arrow is clicked. + +To find the `Advanced Display` option, it is listed as an advanced displayed variable in the variable details list. + + + + + +#### 3.2.6 Transient Variables + +Transient variables are variables that do not need to have their value saved and loaded and have an initial value of zero or null. This is useful for references to other objects and actors who's value isn't known until run-time. This prevents the editor from ever saving a reference to it, and speeds up saving and loading of the blueprint class. + +Because of this, all transient variables should always be initialized as zero or null. To do otherwise would result in hard to debug errors. + + + + + +#### 3.2.8 Config Variables + +Do not use the `Config Variable` flag. This makes it harder for designers to control blueprint behavior. Config variables should only be used in C++ for rarely changed variables. Think of them as `Advanced Advanced Display` variables. + + + + + +### 3.3 Functions, Events, and Event Dispatchers + +This section describes how you should author functions, events, and event dispatchers. Everything that applies to functions also applies to events, unless otherwise noted. + + + + + +#### 3.3.1 Function Naming + +The naming of functions, events, and event dispatchers is critically important. Based on the name alone, certain assumptions can be made about functions. For example: + +* Is it a pure function? +* Is it fetching state information? +* Is it a handler? +* Is it an RPC? +* What is its purpose? + +These questions and more can all be answered when functions are named appropriately. + + + + + +#### 3.3.1.1 All Functions Should Be Verbs + +All functions and events perform some form of action, whether its getting info, calculating data, or causing something to explode. Therefore, all functions should all start with verbs. They should be worded in the present tense whenever possible. They should also have some context as to what they are doing. + +`OnRep` functions, event handlers, and event dispatchers are an exception to this rule. + +Good examples: + +* `Fire` - Good example if in a Character / Weapon class, as it has context. Bad if in a Barrel / Grass / any ambiguous class. +* `Jump` - Good example if in a Character class, otherwise, needs context. +* `Explode` +* `ReceiveMessage` +* `SortPlayerArray` +* `GetArmOffset` +* `GetCoordinates` +* `UpdateTransforms` +* `EnableBigHeadMode` +* `IsEnemy` - ["Is" is a verb.](http://writingexplained.org/is-is-a-verb) + +Bad examples: + +* `Dead` - Is Dead? Will deaden? +* `Rock` +* `ProcessData` - Ambiguous, these words mean nothing. +* `PlayerState` - Nouns are ambiguous. +* `Color` - Verb with no context, or ambiguous noun. + + + + + +#### 3.3.1.2 Property RepNotify Functions Always `OnRep_Variable` + +All functions for replicated with notification variables should have the form `OnRep_Variable`. This is forced by the Blueprint editor. If you are writing a C++ `OnRep` function however, it should also follow this convention when exposing it to Blueprints. + + + + + +#### 3.3.1.3 Info Functions Returning Bool Should Ask Questions + +When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow [the verb rule](#bp-funcs-naming-verbs). + +This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded. + +Good examples: + +* `IsDead` +* `IsOnFire` +* `IsAlive` +* `IsSpeaking` +* `IsHavingAnExistentialCrisis` +* `IsVisible` +* `HasWeapon` - ["Has" is a verb.](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html) +* `WasCharging` - ["Was" is past-tense of "be".](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html) Use "was" when referring to 'previous frame' or 'previous state'. +* `CanReload` - ["Can" is a verb.](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html) + +Bad examples: + +* `Fire` - Is on fire? Will fire? Do fire? +* `OnFire` - Can be confused with event dispatcher for firing. +* `Dead` - Is dead? Will deaden? +* `Visibility` - Is visible? Set visibility? A description of flying conditions? + + + + + +#### 3.3.1.4 Event Handlers and Dispatchers Should Start With `On` + +Any function that handles an event or dispatches an event should start with `On` and continue to follow [the verb rule](#bp-funcs-naming-verbs). The verb may move to the end however if past-tense reads better. + +[Collocations](http://dictionary.cambridge.org/us/grammar/british-grammar/about-words-clauses-and-sentences/collocation) of the word `On` are exempt from following the verb rule. + +`Handle` is not allowed. It is 'Unreal' to use `On` instead of `Handle`, while other frameworks may prefer to use `Handle` instead of `On`. + +Good examples: + +* `OnDeath` - Common collocation in games +* `OnPickup` +* `OnReceiveMessage` +* `OnMessageRecieved` +* `OnTargetChanged` +* `OnClick` +* `OnLeave` + +Bad examples: + +* `OnData` +* `OnTarget` +* `HandleMessage` +* `HandleDeath` + + + + + +#### 3.3.1.5 Remote Procedure Calls Should Be Prefixed With Target + +Any time an RPC is created, it should be prefixed with either `Server`, `Client`, or `Multicast`. No exceptions. + +After the prefix, follow all other rules regarding function naming. + +Good examples: + +* `ServerFireWeapon` +* `ClientNotifyDeath` +* `MulticastSpawnTracerEffect` + +Bad examples: + +* `FireWeapon` - Does not indicate its an RPC of some kind. +* `ServerClientBroadcast` - Confusing. +* `AllNotifyDeath` - Use `Multicast`, never `All`. +* `ClientWeapon` - No verb, ambiguous. + + + + + + +#### 3.3.2 All Functions Must Have Return Nodes + +All functions must have return nodes, no exceptions. + +Return nodes explicitly note that a function has finished its execution. In a world where blueprints can be filled with `Sequence`, `ForLoopWithBreak`, and backwards reroute nodes, explicit execution flow is important for readability, maintenance, and easier debugging. + +The Blueprint compiler is able to follow the flow of execution and will warn you if there is a branch of your code with an unhandled return or bad flow if you use return nodes. + +In situations like where a programmer may add a pin to a Sequence node or add logic after a for loop completes but the loop iteration might return early, this can often result in an accidental error in code flow. The warnings the Blueprint compiler will alert everyone of these issues immediately. + + + + + +#### 3.3.3 No Function Should Have More Than 50 Nodes + +Simply, no function should have more than 50 nodes. Any function this big should be broken down into smaller functions for readability and ease of maintenance. + +The following nodes are not counted as they are deemed to not increase function complexity: + +* Comment +* Route +* Cast +* Getting a Variable +* Breaking a Struct +* Function Entry +* Self + + + + + +#### 3.3.4 All Public Functions Should Have A Description + +This rule applies more to public facing or marketplace blueprints, so that others can more easily navigate and consume your blueprint API. + +Simply, any function that has an access specificer of Public should have its description filled out. + + + + + +#### 3.3.5 All Custom Static Plugin `BlueprintCallable` Functions Must Be Categorized By Plugin Name + +If your project includes a plugin that defines `static` `BlueprintCallable` functions, they should have their category set to the plugin's name or a subset category of the plugin's name. + +For example, `Zed Camera Interface` or `Zed Camera Interface | Image Capturing`. + + + + + +### 3.4 Blueprint Graphs + +This section covers things that apply to all Blueprint graphs. + + + + + +#### 3.4.1 No Spaghetti + +Wires should have clear beginnings and ends. You should never have to mentally untangle wires to make sense of a graph. Many of the following sections are dedicated to reducing spaghetti. + + + + + +#### 3.4.2 Align Wires Not Nodes + +Always align wires, not nodes. You can't always control the size and pin location on a node, but you can always control the location of a node and thus control the wires. Straight wires provide clear linear flow. Wiggly wires wear wits wickedly. You can straighten wires by using the Straighten Connections command with BP nodes selected. Hotkey: Q + +Good example: The tops of the nodes are staggered to keep a perfectly straight white exec line. +![Aligned By Wires](https://github.com/allar/ue4-style-guide/raw/master/images/bp-graphs-align-wires-good.png "Aligned By Wires") + +Bad Example: The tops of the nodes are aligned creating a wiggly white exec line. +![Bad](https://github.com/allar/ue4-style-guide/raw/master/images/bp-graphs-align-wires-bad.png "Wiggly") + +Acceptable Example: Certain nodes might not cooperate no matter how you use the alignment tools. In this situation, try to minimize the wiggle by bringing the node in closer. +![Acceptable](https://github.com/allar/ue4-style-guide/raw/master/images/bp-graphs-align-wires-acceptable.png "Acceptable") + + + + + +#### 3.4.3 White Exec Lines Are Top Priority + +If you ever have to decide between straightening a linear white exec line or straightening data lines of some kind, always straighten the white exec line. + + + + + +#### 3.4.4 Graphs Should Be Reasonably Commented + +Blocks of nodes should be wrapped in comments that describe their higher-level behavior. While every function should be well named so that each individual node is easily readable and understandable, groups of nodes contributing to a purpose should have their purpose described in a comment block. If a function does not have many blocks of nodes and its clear that the nodes are serving a direct purpose in the function's goal, then they do not need to be commented as the function name and description should suffice. + + + + + +#### 3.4.5 Graphs Should Handle Casting Errors Where Appropriate + +If a function or event assumes that a cast always succeeds, it should appropriately report a failure in logic if the cast fails. This lets others know why something that is 'supposed to work' doesn't. A function should also attempt a graceful recover after a failed cast if it's known that the reference being casted could ever fail to be casted. + +This does not mean every cast node should have its failure handled. In many cases, especially events regarding things like collisions, it is expected that execution flow terminates on a failed cast quietly. + + + + + +#### 3.4.6 Graphs Should Not Have Any Dangling / Loose / Dead Nodes + +All nodes in all blueprint graphs must have a purpose. You should not leave dangling blueprint nodes around that have no purpose or are not executed. + +**[⬆ Back to Top](#table-of-contents)** + + + + + + + + +## 4. Static Meshes + +This section will focus on Static Mesh assets and their internals. + +### Sections + +> 4.1 [UVs](#s-uvs) + +> 4.2 [LODs](#s-lods) + +> 4.3 [Modular Socketless Snapping](#s-modular-snapping) + +> 4.4 [Must Have Collision](#s-collision) + +> 4.5 [Correct Scale](#s-scaled) + + + + + +### 4.1 Static Mesh UVs + +If Linter is reporting bad UVs and you can't seem to track it down, open the resulting `.log` file in your project's `Saved/Logs` folder for exact details as to why it's failing. I am hoping to include these messages in the Lint report in the future. + + + + + +#### 4.1.1 All Meshes Must Have UVs + +Pretty simple. All meshes, regardless how they are to be used, should not be missing UVs. + + + + + +#### 4.1.2 All Meshes Must Not Have Overlapping UVs for Lightmaps + +Pretty simple. All meshes, regardless how they are to be used, should have valid non-overlapping UVs. + + + + + +### 4.2 LODs Should Be Set Up Correctly + +This is a subjective check on a per-project basis, but as a general rule any mesh that can be seen at varying distances should have proper LODs. + + + + + +### 4.3 Modular Socketless Assets Should Snap To The Grid Cleanly + +This is a subjective check on a per-asset basis, however any modular socketless assets should snap together cleanly based on the project's grid settings. + +It is up to the project whether to snap based on a power of 2 grid or on a base 10 grid. However if you are authoring modular socketless assets for the marketplace, Epic's requirement is that they snap cleanly when the grid is set to 10 units or bigger. + + + + + +### 4.4 All Meshes Must Have Collision + +Regardless of whether an asset is going to be used for collision in a level, all meshes should have proper collision defined. This helps the engine with things such as bounds calculations, occlusion, and lighting. Collision should also be well-formed to the asset. + + + + + +### 4.5 All Meshes Should Be Scaled Correctly + +This is a subjective check on a per-project basis, however all assets should be scaled correctly to their project. Level designers or blueprint authors should not have to tweak the scale of meshes to get them to confirm in the editor. Scaling meshes in the engine should be treated as a scale override, not a scale correction. + +**[⬆ Back to Top](#table-of-contents)** + + + + + + + + +## 5. Niagara + +This section will focus on Niagara assets and their internals. + +### Sections + +> 5.1 [Naming Rules](#ng-rules) + + + + + +### 5.1 No Spaces, Ever + +As mentioned in [00.1 Forbidden Identifiers](#00), spaces and all white space characters are forbidden in identifiers. This is especially true for Niagara systems as it makes working with things significantly harder if not impossible when working with HLSL or other means of scripting within Niagara and trying to reference an identifier. + +(Original Contribution by [@dunenkoff](https://github.com/Allar/ue5-style-guide/issues/58)) + + +**[⬆ Back to Top](#table-of-contents)** + + + + + + + + +## 6. Levels / Maps + +[See Terminology Note](#terms-level-map) regarding "levels" vs "maps". + +This section will focus on Level assets and their internals. + +### Sections + +> 6.1 [No Errors Or Warnings](#levels-no-errors-or-warnings) + +> 6.2 [Lighting Should Be Built](#levels-lighting-should-be-built) + +> 6.3 [No Player Visible Z Fighting](#evels-no-visible-z-fighting) + +> 6.4 [Marketplace Specific Rules](#evels-levels-mp-rules) + + + + + +### 6.1 No Errors Or Warnings + +All levels should load with zero errors or warnings. If a level loads with any errors or warnings, they should be fixed immediately to prevent cascading issues. + +You can run a map check on an open level in the editor by using the console command "map check". + +Please note: Linter is even more strict on this than the editor is currently, and will catch load errors that the editor will resolve on its own. + + + + + +### 6.2 Lighting Should Be Built + +It is normal during development for levels to occasionally not have lighting built. When doing a test/internal/shipping build or any build that is to be distributed however, lighting should always be built. + + + + + +### 6.3 No Player Visible Z Fighting + +Levels should not have any [z-fighting](https://en.wikipedia.org/wiki/Z-fighting) in all areas visible to the player. + + + + + +### 6.4 Marketplace Specific Rules + +If a project is to be sold on the UE4 Marketplace, it must follow these rules. + + + + + +### 6.4.1 Overview Level + +If your project contains assets that should be visualized or demoed, you must have a map within your project that contains the name "Overview". + +This overview map, if it is visualizing assets, should be set up according to [Epic's guidelines](http://help.epicgames.com/customer/en/portal/articles/2592186-marketplace-submission-guidelines-preparing-your-assets#Required%20Levels%20and%20Maps). + +For example, `InteractionComponent_Overview`. + + + + + +### 6.4.2 Demo Level + +If your project contains assets that should be demoed or come with some sort of tutorial, you must have a map within your project that contains the name "Demo". This level should also contain documentation within it in some form that illustrates how to use your project. See Epic's Content Examples project for good examples on how to do this. + +If your project is a gameplay mechanic or other form of system as opposed to an art pack, this can be the same as your "Overview" map. + +For example, `InteractionComponent_Overview_Demo`, `ExplosionKit_Demo`. + +**[⬆ Back to Top](#table-of-contents)** + + + + + + +## 7. Textures + +This section will focus on Texture assets and their internals. + +### Sections + +> 7.1 [Dimensions Are Powers of 2](#textures-dimension) + +> 7.2 [Texture Density Should Be Uniform](#textures-dimension) + +> 7.3 [Textures Should Be No Bigger than 8192](#textures-max-size) + +> 7.4 [Correct Texture Groups](#textures-textures-group) + + + + + +### 7.1 Dimensions Are Powers of 2 + +All textures, except for UI textures, must have its dimensions in multiples of powers of 2. Textures do not have to be square. + +For example, `128x512`, `1024x1024`, `2048x1024`, `1024x2048`, `1x512`. + + + + + +### 7.2 Texture Density Should Be Uniform + +All textures should be of a size appropriate for their standard use case. Appropriate texture density varies from project to project, but all textures within that project should have a consistent density. + +For example, if a project's texture density is 8 pixel per 1 unit, a texture that is meant to be applied to a 100x100 unit cube should be 1024x1024, as that is the closest power of 2 that matches the project's texture density. + + + + + +### 7.3 Textures Should Be No Bigger than 8192 + +No texture should have a dimension that exceeds 8192 in size, unless you have a very explicit reason to do so. Often, using a texture this big is simply just a waste of resources. + + + + + +### 7.4 Textures Should Be Grouped Correctly + +Every texture has a Texture Group property used for LODing, and this should be set correctly based on its use. For example, all UI textures should belong in the UI texture group. + +**[⬆ Back to Top](#table-of-contents)** + + diff --git a/sites/styleguide.tex b/sites/styleguide.tex new file mode 100644 index 0000000..a672b21 --- /dev/null +++ b/sites/styleguide.tex @@ -0,0 +1,2397 @@ +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{hyphens}{url} +\PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor} +% +\documentclass[ + letterpaper, + DIV=11, + numbers=noendperiod, + oneside]{scrartcl} + +\usepackage{amsmath,amssymb} +\usepackage{iftex} +\ifPDFTeX + \usepackage[T1]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols +\else % if luatex or xetex + \usepackage{unicode-math} + \defaultfontfeatures{Scale=MatchLowercase} + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +\fi +\usepackage{lmodern} +\ifPDFTeX\else + % xetex/luatex font selection +\fi +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +\usepackage{xcolor} +\usepackage[left=1in,marginparwidth=2.0666666666667in,textwidth=4.1333333333333in,marginparsep=0.3in]{geometry} +\setlength{\emergencystretch}{3em} % prevent overfull lines +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +% Make \paragraph and \subparagraph free-standing +\makeatletter +\ifx\paragraph\undefined\else + \let\oldparagraph\paragraph + \renewcommand{\paragraph}{ + \@ifstar + \xxxParagraphStar + \xxxParagraphNoStar + } + \newcommand{\xxxParagraphStar}[1]{\oldparagraph*{#1}\mbox{}} + \newcommand{\xxxParagraphNoStar}[1]{\oldparagraph{#1}\mbox{}} +\fi +\ifx\subparagraph\undefined\else + \let\oldsubparagraph\subparagraph + \renewcommand{\subparagraph}{ + \@ifstar + \xxxSubParagraphStar + \xxxSubParagraphNoStar + } + \newcommand{\xxxSubParagraphStar}[1]{\oldsubparagraph*{#1}\mbox{}} + \newcommand{\xxxSubParagraphNoStar}[1]{\oldsubparagraph{#1}\mbox{}} +\fi +\makeatother + + +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}\usepackage{longtable,booktabs,array} +\usepackage{calc} % for calculating minipage widths +% Correct order of tables after \paragraph or \subparagraph +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +% Allow footnotes in longtable head/foot +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +\usepackage{graphicx} +\makeatletter +\newsavebox\pandoc@box +\newcommand*\pandocbounded[1]{% scales image to fit in text height/width + \sbox\pandoc@box{#1}% + \Gscale@div\@tempa{\textheight}{\dimexpr\ht\pandoc@box+\dp\pandoc@box\relax}% + \Gscale@div\@tempb{\linewidth}{\wd\pandoc@box}% + \ifdim\@tempb\p@<\@tempa\p@\let\@tempa\@tempb\fi% select the smaller of both + \ifdim\@tempa\p@<\p@\scalebox{\@tempa}{\usebox\pandoc@box}% + \else\usebox{\pandoc@box}% + \fi% +} +% Set default figure placement to htbp +\def\fps@figure{htbp} +\makeatother + +\KOMAoption{captions}{tableheading} +\makeatletter +\@ifpackageloaded{caption}{}{\usepackage{caption}} +\AtBeginDocument{% +\ifdefined\contentsname + \renewcommand*\contentsname{Table of contents} +\else + \newcommand\contentsname{Table of contents} +\fi +\ifdefined\listfigurename + \renewcommand*\listfigurename{List of Figures} +\else + \newcommand\listfigurename{List of Figures} +\fi +\ifdefined\listtablename + \renewcommand*\listtablename{List of Tables} +\else + \newcommand\listtablename{List of Tables} +\fi +\ifdefined\figurename + \renewcommand*\figurename{Figure} +\else + \newcommand\figurename{Figure} +\fi +\ifdefined\tablename + \renewcommand*\tablename{Table} +\else + \newcommand\tablename{Table} +\fi +} +\@ifpackageloaded{float}{}{\usepackage{float}} +\floatstyle{ruled} +\@ifundefined{c@chapter}{\newfloat{codelisting}{h}{lop}}{\newfloat{codelisting}{h}{lop}[chapter]} +\floatname{codelisting}{Listing} +\newcommand*\listoflistings{\listof{codelisting}{List of Listings}} +\makeatother +\makeatletter +\makeatother +\makeatletter +\@ifpackageloaded{caption}{}{\usepackage{caption}} +\@ifpackageloaded{subcaption}{}{\usepackage{subcaption}} +\makeatother +\makeatletter +\@ifpackageloaded{sidenotes}{}{\usepackage{sidenotes}} +\@ifpackageloaded{marginnote}{}{\usepackage{marginnote}} +\makeatother + +\usepackage{bookmark} + +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\urlstyle{same} % disable monospaced font for URLs +\hypersetup{ + pdftitle={Styleguide}, + colorlinks=true, + linkcolor={blue}, + filecolor={Maroon}, + citecolor={Blue}, + urlcolor={Blue}, + pdfcreator={LaTeX via pandoc}} + + +\title{Styleguide} +\author{} +\date{} + +\begin{document} +\maketitle + + +This Styleguiade is adapted by Gamemakin UE5 Styleguide. + +\subsection{Important Terminology}\label{important-terminology} + +\subparagraph{Levels/Maps}\label{levelsmaps} + +The word `map' generally refers to what the average person calls a +`level' and may be used interchangeably. See this term's history +\href{https://en.wikipedia.org/wiki/Level_(video_gaming)}{here}. + +\subparagraph{Identifiers}\label{identifiers} + +An \texttt{Identifier} is anything that resembles or serves as a +``name''. For example, the name of an asset, or the name of a material +later, or a blueprint property, a variable, or a folder name, or for a +data table row name, etc\ldots{} + +\subparagraph{Cases}\label{cases} + +There are a few different ways you can \texttt{CaseWordsWhenNaming}. +Here are some common casing types: + +\begin{quote} +PascalCase + +Capitalize every word and remove all spaces, e.g.~\texttt{DesertEagle}, +\texttt{StyleGuide}, \texttt{ASeriesOfWords}. + +camelCase + +The first letter is always lowercase but every following word starts +with uppercase, e.g.~\texttt{desertEagle}, \texttt{styleGuide}, +\texttt{aSeriesOfWords}. + +Snake\_case + +Words can arbitrarily start upper or lowercase but words are separated +by an underscore, e.g.~\texttt{desert\_Eagle}, \texttt{Style\_Guide}, +\texttt{a\_Series\_of\_Words}. +\end{quote} + +\subparagraph{Variables / Properties}\label{variables-properties} + +The words `variable' and `property' in most contexts are interchangable. +If they are both used together in the same context however: + +Property + +Usually refers to a variable defined in a class. For example, if +\texttt{BP\_Barrel} had a variable \texttt{bExploded}, +\texttt{bExploded} may be referred to as a property of +\texttt{BP\_Barrel}. + +When in the context of a class, it is often used to imply accessing +previously defined data. + +Variable + +Usually refers to a variable defined as a function argument or a local +variable inside a function. + +When in the context of a class, it is often used to convey discussion +about its definition and what it will hold. + +\subsection{0. Principles}\label{principles} + +These principles have been adapted from +\href{https://github.com/rwaldron/idiomatic.js/}{idomatic.js style +guide}. + +\subsubsection{0.1 If your UE4 project already has a style guide, you +should follow +it.}\label{if-your-ue4-project-already-has-a-style-guide-you-should-follow-it.} + +If you are working on a project or with a team that has a pre-existing +style guide, it should be respected. Any inconsistency between an +existing style guide and this guide should defer to the existing. + +Style guides should be living documents. You should propose style guide +changes to an existing style guide as well as this guide if you feel the +change benefits all usages. + +\begin{quote} +\mbox{}% +\paragraph{``Arguments over style are pointless. There should be a style +guide, and you should follow +it.''}\label{arguments-over-style-are-pointless.-there-should-be-a-style-guide-and-you-should-follow-it.} + +\href{https://rmurphey.com}{\emph{Rebecca Murphey}} +\end{quote} + +\subsubsection{0.2 All structure, assets, and code in any Unreal Engine +4 project should look like a single person created it, no matter how +many people +contributed.}\label{all-structure-assets-and-code-in-any-unreal-engine-4-project-should-look-like-a-single-person-created-it-no-matter-how-many-people-contributed.} + +Moving from one project to another should not cause a re-learning of +style and structure. Conforming to a style guide removes unneeded +guesswork and ambiguities. + +It also allows for more productive creation and maintenance as one does +not need to think about style. Simply follow the instructions. This +style guide is written with best practices in mind, meaning that by +following this style guide you will also minimize hard to track issues. + +\subsubsection{0.3 Friends do not let friends have bad +style.}\label{friends-do-not-let-friends-have-bad-style.} + +If you see someone working either against a style guide or no style +guide, try to correct them. + +When working within a team or discussing within a community such as +\href{http://join.unrealslackers.org/}{Unreal Slackers}, it is far +easier to help and to ask for help when people are consistent. Nobody +likes to help untangle someone's Blueprint spaghetti or deal with assets +that have names they can't understand. + +If you are helping someone whose work conforms to a different but +consistent and sane style guide, you should be able to adapt to it. If +they do not conform to any style guide, please direct them here. + +\subsubsection{0.4 A team without a style guide is no team of +mine.}\label{a-team-without-a-style-guide-is-no-team-of-mine.} + +When joining an Unreal Engine 4 team, one of your first questions should +be ``Do you have a style guide?''. If the answer is no, you should be +skeptical about their ability to work as a team. + +\subsubsection{0.5 Don't Break The Law}\label{dont-break-the-law} + +Gamemakin LLC is not a lawyer, but please don't introduce illegal +actions and behavior to a project, including but not limited to: + +\begin{itemize} +\tightlist +\item + Don't distribute content you don't have the rights to distribute +\item + Don't infringe on someone else's copyrighted or trademark material +\item + Don't steal content +\item + Follow licensing restrictions on content, e.g.~attribute when + attributions are needed +\end{itemize} + +\subsection{00. Globally Enforced +Opinions}\label{globally-enforced-opinions} + +@TODO\marginpar{\begin{footnotesize}{?quarto-cite:TODO}\vspace{2mm}\par\end{footnotesize}}: +Make this section 1 and update this document accordingly. Or maybe we +don't? + +\subsubsection{00.1 Forbidden Characters}\label{forbidden-characters} + +\paragraph{Identifiers}\label{identifiers-1} + +In any \texttt{Identifier} of any kind, \textbf{never} use the following +unless absolutely forced to: + +\begin{itemize} +\tightlist +\item + White space of any kind +\item + Backward slashes \texttt{\textbackslash{}} +\item + Symbols i.e.~\texttt{\#!@\$\%} +\item + Any Unicode character +\end{itemize} + +Any \texttt{Identifier} should strive to only have the following +characters when possible (the \n \texttt{{[}A-Za-z0-9\_{]}+}) + +\begin{itemize} +\tightlist +\item + ABCDEFGHIJKLMNOPQRSTUVWXYZ +\item + abcdefghijklmnopqrstuvwxyz +\item + 1234567890 +\item + \_ (sparingly) +\end{itemize} + +The reasoning for this is this will ensure the greatest compatibility of +all data across all platforms across all tools, and help prevent +downtime due to potentially bad character handling for identifiers in +code you don't control. + +\subsection{Table of Contents}\label{table-of-contents} + +\begin{quote} +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\tightlist +\item + \hyperref[anc]{Asset Naming Conventions} +\item + \hyperref[structure]{Directory Structure} +\item + \hyperref[bp]{Blueprints} +\item + \hyperref[s]{Static Meshes} +\item + \hyperref[ps]{Particle Systems} +\item + \hyperref[levels]{Levels / Maps} +\item + \hyperref[textures]{Textures} +\end{enumerate} +\end{quote} + +\subsection{1. Asset Naming Conventions}\label{asset-naming-conventions} + +Naming conventions should be treated as law. A project that conforms to +a naming convention is able to have its assets managed, searched, +parsed, and maintained with incredible ease. + +Most things are prefixed with prefixes being generally an acronym of the +asset type followed by an underscore. + +\subsubsection{\texorpdfstring{1.1 Base Asset Name - +\texttt{Prefix\_BaseAssetName\_Variant\_Suffix}}{1.1 Base Asset Name - Prefix\_BaseAssetName\_Variant\_Suffix}}\label{base-asset-name---prefix_baseassetname_variant_suffix} + +All assets should have a \emph{Base Asset Name}. A Base Asset Name +represents a logical grouping of related assets. Any asset that is part +of this logical group should follow the standard of +\texttt{Prefix\_BaseAssetName\_Variant\_Suffix}. + +Keeping the pattern \texttt{Prefix\_BaseAssetName\_Variant\_Suffix} and +in mind and using common sense is generally enough to warrant good asset +names. Here are some detailed rules regarding each element. + +\texttt{Prefix} and \texttt{Suffix} are to be determined by the asset +type through the following \hyperref[asset-name-modifiers]{Asset Name +Modifier} tables. + +\texttt{BaseAssetName} should be determined by a short and easily +recognizable name related to the context of this group of assets. For +example, if you had a character named Bob, all of Bob's assets would +have the \texttt{BaseAssetName} of \texttt{Bob}. + +For unique and specific variations of assets, \texttt{Variant} is either +a short and easily recognizable name that represents logical grouping of +assets that are a subset of an asset's base name. For example, if Bob +had multiple skins these skins should still use \texttt{Bob} as the +\texttt{BaseAssetName} but include a recognizable \texttt{Variant}. An +`Evil' skin would be referred to as \texttt{Bob\_Evil} and a `Retro' +skin would be referred to as \texttt{Bob\_Retro}. + +For unique but generic variations of assets, \texttt{Variant} is a two +digit number starting at \texttt{01}. For example, if you have an +environment artist generating nondescript rocks, they would be named +\texttt{Rock\_01}, \texttt{Rock\_02}, \texttt{Rock\_03}, etc. Except for +rare exceptions, you should never require a three digit variant number. +If you have more than 100 assets, you should consider organizing them +with different base names or using multiple variant names. + +Depending on how your asset variants are made, you can chain together +variant names. For example, if you are creating flooring assets for an +Arch Viz project you should use the base name \texttt{Flooring} with +chained variants such as \texttt{Flooring\_Marble\_01}, +\texttt{Flooring\_Maple\_01}, \texttt{Flooring\_Tile\_Squares\_01}. + +\paragraph{1.1 Examples}\label{examples} + +\subparagraph{1.1e1 Bob}\label{e1-bob} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 2\tabcolsep) * \real{0.2840}} + >{\raggedright\arraybackslash}p{(\linewidth - 2\tabcolsep) * \real{0.7160}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Asset Name +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Skeletal Mesh & SK\_Bob \\ +Material & M\_Bob \\ +Texture (Diffuse/Albedo) & T\_Bob\_D \\ +Texture (Normal) & T\_Bob\_N \\ +Texture (Evil Diffuse) & T\_Bob\_Evil\_D \\ +\end{longtable} + +\subparagraph{1.1e2 Rocks}\label{e2-rocks} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 2\tabcolsep) * \real{0.2840}} + >{\raggedright\arraybackslash}p{(\linewidth - 2\tabcolsep) * \real{0.7160}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Asset Name +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Static Mesh (01) & S\_Rock\_01 \\ +Static Mesh (02) & S\_Rock\_02 \\ +Static Mesh (03) & S\_Rock\_03 \\ +Material & M\_Rock \\ +Material Instance (Snow) & MI\_Rock\_Snow \\ +\end{longtable} + +\subsubsection{1.2 Asset Name Modifiers}\label{asset-name-modifiers} + +When naming an asset, use these tables to determine the prefix and +suffix to use with an asset's \hyperref[base-asset-name]{Base Asset +Name}. + +\paragraph{Sections}\label{sections} + +\begin{quote} +1.2.1 \hyperref[anc-common]{Most Common} +\end{quote} + +\begin{quote} +1.2.2 \hyperref[anc-animations]{Animations} +\end{quote} + +\begin{quote} +1.2.3 \hyperref[anc-ai]{Artificial Intelligence} +\end{quote} + +\begin{quote} +1.2.4 \hyperref[anc-bp]{Blueprints} +\end{quote} + +\begin{quote} +1.2.5 \hyperref[anc-materials]{Materials} +\end{quote} + +\begin{quote} +1.2.6 \hyperref[anc-textures]{Textures} +\end{quote} + +\begin{quote} +1.2.7 \hyperref[anc-misc]{Miscellaneous} +\end{quote} + +\begin{quote} +1.2.8 \hyperref[anc-paper2d]{Paper 2D} +\end{quote} + +\begin{quote} +1.2.9 \hyperref[anc-physics]{Physics} +\end{quote} + +\begin{quote} +1.2.10 \hyperref[anc-sounds]{Sound} +\end{quote} + +\begin{quote} +1.2.11 \hyperref[anc-ui]{User Interface} +\end{quote} + +\begin{quote} +1.2.12 \hyperref[anc-effects]{Effects} +\end{quote} + +\paragraph{1.2.1 Most Common}\label{most-common} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Level / Map & & & \hyperref[2.4]{Should be in a folder called Maps.} \\ +Level (Persistent) & & \_P & \\ +Level (Audio) & & \_Audio & \\ +Level (Lighting) & & \_Lighting & \\ +Level (Geometry) & & \_Geo & \\ +Level (Gameplay) & & \_Gameplay & \\ +Blueprint & BP\_ & & \\ +Material & M\_ & & \\ +Static Mesh & S\_ & & Many use SM\_. We use S\_. \\ +Skeletal Mesh & SK\_ & & \\ +Texture & T\_ & \_? & See \hyperref[anc-textures]{Textures} \\ +Particle System & PS\_ & & \\ +Widget Blueprint & WBP\_ & & \\ +\end{longtable} + +\paragraph{1.2.2 Animations}\label{animations} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Aim Offset & AO\_ & & \\ +Aim Offset 1D & AO\_ & & \\ +Animation Blueprint & ABP\_ & & \\ +Animation Composite & AC\_ & & \\ +Animation Montage & AM\_ & & \\ +Animation Sequence & A\_ & & \\ +Blend Space & BS\_ & & \\ +Blend Space 1D & BS\_ & & \\ +Level Sequence & LS\_ & & \\ +Morph Target & MT\_ & & \\ +Paper Flipbook & PFB\_ & & \\ +Rig & Rig\_ & & \\ +Control Rig & CR\_ & & \\ +Skeletal Mesh & SK\_ & & \\ +Skeleton & SKEL\_ & & \\ +\end{longtable} + +\subsubsection{1.2.3 Artificial +Intelligence}\label{artificial-intelligence} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +AI Controller & AIC\_ & & \\ +Behavior Tree & BT\_ & & \\ +Blackboard & BB\_ & & \\ +Decorator & BTDecorator\_ & & \\ +Service & BTService\_ & & \\ +Task & BTTask\_ & & \\ +Environment Query & EQS\_ & & \\ +EnvQueryContext & EQS\_ & Context & \\ +\end{longtable} + +\subsubsection{1.2.4 Blueprints}\label{blueprints} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Blueprint & BP\_ & & \\ +Blueprint Component & BP\_ & Component & I.e. BP\_InventoryComponent \\ +Blueprint Function Library & BPFL\_ & & \\ +Blueprint Interface & BPI\_ & & \\ +Blueprint Macro Library & BPML\_ & & Do not use macro libraries if +possible. \\ +Enumeration & E & & No underscore. \\ +Structure & F or S & & No underscore. \\ +Tutorial Blueprint & TBP\_ & & \\ +Widget Blueprint & WBP\_ & & \\ +\end{longtable} + +\subsubsection{1.2.5 Materials}\label{materials} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3580}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1235}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1235}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3951}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Material & M\_ & & \\ +Material (Post Process) & PP\_ & & \\ +Material Function & MF\_ & & \\ +Material Instance & MI\_ & & \\ +Material Parameter Collection & MPC\_ & & \\ +Subsurface Profile & SP\_ & & \\ +Physical Materials & PM\_ & & \\ +Decal & M\_, MI\_ & \_Decal & \\ +\end{longtable} + +\subsubsection{1.2.6 Textures}\label{textures} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Texture & T\_ & & \\ +Texture (Diffuse/Albedo/Base Color) & T\_ & \_D & \\ +Texture (Normal) & T\_ & \_N & \\ +Texture (Roughness) & T\_ & \_R & \\ +Texture (Alpha/Opacity) & T\_ & \_A & \\ +Texture (Ambient Occlusion) & T\_ & \_O & \\ +Texture (Bump) & T\_ & \_B & \\ +Texture (Emissive) & T\_ & \_E & \\ +Texture (Mask) & T\_ & \_M & \\ +Texture (Specular) & T\_ & \_S & \\ +Texture (Metallic) & T\_ & \_M & \\ +Texture (Packed) & T\_ & \_* & See notes below about +\hyperref[anc-textures-packing]{packing}. \\ +Texture Cube & TC\_ & & \\ +Media Texture & MT\_ & & \\ +Render Target & RT\_ & & \\ +Cube Render Target & RTC\_ & & \\ +Texture Light Profile & TLP & & \\ +\end{longtable} + +\paragraph{1.2.6.1 Texture Packing}\label{texture-packing} + +It is common practice to pack multiple layers of texture data into one +texture. An example of this is packing Emissive, Roughness, Ambient +Occlusion together as the Red, Green, and Blue channels of a texture +respectively. To determine the suffix, simply stack the given suffix +letters from above together, e.g.~\texttt{\_ERO}. + +\begin{quote} +It is generally acceptable to include an Alpha/Opacity layer in your +Diffuse/Albedo's alpha channel and as this is common practice, adding +\texttt{A} to the \texttt{\_D} suffix is optional. +\end{quote} + +Packing 4 channels of data into a texture (RGBA) is not recommended +except for an Alpha/Opacity mask in the Diffuse/Albedo's alpha channel +as a texture with an alpha channel incurs more overhead than one +without. + +\subsubsection{1.2.7 Miscellaneous}\label{miscellaneous} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1282}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1282}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4103}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Animated Vector Field & VFA\_ & & \\ +Camera Anim & CA\_ & & \\ +Color Curve & Curve\_ & \_Color & \\ +Curve Table & Curve\_ & \_Table & \\ +Data Asset & *\_ & & Prefix should be based on class. \\ +Data Table & DT\_ & & \\ +Float Curve & Curve\_ & \_Float & \\ +Foliage Type & FT\_ & & \\ +Force Feedback Effect & FFE\_ & & \\ +Landscape Grass Type & LG\_ & & \\ +Landscape Layer & LL\_ & & \\ +Matinee Data & Matinee\_ & & \\ +Media Player & MP\_ & & \\ +Object Library & OL\_ & & \\ +Redirector & & & These should be fixed up ASAP. \\ +Sprite Sheet & SS\_ & & \\ +Static Vector Field & VF\_ & & \\ +Substance Graph Instance & SGI\_ & & \\ +Substance Instance Factory & SIF\_ & & \\ +Touch Interface Setup & TI\_ & & \\ +Vector Curve & Curve\_ & \_Vector & \\ +\end{longtable} + +\subsubsection{1.2.8 Paper 2D}\label{paper-2d} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Paper Flipbook & PFB\_ & & \\ +Sprite & SPR\_ & & \\ +Sprite Atlas Group & SPRG\_ & & \\ +Tile Map & TM\_ & & \\ +Tile Set & TS\_ & & \\ +\end{longtable} + +\subsubsection{1.2.9 Physics}\label{physics} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Physical Material & PM\_ & & \\ +Physics Asset & PHYS\_ & & \\ +Destructible Mesh & DM\_ & & \\ +\end{longtable} + +\subsubsection{1.2.10 Sounds}\label{sounds} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Dialogue Voice & DV\_ & & \\ +Dialogue Wave & DW\_ & & \\ +Media Sound Wave & MSW\_ & & \\ +Reverb Effect & Reverb\_ & & \\ +Sound Attenuation & ATT\_ & & \\ +Sound Class & & & No prefix/suffix. Should be put in a folder called +SoundClasses \\ +Sound Concurrency & & \_SC & Should be named after a SoundClass \\ +Sound Cue & A\_ & \_Cue & \\ +Sound Mix & Mix\_ & & \\ +Sound Wave & A\_ & & \\ +\end{longtable} + +\subsubsection{1.2.11 User Interface}\label{user-interface} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Font & Font\_ & & \\ +Slate Brush & Brush\_ & & \\ +Slate Widget Style & Style\_ & & \\ +Widget Blueprint & WBP\_ & & \\ +\end{longtable} + +\subsubsection{1.2.12 Effects}\label{effects} + +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3067}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1333}} + >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.4267}}@{}} +\toprule\noalign{} +\begin{minipage}[b]{\linewidth}\raggedright +Asset Type +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Prefix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Suffix +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Notes +\end{minipage} \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +Particle System & PS\_ & & \\ +Material (Post Process) & PP\_ & & \\ +\end{longtable} + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{2. Content Directory +Structure}\label{content-directory-structure} + +Equally important as asset names, the directory structure style of a +project should be considered law. Asset naming conventions and content +directory structure go hand in hand, and a violation of either causes +unneeded chaos. + +There are multiple ways to lay out the content of a UE4 project. In this +style, we will be using a structure that relies more on filtering and +search abilities of the Content Browser for those working with assets to +find assets of a specific type instead of another common structure that +groups asset types with folders. + +\begin{quote} +If you are using the prefix \hyperref[1.2]{naming convention} above, +using folders to contain assets of similar types such as +\texttt{Meshes}, \texttt{Textures}, and \texttt{Materials} is a +redundant practice as asset types are already both sorted by prefix as +well as able to be filtered in the content browser. +\end{quote} + +\#\#\# 2e1 Example Project Content Structure + +The reasons for this structure are listed in the following sub-sections. + +\subsubsection{Sections}\label{sections-1} + +\begin{quote} +2.1 \hyperref[structure-folder-names]{Folder Names} +\end{quote} + +\begin{quote} +2.2 \hyperref[structure-top-level]{Top-Level Folders} +\end{quote} + +\begin{quote} +2.3 \hyperref[structure-developers]{Developer Folders} +\end{quote} + +\begin{quote} +2.4 \hyperref[structure-maps]{Maps} +\end{quote} + +\begin{quote} +2.5 \hyperref[structure-core]{Core} +\end{quote} + +\begin{quote} +2.6 \hyperref[structure-assettypes]{\texttt{Assets} and +\texttt{AssetTypes}} +\end{quote} + +\begin{quote} +2.7 \hyperref[structure-large-sets]{Large Sets} +\end{quote} + +\begin{quote} +2.8 \hyperref[structure-material-library]{Material Library} +\end{quote} + +\#\#\# 2.1 Folder Names + +These are common rules for naming any folder in the content structure. + +\paragraph{\texorpdfstring{2.1.1 Always Use +PascalCase\hyperref[terms-cases]{*}}{2.1.1 Always Use PascalCase*}}\label{always-use-pascalcase} + +PascalCase refers to starting a name with a capital letter and then +instead of using spaces, every following word also starts with a capital +letter. For example, \texttt{DesertEagle}, \texttt{RocketPistol}, and +\texttt{ASeriesOfWords}. + +See \hyperref[terms-cases]{Cases}. + +\paragraph{2.1.2 Never Use Spaces}\label{never-use-spaces} + +Re-enforcing \hyperref[2.1.1]{2.1.1}, never use spaces. Spaces can cause +various engineering tools and batch processes to fail. Ideally, your +project's root also contains no spaces and is located somewhere such as +\texttt{D:\textbackslash{}Project} instead of +\texttt{C:\textbackslash{}Users\textbackslash{}My\ Name\textbackslash{}My\ Documents\textbackslash{}Unreal\ Projects}. + +\paragraph{2.1.3 Never Use Unicode Characters And Other +Symbols}\label{never-use-unicode-characters-and-other-symbols} + +If one of your game characters is named `Zoë', its folder name should be +\texttt{Zoe}. Unicode characters can be worse than +\hyperref[2.1.2]{Spaces} for engineering tool and some parts of UE4 +don't support Unicode characters in paths either. + +Related to this, if your project has +\href{https://answers.unrealengine.com/questions/101207/undefined.html}{unexplained +issues} and your computer's user name has a Unicode character (i.e.~your +name is \texttt{Zoë}), any project located in your +\texttt{My\ Documents} folder will suffer from this issue. Often simply +moving your project to something like \texttt{D:\textbackslash{}Project} +will fix these mysterious issues. + +Using other characters outside \texttt{a-z}, \texttt{A-Z}, and +\texttt{0-9} such as \texttt{@}, \texttt{-}, \texttt{\_}, \texttt{,}, +\texttt{*}, and \texttt{\#} can also lead to unexpected and hard to +track issues on other platforms, source control, and weaker engineering +tools. + +\#\#\# 2.2 Use A Top Level Folder For Project Specific Assets + +All of a project's assets should exist in a folder named after the +project. For example, if your project is named `Generic Shooter', +\emph{all} of it's content should exist in +\texttt{Content/GenericShooter}. + +\begin{quote} +The \texttt{Developers} folder is not for assets that your project +relies on and therefore is not project specific. See +\hyperref[2.3]{Developer Folders} for details about this. +\end{quote} + +There are multiple reasons for this approach. + +\paragraph{2.2.1 No Global Assets}\label{no-global-assets} + +Often in code style guides it is written that you should not pollute the +global namespace and this follows the same principle. When assets are +allowed to exist outside of a project folder, it often becomes much +harder to enforce a strict structure layout as assets not in a folder +encourages the bad behavior of not having to organize assets. + +Every asset should have a purpose, otherwise it does not belong in a +project. If an asset is an experimental test and shouldn't be used by +the project it should be put in a \hyperref[2.3]{\texttt{Developer}} +folder. + +\paragraph{2.2.2 Reduce Migration +Conflicts}\label{reduce-migration-conflicts} + +When working on multiple projects it is common for a team to copy assets +from one project to another if they have made something useful for both. +When this occurs, the easiest way to perform the copy is to use the +Content Browser's Migrate functionality as it will copy over not just +the selected asset but all of its dependencies. + +These dependencies are what can easily get you into trouble. If two +project's assets do not have a top level folder and they happen to have +similarly named or already previously migrated assets, a new migration +can accidentally wipe any changes to the existing assets. + +This is also the primary reason why Epic's Marketplace staff enforces +the same policy for submitted assets. + +After a migration, safe merging of assets can be done using the `Replace +References' tool in the content browser with the added clarity of assets +not belonging to a project's top level folder are clearly pending a +merge. Once assets are merged and fully migrated, there shouldn't be +another top level folder in your Content tree. This method is +\emph{100\%} guaranteed to make any migrations that occur completely +safe. + +\subparagraph{2.2.2e1 Master Material +Example}\label{e1-master-material-example} + +For example, say you created a master material in one project that you +would like to use in another project so you migrated that asset over. If +this asset is not in a top level folder, it may have a name like +\texttt{Content/MaterialLibrary/M\_Master}. If the target project +doesn't have a master material already, this should work without issue. + +As work on one or both projects progress, their respective master +materials may change to be tailored for their specific projects due to +the course of normal development. + +The issue comes when, for example, an artist for one project created a +nice generic modular set of static meshes and someone wants to include +that set of static meshes in the second project. If the artist who +created the assets used material instances based on +\texttt{Content/MaterialLibrary/M\_Master} as they're instructed to, +when a migration is performed there is a great chance of conflict for +the previously migrated \texttt{Content/MaterialLibrary/M\_Master} +asset. + +This issue can be hard to predict and hard to account for. The person +migrating the static meshes may not be the same person who is familiar +with the development of both project's master material, and they may not +be even aware that the static meshes in question rely on material +instances which then rely on the master material. The Migrate tool +requires the entire chain of dependencies to work however, and so it +will be forced to grab \texttt{Content/MaterialLibrary/M\_Master} when +it copies these assets to the other project and it will overwrite the +existing asset. + +It is at this point where if the master materials for both projects are +incompatible in \emph{any way}, you risk breaking possibly the entire +material library for a project as well as any other dependencies that +may have already been migrated, simply because assets were not stored in +a top level folder. The simple migration of static meshes now becomes a +very ugly task. + +\paragraph{2.2.3 Samples, Templates, and Marketplace Content Are +Risk-Free}\label{samples-templates-and-marketplace-content-are-risk-free} + +An extension to \hyperref[2.2.2]{2.2.2}, if a team member decides to add +sample content, template files, or assets they bought from the +marketplace, it is guaranteed, as long your project's top-level folder +is uniquely named,that these new assets will not interfere with your +project. + +You can not trust marketplace content to fully conform to the +\hyperref[2.2]{top level folder rule}. There exists many assets that +have the majority of their content in a top level folder but also have +possibly modified Epic sample content as well as level files polluting +the global \texttt{Content} folder. + +When adhering to \hyperref[2.2]{2.2}, the worst marketplace conflict you +can have is if two marketplace assets both have the same Epic sample +content. If all your assets are in a project specific folder, including +sample content you may have moved into your folder, your project will +never break. + +\paragraph{2.2.4 DLC, Sub-Projects, and Patches Are Easily +Maintained}\label{dlc-sub-projects-and-patches-are-easily-maintained} + +If your project plans to release DLC or has multiple sub-projects +associated with it that may either be migrated out or simply not cooked +in a build, assets relating to these projects should have their own +separate top level content folder. This make cooking DLC separate from +main project content far easier. Sub-projects can also be migrated in +and out with minimal effort. If you need to change a material of an +asset or add some very specific asset override behavior in a patch, you +can easily put these changes in a patch folder and work safely without +the chance of breaking the core project. + +\subsubsection{2.3 Use Developers Folder For Local +Testing}\label{use-developers-folder-for-local-testing} + +During a project's development, it is very common for team members to +have a sort of `sandbox' where they can experiment freely without +risking the core project. Because this work may be ongoing, these team +members may wish to put their assets on a project's source control +server. Not all teams require use of Developer folders, but ones that do +use them often run into a common problem with assets submitted to source +control. + +It is very easy for a team member to accidentally use assets that are +not ready for use, which will cause issues once those assets are +removed. For example, an artist may be iterating on a modular set of +static meshes and still working on getting their sizing and grid +snapping correct. If a world builder sees these assets in the main +project folder, they might use them all over a level not knowing they +could be subject to incredible change and/or removal. This causes +massive amounts of re-working for everyone on the team to resolve. + +If these modular assets were placed in a Developer folder, the world +builder should never have had a reason to use them and the whole issue +would never happen. The Content Browser has specific View Options that +will hide Developer folders (they are hidden by default) making it +impossible to accidentally use Developer assets under normal use. + +Once the assets are ready for use, an artist simply has to move the +assets into the project specific folder and fix up redirectors. This is +essentially `promoting' the assets from experimental to production. + +\subsubsection{\texorpdfstring{2.4 All Map\hyperref[terms-level-map]{*} +Files Belong In A Folder Called +Maps}{2.4 All Map* Files Belong In A Folder Called Maps}}\label{all-map-files-belong-in-a-folder-called-maps} + +Map files are incredibly special and it is common for every project to +have its own map naming system, especially if they work with sub-levels +or streaming levels. No matter what system of map organization is in +place for the specific project, all levels should belong in +\texttt{/Content/Project/Maps}. + +Being able to tell someone to open a specific map without having to +explain where it is is a great time saver and general `quality of life' +improvement. It is common for levels to be within sub-folders of +\texttt{Maps}, such as \texttt{Maps/Campaign1/} or \texttt{Maps/Arenas}, +but the most important thing here is that they all exist within +\texttt{/Content/Project/Maps}. + +This also simplifies the job of cooking for engineers. Wrangling levels +for a build process can be extremely frustrating if they have to dig +through arbitrary folders for them. If a team's maps are all in one +place, it is much harder to accidentally not cook a map in a build. It +also simplifies lighting build scripts as well as QA processes. + +\subsubsection{\texorpdfstring{2.5 Use A \texttt{Core} Folder For +Critical Blueprints And Other +Assets}{2.5 Use A Core Folder For Critical Blueprints And Other Assets}}\label{use-a-core-folder-for-critical-blueprints-and-other-assets} + +Use \texttt{/Content/Project/Core} folder for assets that are absolutely +fundamental to a project's workings. For example, base +\texttt{GameMode}, \texttt{Character}, \texttt{PlayerController}, +\texttt{GameState}, \texttt{PlayerState}, and related Blueprints should +live here. + +This creates a very clear ``don't touch these'' message for other team +members. Non-engineers should have very little reason to enter the +\texttt{Core} folder. Following good code structure style, designers +should be making their gameplay tweaks in child classes that expose +functionality. World builders should be using prefab Blueprints in +designated folders instead of potentially abusing base classes. + +For example, if your project requires pickups that can be placed in a +level, there should exist a base Pickup class in \texttt{Core/Pickups} +that defines base behavior for a pickup. Specific pickups such as a +Health or Ammo should exist in a folder such as +\texttt{/Content/Project/Placeables/Pickups/}. Game designers can define +and tweak pickups in this folder however they please, but they should +not touch \texttt{Core/Pickups} as they may unintentionally break +pickups project-wide. + +\subsubsection{\texorpdfstring{2.6 Do Not Create Folders Called +\texttt{Assets} or +\texttt{AssetTypes}}{2.6 Do Not Create Folders Called Assets or AssetTypes}}\label{do-not-create-folders-called-assets-or-assettypes} + +\paragraph{\texorpdfstring{2.6.1 Creating a folder named \texttt{Assets} +is +redundant.}{2.6.1 Creating a folder named Assets is redundant.}}\label{creating-a-folder-named-assets-is-redundant.} + +All assets are assets. + +\paragraph{\texorpdfstring{2.6.2 Creating a folder named +\texttt{Meshes}, \texttt{Textures}, or \texttt{Materials} is +redundant.}{2.6.2 Creating a folder named Meshes, Textures, or Materials is redundant.}}\label{creating-a-folder-named-meshes-textures-or-materials-is-redundant.} + +All asset names are named with their asset type in mind. These folders +offer only redundant information and the use of these folders can easily +be replaced with the robust and easy to use filtering system the Content +Browser provides. + +Want to view only static mesh in \texttt{Environment/Rocks/}? Simply +turn on the Static Mesh filter. If all assets are named correctly, they +will also be sorted in alphabetical order regardless of prefixes. Want +to view both static meshes and skeletal meshes? Simply turn on both +filters. This eliminates the need to potentially have to +\texttt{Control-Click} select two folders in the Content Browser's tree +view. + +\begin{quote} +This also extends the full path name of an asset for very little +benefit. The \texttt{S\_} prefix for a static mesh is only two +characters, whereas \texttt{Meshes/} is seven characters. +\end{quote} + +Not doing this also prevents the inevitability of someone putting a +static mesh or a texture in a \texttt{Materials} folder. + +\subsubsection{2.7 Very Large Asset Sets Get Their Own Folder +Layout}\label{very-large-asset-sets-get-their-own-folder-layout} + +This can be seen as a pseudo-exception to \hyperref[2.6]{2.6}. + +There are certain asset types that have a huge volume of related files +where each asset has a unique purpose. The two most common are Animation +and Audio assets. If you find yourself having 15+ of these assets that +belong together, they should be together. + +For example, animations that are shared across multiple characters +should lay in \texttt{Characters/Common/Animations} and may have +sub-folders such as \texttt{Locomotion} or \texttt{Cinematic}. + +\begin{quote} +This does not apply to assets like textures and materials. It is common +for a \texttt{Rocks} folder to have a large amount of textures if there +are a large amount of rocks, however these textures are generally only +related to a few specific rocks and should be named appropriately. Even +if these textures are part of a \hyperref[2.8]{Material Library}. +\end{quote} + +\subsubsection{\texorpdfstring{2.8 +\texttt{MaterialLibrary}}{2.8 MaterialLibrary}}\label{materiallibrary} + +If your project makes use of master materials, layered materials, or any +form of reusable materials or textures that do not belong to any subset +of assets, these assets should be located in +\texttt{Content/Project/MaterialLibrary}. + +This way all `global' materials have a place to live and are easily +located. + +\begin{quote} +This also makes it incredibly easy to enforce a `use material instances +only' policy within a project. If all artists and assets should be using +material instances, then the only regular material assets that should +exist are within this folder. You can easily verify this by searching +for base materials in any folder that isn't the +\texttt{MaterialLibrary}. +\end{quote} + +The \texttt{MaterialLibrary} doesn't have to consist of purely +materials. Shared utility textures, material functions, and other things +of this nature should be stored here as well within folders that +designate their intended purpose. For example, generic noise textures +should be located in \texttt{MaterialLibrary/Utility}. + +Any testing or debug materials should be within +\texttt{MaterialLibrary/Debug}. This allows debug materials to be easily +stripped from a project before shipping and makes it incredibly apparent +if production assets are using them if reference errors are shown. + +\subsubsection{2.9 No Empty Folders}\label{no-empty-folders} + +There simply shouldn't be any empty folders. They clutter the content +browser. + +If you find that the content browser has an empty folder you can't +delete, you should perform the following: 1. Be sure you're using source +control. 1. Immediately run Fix Up Redirectors on your project. 1. +Navigate to the folder on-disk and delete the assets inside. 1. Close +the editor. 1. Make sure your source control state is in sync (i.e.~if +using Perforce, run a Reconcile Offline Work on your content directory) +1. Open the editor. Confirm everything still works as expected. If it +doesn't, revert, figure out what went wrong, and try again. 1. Ensure +the folder is now gone. 1. Submit changes to source control. + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{3. Blueprints}\label{blueprints-1} + +This section will focus on Blueprint classes and their internals. When +possible, style rules conform to +\href{https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard}{Epic's +Coding Standard}. + +Remember: Blueprinting badly bears blunders, beware! (Phrase by +\href{http://github.com/KorkuVeren}{KorkuVeren}) + +\subsubsection{Sections}\label{sections-2} + +\begin{quote} +3.1 \hyperref[bp-compiling]{Compiling} +\end{quote} + +\begin{quote} +3.2 \hyperref[bp-vars]{Variables} +\end{quote} + +\begin{quote} +3.3 \hyperref[bp-functions]{Functions} +\end{quote} + +\begin{quote} +3.4 \hyperref[bp-graphs]{Graphs} +\end{quote} + +\subsubsection{3.1 Compiling}\label{compiling} + +All blueprints should compile with zero warnings and zero errors. You +should fix blueprint warnings and errors immediately as they can quickly +cascade into very scary unexpected behavior. + +Do \emph{not} submit broken blueprints to source control. If you must +store them on source control, shelve them instead. + +Broken blueprints can cause problems that manifest in other ways, such +as broken references, unexpected behavior, cooking failures, and +frequent unneeded recompilation. A broken blueprint has the power to +break your entire game. + +\subsubsection{3.2 Variables}\label{variables} + +The words \texttt{variable} and \texttt{property} may be used +interchangeably. + +\paragraph{Sections}\label{sections-3} + +\begin{quote} +3.2.1 \hyperref[bp-vars]{Naming} +\end{quote} + +\begin{quote} +3.2.2 \hyperref[bp-vars-editable]{Editable} +\end{quote} + +\begin{quote} +3.2.3 \hyperref[bp-vars-categories]{Categories} +\end{quote} + +\begin{quote} +3.2.4 \hyperref[bp-vars-access]{Access} +\end{quote} + +\begin{quote} +3.2.5 \hyperref[bp-vars-advanced]{Advanced} +\end{quote} + +\begin{quote} +3.2.6 \hyperref[bp-vars-transient]{Transient} +\end{quote} + +\begin{quote} +3.2.7 \hyperref[bp-vars-config]{Config} +\end{quote} + +\paragraph{3.2.1 Naming}\label{naming} + +\subparagraph{3.2.1.1 Nouns}\label{nouns} + +All non-boolean variable names must be clear, unambiguous, and +descriptive nouns. + +\subparagraph{3.2.1.2 PascalCase}\label{pascalcase-1} + +All non-boolean variables should be in the form of +\hyperref[terms-cases]{PascalCase}. + +3.2.1.2e Examples: + +\begin{itemize} +\tightlist +\item + \texttt{Score} +\item + \texttt{Kills} +\item + \texttt{TargetPlayer} +\item + \texttt{Range} +\item + \texttt{CrosshairColor} +\item + \texttt{AbilityID} +\end{itemize} + +\subparagraph{\texorpdfstring{3.2.1.3 Boolean \texttt{b} +Prefix}{3.2.1.3 Boolean b Prefix}}\label{boolean-b-prefix} + +All booleans should be named in PascalCase but prefixed with a lowercase +\texttt{b}. + +Example: Use \texttt{bDead} and \texttt{bEvil}, \textbf{not} +\texttt{Dead} and \texttt{Evil}. + +UE4 Blueprint editors know not to include the \texttt{b} in +user-friendly displays of the variable. + +\subparagraph{3.2.1.4 Boolean Names}\label{boolean-names} + +3.2.1.4.1 General And Independent State Information + +All booleans should be named as descriptive adjectives when possible if +representing general information. Do not include words that phrase the +variable as a question, such as \texttt{Is}. This is reserved for +functions. + +Example: Use \texttt{bDead} and \texttt{bHostile} \textbf{not} +\texttt{bIsDead} and \texttt{bIsHostile}. + +Try to not use verbs such as \texttt{bRunning}. Verbs tend to lead to +complex states. + +3.2.1.4.2 Complex States + +Do not to use booleans to represent complex and/or dependent states. +This makes state adding and removing complex and no longer easily +readable. Use an enumeration instead. + +Example: When defining a weapon, do \textbf{not} use \texttt{bReloading} +and \texttt{bEquipping} if a weapon can't be both reloading and +equipping. Define an enumeration named \texttt{EWeaponState} and use a +variable with this type named \texttt{WeaponState} instead. This makes +it far easier to add new states to weapons. + +Example: Do \textbf{not} use \texttt{bRunning} if you also need +\texttt{bWalking} or \texttt{bSprinting}. This should be defined as an +enumeration with clearly defined state names. + +\subparagraph{3.2.1.5 Considered Context}\label{considered-context} + +All variable names must not be redundant with their context as all +variable references in Blueprint will always have context. + +3.2.1.5e Examples: + +Consider a Blueprint called \texttt{BP\_PlayerCharacter}. + +\textbf{Bad} + +\begin{itemize} +\tightlist +\item + \texttt{PlayerScore} +\item + \texttt{PlayerKills} +\item + \texttt{MyTargetPlayer} +\item + \texttt{MyCharacterName} +\item + \texttt{CharacterSkills} +\item + \texttt{ChosenCharacterSkin} +\end{itemize} + +All of these variables are named redundantly. It is implied that the +variable is representative of the \texttt{BP\_PlayerCharacter} it +belongs to because it is \texttt{BP\_PlayerCharacter} that is defining +these variables. + +\textbf{Good} + +\begin{itemize} +\tightlist +\item + \texttt{Score} +\item + \texttt{Kills} +\item + \texttt{TargetPlayer} +\item + \texttt{Name} +\item + \texttt{Skills} +\item + \texttt{Skin} +\end{itemize} + +\subparagraph{\texorpdfstring{3.2.1.6 Do \emph{Not} Include Atomic Type +Names}{3.2.1.6 Do Not Include Atomic Type Names}}\label{do-not-include-atomic-type-names} + +Atomic or primitive variables are variables that represent data in their +simplest form, such as booleans, integers, floats, and enumerations. + +Strings and vectors are considered atomic in terms of style when working +with Blueprints, however they are technically not atomic. + +\begin{quote} +While vectors consist of three floats, vectors are often able to be +manipulated as a whole, same with rotators. +\end{quote} + +\begin{quote} +Do \emph{not} consider Text variables as atomic, they are secretly +hiding localization functionality. The atomic type of a string of +characters is \texttt{String}, not \texttt{Text}. +\end{quote} + +Atomic variables should not have their type name in their name. + +Example: Use \texttt{Score}, \texttt{Kills}, and \texttt{Description} +\textbf{not} \texttt{ScoreFloat}, \texttt{FloatKills}, +\texttt{DescriptionString}. + +The only exception to this rule is when a variable represents `a number +of' something to be counted \emph{and} when using a name without a +variable type is not easy to read. + +Example: A fence generator needs to generate X number of posts. Store X +in \texttt{NumPosts} or \texttt{PostsCount} instead of \texttt{Posts} as +\texttt{Posts} may potentially read as an Array of a variable type named +\texttt{Post}. + +\subparagraph{3.2.1.7 Do Include Non-Atomic Type +Names}\label{do-include-non-atomic-type-names} + +Non-atomic or complex variables are variables that represent data as a +collection of atomic variables. Structs, Classes, Interfaces, and +primitives with hidden behavior such as \texttt{Text} and \texttt{Name} +all qualify under this rule. + +\begin{quote} +While an Array of an atomic variable type is a list of variables, Arrays +do not change the `atomicness' of a variable type. +\end{quote} + +These variables should include their type name while still considering +their context. + +If a class owns an instance of a complex variable, i.e.~if a +\texttt{BP\_PlayerCharacter} owns a \texttt{BP\_Hat}, it should be +stored as the variable type as without any name modifications. + +Example: Use \texttt{Hat}, \texttt{Flag}, and \texttt{Ability} +\textbf{not} \texttt{MyHat}, \texttt{MyFlag}, and +\texttt{PlayerAbility}. + +If a class does not own the value a complex variable represents, you +should use a noun along with the variable type. + +Example: If a \texttt{BP\_Turret} has the ability to target a +\texttt{BP\_PlayerCharacter}, it should store its target as +\texttt{TargetPlayer} as when in the context of \texttt{BP\_Turret} it +should be clear that it is a reference to another complex variable type +that it does not own. + +\subparagraph{3.2.1.8 Arrays}\label{arrays} + +Arrays follow the same naming rules as above, but should be named as a +plural noun. + +Example: Use \texttt{Targets}, \texttt{Hats}, and \texttt{EnemyPlayers}, +\textbf{not} \texttt{TargetList}, \texttt{HatArray}, +\texttt{EnemyPlayerArray}. + +\paragraph{3.2.2 Editable Variables}\label{editable-variables} + +All variables that are safe to change the value of in order to configure +behavior of a blueprint should be marked as \texttt{Editable}. + +Conversely, all variables that are not safe to change or should not be +exposed to designers should \emph{not} be marked as editable, unless for +engineering reasons the variable must be marked as +\texttt{Expose\ On\ Spawn}. + +Do not arbitrarily mark variables as \texttt{Editable}. + +\subparagraph{3.2.2.1 Tooltips}\label{tooltips} + +All \texttt{Editable} variables, including those marked editable just so +they can be marked as \texttt{Expose\ On\ Spawn}, should have a +description in their \texttt{Tooltip} fields that explains how changing +this value affects the behavior of the blueprint. + +\subparagraph{3.2.2.2 Slider And Value +Ranges}\label{slider-and-value-ranges} + +All \texttt{Editable} variables should make use of slider and value +ranges if there is ever a value that a variable should \emph{not} be set +to. + +Example: A blueprint that generates fence posts might have an editable +variable named \texttt{PostsCount} and a value of -1 would not make any +sense. Use the range fields to mark 0 as a minimum. + +If an editable variable is used in a Construction Script, it should have +a reasonable Slider Range defined so that someone can not accidentally +assign it a large value that could crash the editor. + +A Value Range only needs to be defined if the bounds of a value are +known. While a Slider Range prevents accidental large number inputs, an +undefined Value Range allows a user to specify a value outside the +Slider Range that may be considered `dangerous' but still valid. + +\paragraph{3.2.3 Categories}\label{categories} + +If a class has only a small number of variables, categories are not +required. + +If a class has a moderate amount of variables (5-10), all +\texttt{Editable} variables should have a non-default category assigned. +A common category is \texttt{Config}. + +If a class has a large amount of variables, all \texttt{Editable} +variables should be categorized into sub-categories using the category +\texttt{Config} as the base category. Non-editable variables should be +categorized into descriptive categories describing their usage. + +\begin{quote} +You can define sub-categories by using the pipe character +\texttt{\textbar{}}, i.e.~\texttt{Config\ \textbar{}\ Animations}. +\end{quote} + +Example: A weapon class set of variables might be organized as: + +\begin{verbatim} +|-- Config +| |-- Animations +| |-- Effects +| |-- Audio +| |-- Recoil +| |-- Timings +|-- Animations +|-- State +|-- Visuals +\end{verbatim} + +\paragraph{3.2.4 Variable Access Level}\label{variable-access-level} + +In C++, variables have a concept of access level. Public means any code +outside the class can access the variable. Protected means only the +class and any child classes can access this variable internally. Private +means only this class and no child classes can access this variable. + +Blueprints do not have a defined concept of protected access currently. + +Treat \texttt{Editable} variables as public variables. Treat +non-editable variables as protected variables. + +\subparagraph{3.2.4.1 Private Variables}\label{private-variables} + +Unless it is known that a variable should only be accessed within the +class it is defined and never a child class, do not mark variables as +private. Until variables are able to be marked \texttt{protected}, +reserve private for when you absolutely know you want to restrict child +class usage. + +\paragraph{3.2.5 Advanced Display}\label{advanced-display} + +If a variable should be editable but often untouched, mark it as +\texttt{Advanced\ Display}. This makes the variable hidden unless the +advanced display arrow is clicked. + +To find the \texttt{Advanced\ Display} option, it is listed as an +advanced displayed variable in the variable details list. + +\paragraph{3.2.6 Transient Variables}\label{transient-variables} + +Transient variables are variables that do not need to have their value +saved and loaded and have an initial value of zero or null. This is +useful for references to other objects and actors who's value isn't +known until run-time. This prevents the editor from ever saving a +reference to it, and speeds up saving and loading of the blueprint +class. + +Because of this, all transient variables should always be initialized as +zero or null. To do otherwise would result in hard to debug errors. + +\paragraph{3.2.8 Config Variables}\label{config-variables} + +Do not use the \texttt{Config\ Variable} flag. This makes it harder for +designers to control blueprint behavior. Config variables should only be +used in C++ for rarely changed variables. Think of them as +\texttt{Advanced\ Advanced\ Display} variables. + +\subsubsection{3.3 Functions, Events, and Event +Dispatchers}\label{functions-events-and-event-dispatchers} + +This section describes how you should author functions, events, and +event dispatchers. Everything that applies to functions also applies to +events, unless otherwise noted. + +\paragraph{3.3.1 Function Naming}\label{function-naming} + +The naming of functions, events, and event dispatchers is critically +important. Based on the name alone, certain assumptions can be made +about functions. For example: + +\begin{itemize} +\tightlist +\item + Is it a pure function? +\item + Is it fetching state information? +\item + Is it a handler? +\item + Is it an RPC? +\item + What is its purpose? +\end{itemize} + +These questions and more can all be answered when functions are named +appropriately. + +\paragraph{3.3.1.1 All Functions Should Be +Verbs}\label{all-functions-should-be-verbs} + +All functions and events perform some form of action, whether its +getting info, calculating data, or causing something to explode. +Therefore, all functions should all start with verbs. They should be +worded in the present tense whenever possible. They should also have +some context as to what they are doing. + +\texttt{OnRep} functions, event handlers, and event dispatchers are an +exception to this rule. + +Good examples: + +\begin{itemize} +\tightlist +\item + \texttt{Fire} - Good example if in a Character / Weapon class, as it + has context. Bad if in a Barrel / Grass / any ambiguous class. +\item + \texttt{Jump} - Good example if in a Character class, otherwise, needs + context. +\item + \texttt{Explode} +\item + \texttt{ReceiveMessage} +\item + \texttt{SortPlayerArray} +\item + \texttt{GetArmOffset} +\item + \texttt{GetCoordinates} +\item + \texttt{UpdateTransforms} +\item + \texttt{EnableBigHeadMode} +\item + \texttt{IsEnemy} - + \href{http://writingexplained.org/is-is-a-verb}{``Is'' is a verb.} +\end{itemize} + +Bad examples: + +\begin{itemize} +\tightlist +\item + \texttt{Dead} - Is Dead? Will deaden? +\item + \texttt{Rock} +\item + \texttt{ProcessData} - Ambiguous, these words mean nothing. +\item + \texttt{PlayerState} - Nouns are ambiguous. +\item + \texttt{Color} - Verb with no context, or ambiguous noun. +\end{itemize} + +\paragraph{\texorpdfstring{3.3.1.2 Property RepNotify Functions Always +\texttt{OnRep\_Variable}}{3.3.1.2 Property RepNotify Functions Always OnRep\_Variable}}\label{property-repnotify-functions-always-onrep_variable} + +All functions for replicated with notification variables should have the +form \texttt{OnRep\_Variable}. This is forced by the Blueprint editor. +If you are writing a C++ \texttt{OnRep} function however, it should also +follow this convention when exposing it to Blueprints. + +\paragraph{3.3.1.3 Info Functions Returning Bool Should Ask +Questions}\label{info-functions-returning-bool-should-ask-questions} + +When writing a function that does not change the state of or modify any +object and is purely for getting information, state, or computing a +yes/no value, it should ask a question. This should also follow +\hyperref[bp-funcs-naming-verbs]{the verb rule}. + +This is extremely important as if a question is not asked, it may be +assumed that the function performs an action and is returning whether +that action succeeded. + +Good examples: + +\begin{itemize} +\tightlist +\item + \texttt{IsDead} +\item + \texttt{IsOnFire} +\item + \texttt{IsAlive} +\item + \texttt{IsSpeaking} +\item + \texttt{IsHavingAnExistentialCrisis} +\item + \texttt{IsVisible} +\item + \texttt{HasWeapon} - + \href{http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html}{``Has'' + is a verb.} +\item + \texttt{WasCharging} - + \href{http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html}{``Was'' + is past-tense of ``be''.} Use ``was'' when referring to `previous + frame' or `previous state'. +\item + \texttt{CanReload} - + \href{http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html}{``Can'' + is a verb.} +\end{itemize} + +Bad examples: + +\begin{itemize} +\tightlist +\item + \texttt{Fire} - Is on fire? Will fire? Do fire? +\item + \texttt{OnFire} - Can be confused with event dispatcher for firing. +\item + \texttt{Dead} - Is dead? Will deaden? +\item + \texttt{Visibility} - Is visible? Set visibility? A description of + flying conditions? +\end{itemize} + +\paragraph{\texorpdfstring{3.3.1.4 Event Handlers and Dispatchers Should +Start With +\texttt{On}}{3.3.1.4 Event Handlers and Dispatchers Should Start With On}}\label{event-handlers-and-dispatchers-should-start-with-on} + +Any function that handles an event or dispatches an event should start +with \texttt{On} and continue to follow +\hyperref[bp-funcs-naming-verbs]{the verb rule}. The verb may move to +the end however if past-tense reads better. + +\href{http://dictionary.cambridge.org/us/grammar/british-grammar/about-words-clauses-and-sentences/collocation}{Collocations} +of the word \texttt{On} are exempt from following the verb rule. + +\texttt{Handle} is not allowed. It is `Unreal' to use \texttt{On} +instead of \texttt{Handle}, while other frameworks may prefer to use +\texttt{Handle} instead of \texttt{On}. + +Good examples: + +\begin{itemize} +\tightlist +\item + \texttt{OnDeath} - Common collocation in games +\item + \texttt{OnPickup} +\item + \texttt{OnReceiveMessage} +\item + \texttt{OnMessageRecieved} +\item + \texttt{OnTargetChanged} +\item + \texttt{OnClick} +\item + \texttt{OnLeave} +\end{itemize} + +Bad examples: + +\begin{itemize} +\tightlist +\item + \texttt{OnData} +\item + \texttt{OnTarget} +\item + \texttt{HandleMessage} +\item + \texttt{HandleDeath} +\end{itemize} + +\paragraph{3.3.1.5 Remote Procedure Calls Should Be Prefixed With +Target}\label{remote-procedure-calls-should-be-prefixed-with-target} + +Any time an RPC is created, it should be prefixed with either +\texttt{Server}, \texttt{Client}, or \texttt{Multicast}. No exceptions. + +After the prefix, follow all other rules regarding function naming. + +Good examples: + +\begin{itemize} +\tightlist +\item + \texttt{ServerFireWeapon} +\item + \texttt{ClientNotifyDeath} +\item + \texttt{MulticastSpawnTracerEffect} +\end{itemize} + +Bad examples: + +\begin{itemize} +\tightlist +\item + \texttt{FireWeapon} - Does not indicate its an RPC of some kind. +\item + \texttt{ServerClientBroadcast} - Confusing. +\item + \texttt{AllNotifyDeath} - Use \texttt{Multicast}, never \texttt{All}. +\item + \texttt{ClientWeapon} - No verb, ambiguous. +\end{itemize} + +\paragraph{3.3.2 All Functions Must Have Return +Nodes}\label{all-functions-must-have-return-nodes} + +All functions must have return nodes, no exceptions. + +Return nodes explicitly note that a function has finished its execution. +In a world where blueprints can be filled with \texttt{Sequence}, +\texttt{ForLoopWithBreak}, and backwards reroute nodes, explicit +execution flow is important for readability, maintenance, and easier +debugging. + +The Blueprint compiler is able to follow the flow of execution and will +warn you if there is a branch of your code with an unhandled return or +bad flow if you use return nodes. + +In situations like where a programmer may add a pin to a Sequence node +or add logic after a for loop completes but the loop iteration might +return early, this can often result in an accidental error in code flow. +The warnings the Blueprint compiler will alert everyone of these issues +immediately. + +\paragraph{3.3.3 No Function Should Have More Than 50 +Nodes}\label{no-function-should-have-more-than-50-nodes} + +Simply, no function should have more than 50 nodes. Any function this +big should be broken down into smaller functions for readability and +ease of maintenance. + +The following nodes are not counted as they are deemed to not increase +function complexity: + +\begin{itemize} +\tightlist +\item + Comment +\item + Route +\item + Cast +\item + Getting a Variable +\item + Breaking a Struct +\item + Function Entry +\item + Self +\end{itemize} + +\paragraph{3.3.4 All Public Functions Should Have A +Description}\label{all-public-functions-should-have-a-description} + +This rule applies more to public facing or marketplace blueprints, so +that others can more easily navigate and consume your blueprint API. + +Simply, any function that has an access specificer of Public should have +its description filled out. + +\paragraph{\texorpdfstring{3.3.5 All Custom Static Plugin +\texttt{BlueprintCallable} Functions Must Be Categorized By Plugin +Name}{3.3.5 All Custom Static Plugin BlueprintCallable Functions Must Be Categorized By Plugin Name}}\label{all-custom-static-plugin-blueprintcallable-functions-must-be-categorized-by-plugin-name} + +If your project includes a plugin that defines \texttt{static} +\texttt{BlueprintCallable} functions, they should have their category +set to the plugin's name or a subset category of the plugin's name. + +For example, \texttt{Zed\ Camera\ Interface} or +\texttt{Zed\ Camera\ Interface\ \textbar{}\ Image\ Capturing}. + +\subsubsection{3.4 Blueprint Graphs}\label{blueprint-graphs} + +This section covers things that apply to all Blueprint graphs. + +\paragraph{3.4.1 No Spaghetti}\label{no-spaghetti} + +Wires should have clear beginnings and ends. You should never have to +mentally untangle wires to make sense of a graph. Many of the following +sections are dedicated to reducing spaghetti. + +\paragraph{3.4.2 Align Wires Not Nodes}\label{align-wires-not-nodes} + +Always align wires, not nodes. You can't always control the size and pin +location on a node, but you can always control the location of a node +and thus control the wires. Straight wires provide clear linear flow. +Wiggly wires wear wits wickedly. You can straighten wires by using the +Straighten Connections command with BP nodes selected. Hotkey: Q + +Good example: The tops of the nodes are staggered to keep a perfectly +straight white exec line. +\pandocbounded{\includegraphics[keepaspectratio]{styleguide_files/mediabag/bp-graphs-align-wire.png}} + +Bad Example: The tops of the nodes are aligned creating a wiggly white +exec line. +\pandocbounded{\includegraphics[keepaspectratio]{styleguide_files/mediabag/bp-graphs-align-wire1.png}} + +Acceptable Example: Certain nodes might not cooperate no matter how you +use the alignment tools. In this situation, try to minimize the wiggle +by bringing the node in closer. +\pandocbounded{\includegraphics[keepaspectratio]{styleguide_files/mediabag/bp-graphs-align-wire12.png}} + +\paragraph{3.4.3 White Exec Lines Are Top +Priority}\label{white-exec-lines-are-top-priority} + +If you ever have to decide between straightening a linear white exec +line or straightening data lines of some kind, always straighten the +white exec line. + +\paragraph{3.4.4 Graphs Should Be Reasonably +Commented}\label{graphs-should-be-reasonably-commented} + +Blocks of nodes should be wrapped in comments that describe their +higher-level behavior. While every function should be well named so that +each individual node is easily readable and understandable, groups of +nodes contributing to a purpose should have their purpose described in a +comment block. If a function does not have many blocks of nodes and its +clear that the nodes are serving a direct purpose in the function's +goal, then they do not need to be commented as the function name and +description should suffice. + +\paragraph{3.4.5 Graphs Should Handle Casting Errors Where +Appropriate}\label{graphs-should-handle-casting-errors-where-appropriate} + +If a function or event assumes that a cast always succeeds, it should +appropriately report a failure in logic if the cast fails. This lets +others know why something that is `supposed to work' doesn't. A function +should also attempt a graceful recover after a failed cast if it's known +that the reference being casted could ever fail to be casted. + +This does not mean every cast node should have its failure handled. In +many cases, especially events regarding things like collisions, it is +expected that execution flow terminates on a failed cast quietly. + +\paragraph{3.4.6 Graphs Should Not Have Any Dangling / Loose / Dead +Nodes}\label{graphs-should-not-have-any-dangling-loose-dead-nodes} + +All nodes in all blueprint graphs must have a purpose. You should not +leave dangling blueprint nodes around that have no purpose or are not +executed. + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{4. Static Meshes}\label{static-meshes} + +This section will focus on Static Mesh assets and their internals. + +\subsubsection{Sections}\label{sections-4} + +\begin{quote} +4.1 \hyperref[s-uvs]{UVs} +\end{quote} + +\begin{quote} +4.2 \hyperref[s-lods]{LODs} +\end{quote} + +\begin{quote} +4.3 \hyperref[s-modular-snapping]{Modular Socketless Snapping} +\end{quote} + +\begin{quote} +4.4 \hyperref[s-collision]{Must Have Collision} +\end{quote} + +\begin{quote} +4.5 \hyperref[s-scaled]{Correct Scale} +\end{quote} + +\subsubsection{4.1 Static Mesh UVs}\label{static-mesh-uvs} + +If Linter is reporting bad UVs and you can't seem to track it down, open +the resulting \texttt{.log} file in your project's \texttt{Saved/Logs} +folder for exact details as to why it's failing. I am hoping to include +these messages in the Lint report in the future. + +\paragraph{4.1.1 All Meshes Must Have +UVs}\label{all-meshes-must-have-uvs} + +Pretty simple. All meshes, regardless how they are to be used, should +not be missing UVs. + +\paragraph{4.1.2 All Meshes Must Not Have Overlapping UVs for +Lightmaps}\label{all-meshes-must-not-have-overlapping-uvs-for-lightmaps} + +Pretty simple. All meshes, regardless how they are to be used, should +have valid non-overlapping UVs. + +\subsubsection{4.2 LODs Should Be Set Up +Correctly}\label{lods-should-be-set-up-correctly} + +This is a subjective check on a per-project basis, but as a general rule +any mesh that can be seen at varying distances should have proper LODs. + +\subsubsection{4.3 Modular Socketless Assets Should Snap To The Grid +Cleanly}\label{modular-socketless-assets-should-snap-to-the-grid-cleanly} + +This is a subjective check on a per-asset basis, however any modular +socketless assets should snap together cleanly based on the project's +grid settings. + +It is up to the project whether to snap based on a power of 2 grid or on +a base 10 grid. However if you are authoring modular socketless assets +for the marketplace, Epic's requirement is that they snap cleanly when +the grid is set to 10 units or bigger. + +\subsubsection{4.4 All Meshes Must Have +Collision}\label{all-meshes-must-have-collision} + +Regardless of whether an asset is going to be used for collision in a +level, all meshes should have proper collision defined. This helps the +engine with things such as bounds calculations, occlusion, and lighting. +Collision should also be well-formed to the asset. + +\subsubsection{4.5 All Meshes Should Be Scaled +Correctly}\label{all-meshes-should-be-scaled-correctly} + +This is a subjective check on a per-project basis, however all assets +should be scaled correctly to their project. Level designers or +blueprint authors should not have to tweak the scale of meshes to get +them to confirm in the editor. Scaling meshes in the engine should be +treated as a scale override, not a scale correction. + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{5. Niagara}\label{niagara} + +This section will focus on Niagara assets and their internals. + +\subsubsection{Sections}\label{sections-5} + +\begin{quote} +5.1 \hyperref[ng-rules]{Naming Rules} +\end{quote} + +\subsubsection{5.1 No Spaces, Ever}\label{no-spaces-ever} + +As mentioned in \hyperref[00]{00.1 Forbidden Identifiers}, spaces and +all white space characters are forbidden in identifiers. This is +especially true for Niagara systems as it makes working with things +significantly harder if not impossible when working with HLSL or other +means of scripting within Niagara and trying to reference an identifier. + +(Original Contribution by +\href{https://github.com/Allar/ue5-style-guide/issues/58}{@dunenkoff\marginpar{\begin{footnotesize}{?quarto-cite:dunenkoff}\vspace{2mm}\par\end{footnotesize}}}) + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{6. Levels / Maps}\label{levels-maps} + +\hyperref[terms-level-map]{See Terminology Note} regarding ``levels'' vs +``maps''. + +This section will focus on Level assets and their internals. + +\subsubsection{Sections}\label{sections-6} + +\begin{quote} +6.1 \hyperref[levels-no-errors-or-warnings]{No Errors Or Warnings} +\end{quote} + +\begin{quote} +6.2 \hyperref[levels-lighting-should-be-built]{Lighting Should Be Built} +\end{quote} + +\begin{quote} +6.3 \hyperref[evels-no-visible-z-fighting]{No Player Visible Z Fighting} +\end{quote} + +\begin{quote} +6.4 \hyperref[evels-levels-mp-rules]{Marketplace Specific Rules} +\end{quote} + +\subsubsection{6.1 No Errors Or Warnings}\label{no-errors-or-warnings} + +All levels should load with zero errors or warnings. If a level loads +with any errors or warnings, they should be fixed immediately to prevent +cascading issues. + +You can run a map check on an open level in the editor by using the +console command ``map check''. + +Please note: Linter is even more strict on this than the editor is +currently, and will catch load errors that the editor will resolve on +its own. + +\subsubsection{6.2 Lighting Should Be +Built}\label{lighting-should-be-built} + +It is normal during development for levels to occasionally not have +lighting built. When doing a test/internal/shipping build or any build +that is to be distributed however, lighting should always be built. + +\subsubsection{6.3 No Player Visible Z +Fighting}\label{no-player-visible-z-fighting} + +Levels should not have any +\href{https://en.wikipedia.org/wiki/Z-fighting}{z-fighting} in all areas +visible to the player. + +\subsubsection{6.4 Marketplace Specific +Rules}\label{marketplace-specific-rules} + +If a project is to be sold on the UE4 Marketplace, it must follow these +rules. + +\subsubsection{6.4.1 Overview Level}\label{overview-level} + +If your project contains assets that should be visualized or demoed, you +must have a map within your project that contains the name ``Overview''. + +This overview map, if it is visualizing assets, should be set up +according to +\href{http://help.epicgames.com/customer/en/portal/articles/2592186-marketplace-submission-guidelines-preparing-your-assets\#Required\%20Levels\%20and\%20Maps}{Epic's +guidelines}. + +For example, \texttt{InteractionComponent\_Overview}. + +\subsubsection{6.4.2 Demo Level}\label{demo-level} + +If your project contains assets that should be demoed or come with some +sort of tutorial, you must have a map within your project that contains +the name ``Demo''. This level should also contain documentation within +it in some form that illustrates how to use your project. See Epic's +Content Examples project for good examples on how to do this. + +If your project is a gameplay mechanic or other form of system as +opposed to an art pack, this can be the same as your ``Overview'' map. + +For example, \texttt{InteractionComponent\_Overview\_Demo}, +\texttt{ExplosionKit\_Demo}. + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + +\subsection{7. Textures}\label{textures-1} + +This section will focus on Texture assets and their internals. + +\subsubsection{Sections}\label{sections-7} + +\begin{quote} +7.1 \hyperref[textures-dimension]{Dimensions Are Powers of 2} +\end{quote} + +\begin{quote} +7.2 \hyperref[textures-dimension]{Texture Density Should Be Uniform} +\end{quote} + +\begin{quote} +7.3 \hyperref[textures-max-size]{Textures Should Be No Bigger than 8192} +\end{quote} + +\begin{quote} +7.4 \hyperref[textures-textures-group]{Correct Texture Groups} +\end{quote} + +\subsubsection{7.1 Dimensions Are Powers of +2}\label{dimensions-are-powers-of-2} + +All textures, except for UI textures, must have its dimensions in +multiples of powers of 2. Textures do not have to be square. + +For example, \texttt{128x512}, \texttt{1024x1024}, \texttt{2048x1024}, +\texttt{1024x2048}, \texttt{1x512}. + +\subsubsection{7.2 Texture Density Should Be +Uniform}\label{texture-density-should-be-uniform} + +All textures should be of a size appropriate for their standard use +case. Appropriate texture density varies from project to project, but +all textures within that project should have a consistent density. + +For example, if a project's texture density is 8 pixel per 1 unit, a +texture that is meant to be applied to a 100x100 unit cube should be +1024x1024, as that is the closest power of 2 that matches the project's +texture density. + +\subsubsection{7.3 Textures Should Be No Bigger than +8192}\label{textures-should-be-no-bigger-than-8192} + +No texture should have a dimension that exceeds 8192 in size, unless you +have a very explicit reason to do so. Often, using a texture this big is +simply just a waste of resources. + +\subsubsection{7.4 Textures Should Be Grouped +Correctly}\label{textures-should-be-grouped-correctly} + +Every texture has a Texture Group property used for LODing, and this +should be set correctly based on its use. For example, all UI textures +should belong in the UI texture group. + +\textbf{\hyperref[table-of-contents]{⬆ Back to Top}} + + + + +\end{document} diff --git a/sites/styleguide_files/mediabag/bp-graphs-align-wire.png b/sites/styleguide_files/mediabag/bp-graphs-align-wire.png new file mode 100644 index 0000000..b9f2edd --- /dev/null +++ b/sites/styleguide_files/mediabag/bp-graphs-align-wire.png @@ -0,0 +1,1817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page not found · GitHub · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ Skip to content + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + +
+
+ +
+
+ 404 “This is not the web page you are looking for” + + + + + + + + + + + + +
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/sites/styleguide_files/mediabag/bp-graphs-align-wire1.png b/sites/styleguide_files/mediabag/bp-graphs-align-wire1.png new file mode 100644 index 0000000..385e747 --- /dev/null +++ b/sites/styleguide_files/mediabag/bp-graphs-align-wire1.png @@ -0,0 +1,1817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page not found · GitHub · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ Skip to content + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + +
+
+ +
+
+ 404 “This is not the web page you are looking for” + + + + + + + + + + + + +
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/sites/styleguide_files/mediabag/bp-graphs-align-wire12.png b/sites/styleguide_files/mediabag/bp-graphs-align-wire12.png new file mode 100644 index 0000000..fa792b8 --- /dev/null +++ b/sites/styleguide_files/mediabag/bp-graphs-align-wire12.png @@ -0,0 +1,1817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page not found · GitHub · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ Skip to content + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + +
+
+ +
+
+ 404 “This is not the web page you are looking for” + + + + + + + + + + + + +
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/sites/webservices.qmd b/sites/webservices.qmd new file mode 100644 index 0000000..e04cb53 --- /dev/null +++ b/sites/webservices.qmd @@ -0,0 +1,333 @@ +--- +title: "Websevices" +--- +# Forgejo + +Forgejo is an open source source control system. As game development not only needs to track text files but large binaries (Images, Videos, Audio etc.), traditional providers like GitHub or GitLab might not scale or become quite pricey. This is why a self-hosted solution was set up. + +The Forgejo instance is currently hosted on Hetzner Cloud cpx11. For storage, a 1tb Hetzner Storage Box is attached via CIFS. The Forgejo instance can be accessed on [https://code.virtuos.world](https://code.virtuos.world). + +## Installation on Ubuntu Server 22.04 + +- On a new server, add a new user that is not root: + +```bash +adduser newusername +usermod -aG sudo newusername +sudo -i -u git newusername +``` + +- Create git user account and add it to the docker usergroup, then switch to the new user. + +```bash +sudo adduser --system --shell /bin/bash -gecos 'Git Version Control' --group --disabled-password --home /home/git/ git +sudo usermod -aG docker git +``` + +- Automount the storage box by editing `/etc/fstab`. Important: Use the UID and GID of the newly created git user! You can get them by typing `id git`. + +```bash +sudo nano /etc/fstab +``` + +- Add this line + +``` +//.your-storagebox.de/backup /mnt/ cifs iocharset=utf8,rw,credentials=/etc/backup-credentials.txt,uid=,gid=,file_mode=0660,dir_mode=0770 0 0 +``` + +Create the credentials file… + +```bash +sudo nano /etc/backup-credentials.txt +``` + +…and fill it with your username and password. + +``` +username=uXXXXXX +password=yourpassword +``` + +- Install `cifs-utils` + +```bash +apt install cifs-utils +``` + +- Mounting might result in an error regarding the iocharset, to fix that do: + +```bash +apt install linux-generic +apt install linux-modules-extra-$(uname -r) +reboot +``` + +- Mount the storage + +```bash +sudo mount -a +``` + +- Install docker-compose + +```bash +sudo apt install docker-compose +``` + +- Create docker directory + +```bash +sudo mkdir ~/forgejo +``` + +- Create docker-compose file + +```bash +sudo nano docker-compose.yml +``` + +- Paste the following content. This assumes your UID is 115 and your GID is 120. Use `id -u ` to find your values. It also maps the repository to use the storage box. + +> Edit: I removed `- /mnt/source/git/repositories:/data/git/repositories` as it's slow and hooks won't work on the Storage Box! + +```yaml +version: '3' + +networks: + forgejo: + external: false + +services: + server: + image: codeberg.org/forgejo/forgejo:1.20 + container_name: forgejo + environment: + - USER_UID=115 + - USER_GID=120 + restart: always + networks: + - forgejo + volumes: + - ./forgejo:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + - /mnt/source/git/lfs:/data/lfs + + ports: + - '3000:3000' + - '222:22' +``` + +For some reason in my case, the app.ini pointed to `/data/git/lfs` instead of `data/lfs`. Fixing this resulted in actually using `/mnt/source/git/lfs` on the host. + +- Install nginx + +```bash +sudo apt install nginx +``` + +- Setup firewall + +```bash +sudo ufw allow OpenSSH +sudo ufw allow "Nginx Full" +sudo ufw enable +``` + +- Open nginx config + +```bash +sudo nano /etc/nginx/sites-available/forgejo +``` + +- Add: + +```nginx +server { + listen 80; + listen [::]:80; + server_name my.domain.tld; + + location / { + client_max_body_size 4G; + proxy_pass http://localhost:3000; + proxy_set_header Host $host; + proxy_set_header X-Real_IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +(This assumes you have registered a domain and added A and AAAA records.) + +- Create symlink to actually enable the site + +```bash +sudo ln -s /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/ +``` + +- Install Certbot + +```bash +sudo apt install snapd +sudo snap install --classic certbot +sudo ln -s /snap/bin/certbot /usr/bin/certbot +``` + +- Get Let's Encrypt certificate. For testing, add `--test-cert`. + +```bash +sudo certbot --nginx +``` + +- Run your docker compose + +```bash +cd ~/forgejo +sudo docker-compose up -d +``` + +- To redirect the homepage to the repository view: + +```nginx +server { + server_name code.virtuos.world; + + location / { + client_max_body_size 4G; + proxy_pass http://localhost:3000; + proxy_set_header Host $host; + proxy_set_header X-Real_IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = / { + return 301 https://$host/explore/repos; + } + + listen [::]:443 ssl ipv6only=on; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/code.virtuos.world/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/code.virtuos.world/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; +} + +server { + if ($host = code.virtuos.world) { + return 301 https://$host$request_uri; + } + + listen 80; + listen [::]:80; + server_name code.virtuos.world; + return 404; +} +``` + +Thanks to KeepItTechie for this tutorial: [https://www.youtube.com/watch?v=I4OQMc1rIO4](https://www.youtube.com/watch?v=I4OQMc1rIO4) + +## Customizing Forgejo/Gitea + +On the host, the path starts from the folder with your docker-compose file, `/forgejo/gitea/public/assets/` + +Paste the images with the respective names listed below: + +- `public/img/logo.svg` - Used for site icon, app icon +- `public/img/logo.png` - Used for Open Graph +- `public/img/avatar_default.png` - Used as the default avatar image +- `public/img/apple-touch-icon.png` - Used on iOS devices for bookmarks +- `public/img/favicon.svg` - Used for favicon +- `public/img/favicon.png` - Used as fallback for browsers that don't support SVG favicons + +--- + +# Leantime + +Leantime is an open source project management system. The Leantime instance is hosted on Uberspace.de and can be accessed on [https://manage.virtuos.world](https://manage.virtuos.world). + +## Installation on Uberspace + +- Download latest release package, upload and untar: + +```bash +tar -xf +``` + +- Create an empty MySQL database: + +```bash +mysql -e "CREATE DATABASE _leantime" +``` + +- Point your domain to the `public/` directory +Edit `/leantime/public/.htaccess`: + +```apache +Options +SymLinksIfOwnerMatch +RewriteEngine On +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^ index.php [L] +``` + +- Get your MySQL credentials: + +```bash +my_print_defaults client +``` + +- Fill in your database credentials (username, password, host, dbname) in `config/sample.env` +- Rename `config/sample.env` to `config/.env` +- Navigate to `/install` +- Follow instructions to install database and set up first user account + +## Updating Leantime + +Leantime comes with an update script in `/leantime`: + +```bash +./updateLeantime.sh +``` + +--- + +# Wordpress + +Wordpress is an open source Content Management System (CMS). The Wordpress instance is hosted on Uberspace.de and can be accessed on [https://virtuos.world](https://virtuos.world). + +## Installation on Uberspace + +The Wordpress installation is well documented on +[https://lab.uberspace.de/guide_wordpress/](https://lab.uberspace.de/guide_wordpress/) + +## Updating Wordpress + +Wordpress updates itself. Plugins may need manual updating via the Wordpress Interface. + +--- + +# Wiki.js + +Wiki.js is an open source Wiki software. The Wiki.js instance is hosted on Uberspace.de and you are currently accessing it on [https://docs.virtuos.world](https://docs.virtuos.world). + +## Installation on Uberspace + +The Wiki.js installation is well documented on +[https://lab.uberspace.de/guide_wiki-js/](https://lab.uberspace.de/guide_wiki-js/) + +## Updating Wiki.js + +An update script is available at the same location: +[https://lab.uberspace.de/guide_wiki-js/](https://lab.uberspace.de/guide_wiki-js/) + +--- + +# Pretix + +Pretix is an open source ticketing system. It's currently not in use. This installation is not as easy, but well documented here: +[https://docs.pretix.eu/en/latest/admin/installation/docker_smallscale.html](https://docs.pretix.eu/en/latest/admin/installation/docker_smallscale.html) diff --git a/theme.scss b/theme.scss new file mode 100644 index 0000000..838fc60 --- /dev/null +++ b/theme.scss @@ -0,0 +1,37 @@ +/*-- scss:defaults --*/ +/* Define any default settings for the theme */ + +$primary: #009fe3; + +/*-- scss:rules --*/ +/* Add custom rules for sidebar items and sections */ +.sidebar-item { + padding-bottom: 5px; /* Optional: spacing between items */ +} + +.sidebar-item:last-child { + border-bottom: none; +} + +.sidebar-item-section:not(:first-child) { + margin-top: 20px; /* Add space above each *non-first* section */ + padding-top: 10px; +} + + + +.sidebar-item-text { + font-weight: bold +} + + + + +/*-- scss:mixins --*/ +/* Add any reusable mixins if necessary */ + +/*-- scss:functions --*/ +/* Define any helper functions */ + +/*-- scss:uses --*/ +/* Any specific imports or additional styles */