<meta charset="utf-8"> <meta content="ie=edge" http-equiv="x-ua-compatible"> <meta name="handheldfriendly" content="true"> <meta name="viewport" content="initial-scale=1, width=device-width"> <meta name="description" content="Envision. Prototype. Perfect."> <meta name="application-name" content="v4k" /> <meta name="twitter:title" content="we are v4.games"> <meta name="twitter:description" content="Envision. Prototype. Perfect."> <meta name="twitter:image" content="https://v4k.dev/opengraph.png"> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:creator" content="@hey_v4games"> <meta name="twitter:site" content="@hey_v4games"> <meta name="twitter:image:alt" content="v4.games"> <meta property="og:site_name" content="v4.games"> <meta property="og:title" content="we are v4.games"> <meta property="og:description" content="Envision. Prototype. Perfect."> <meta property="og:image" content="https://v4k.dev/opengraph.png"> <meta property="og:url" content="https://v4k.dev/"> <meta property="og:type" content="website"> <link rel="apple-touch-icon" sizes="57x57" href="/icons/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="60x60" href="/icons/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="72x72" href="/icons/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="76x76" href="/icons/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="114x114" href="/icons/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="120x120" href="/icons/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="144x144" href="/icons/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="152x152" href="/icons/apple-icon-152x152.png"> <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-icon-180x180.png"> <link rel="icon" type="image/png" sizes="192x192" href="/icons/android-icon-192x192.png"> <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="96x96" href="/icons/favicon-96x96.png"> <link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png"> <link rel="manifest" href="/icons/manifest.json"> <meta name="msapplication-TileColor" content="#ffffff"> <meta name="msapplication-TileImage" content="/icons/ms-icon-144x144.png"> <meta name="theme-color" content="#ffffff"> <link type="application/json+oembed" href="https://v4k.dev/oembed.json" /> <link rel="canonical" href="https://v4k.dev/"> <style class="fallback">body{visibility:hidden;}</style><style> /* original .css from: https://autodesk.github.io/standard-surface/style/style.css */ /******************************************************************************/ /* Fonts /******************************************************************************/ @font-face { font-family: 'Artifakt Legend'; font-style: normal; font-weight: 700; src: url('https://autodesk.github.io/standard-surface/style/fonts/Artifakt/Artifakt Legend Bold.woff2') format('woff2'); } @font-face { font-family: 'Artifakt Element'; font-style: normal; font-weight: 400; src: url('https://autodesk.github.io/standard-surface/style/fonts/Artifakt/Artifakt Element Regular.woff2') format('woff2'); } @font-face { font-family: 'Artifakt Element'; font-style: normal; font-weight: 500; src: url('https://autodesk.github.io/standard-surface/style/fonts/Artifakt/Artifakt Element Medium.woff2') format('woff2'); } @font-face { font-family: 'Artifakt Element'; font-style: normal; font-weight: 700; src: url('https://autodesk.github.io/standard-surface/style/fonts/Artifakt/Artifakt Element Bold.woff2') format('woff2'); } @font-face { font-family: 'Roboto Mono'; font-style: normal; font-weight: 400; src: local('Roboto Mono'), local('RobotoMono-Regular'), url('https://autodesk.github.io/standard-surface/style/fonts/RobotoMono/RobotoMono-Regular.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* Latin */ } @font-face { font-family: 'Roboto Mono'; font-style: normal; font-weight: 700; src: local('Roboto Mono Bold'), local('RobotoMono-Bold'), url('https://autodesk.github.io/standard-surface/style/fonts/RobotoMono/RobotoMono-Bold.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* Latin */ } @font-face { font-family: 'PT Serif'; font-style: italic; font-weight: 400; src: local('PT Serif Italic'), local('PTSerif-Italic'), url('https://autodesk.github.io/standard-surface/style/fonts/PTSerif/PTSerif-Italic.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* Latin */ } @font-face { font-family: 'PT Serif'; font-style: normal; font-weight: 400; src: local('PT Serif'), local('PTSerif-Regular'), url('https://autodesk.github.io/standard-surface/style/fonts/PTSerif/PTSerif-Regular.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* Latin */ } @font-face { font-family: 'PT Serif'; font-style: normal; font-weight: 700; src: local('PT Serif Bold'), local('PTSerif-Bold'), url('https://autodesk.github.io/standard-surface/style/fonts/PTSerif/PTSerif-Bold.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* Latin */ } /******************************************************************************/ /* Document body /******************************************************************************/ body { max-width: 800px; font-family: 'Artifakt Element', sans-serif; /*'PT Serif', serif;*/ /*<@r-lyeh*/ padding: 70px 10px 0px 10px; min-width: 260px; font-size: 16px; /*16px;*/ /*<@r-lyeh*/ line-height: 19px; /*21px*/ /*<@r-lyeh*/ color: rgb(224,224,255); /*black;*/ /*<@r-lyeh*/ background-color: rgb(40,40,40); /*<@r-lyeh*/ text-align: left; /*<@r-lyeh*/ } @media print { body { max-width: 100%; padding: 0 5%; } } /******************************************************************************/ /* Table of contents /******************************************************************************/ /* For screens wide enough, put on the left side */ @media screen and (min-width: 1100px) /*<@r-lyeh*/ { .md .longTOC, .md .mediumTOC, .md .shortTOC { max-width: 300px; /*<@r-lyeh*/ left: 0em; /*right: 0em;*/ /*<@r-lyeh*/ display: block; position: fixed; top: -30px; /*0;*/ /*<@r-lyeh*/ padding: 0em 1em 0 0; /*1em 1em 0 0;*/ /*<@r-lyeh*/ bottom: 0; margin-top: 0; margin-bottom: 0; font-size: 85%; line-height: 120%; border: 0; opacity: 0.66; font-family: 'Artifakt Element', sans-serif; } .md .shortTOC { top: 0; padding: 1em 1em 0 0; } .md .longTOC, .md .mediumTOC { overflow-y: hidden; /*< @r-lyeh*/ /* https://css-tricks.com/scrollbars-on-hover/ overflow-y: scroll; mask-image: linear-gradient(to top, transparent, black), linear-gradient(to left, transparent 17px, black 17px); mask-size: 100% 20000px; mask-position: left bottom; -webkit-mask-image: linear-gradient(to top, transparent, black), linear-gradient(to left, transparent 17px, black 17px); -webkit-mask-size: 100% 20000px; -webkit-mask-position: left bottom; transition: mask-position 0.3s, -webkit-mask-position 0.3s; */ } .md .longTOC a, .md .mediumTOC a, .md .shortTOC a { font-family: 'Artifakt Element', sans-serif; } .md .longTOC:hover, .md .mediumTOC:hover, .md .shortTOC:hover { opacity: 1; } } /* For narrow screens, make inline */ @media screen and (max-width: 1099px) /*<@r-lyeh*/ { .md .longTOC, .md .mediumTOC, .md .shortTOC { display: block; margin: 20px 0 40px 3px; padding: 0; padding-top: 13px; float: initial; font-size: 98%; line-height: 120%; border: 0; font-family: 'Artifakt Element', sans-serif; border-top: 1px solid rgba(0,0,0,.1); border-bottom: 1px solid rgba(0,0,0,.1); } .md .longTOC a, .md .mediumTOC a, .md .shortTOC a { font-family: 'Artifakt Element', sans-serif; } } /* For print, hide */ @media print { .md .longTOC, .md .mediumTOC, .md .shortTOC { display: none; } } .md div.title { font-family: 'Artifakt Legend', sans-serif; font-weight: 700; border: 0; } contents, .md .tocHeader, .md h1, .md h2, .md h3, .md h4, .md h5, .md h6, .md .nonumberh1, .md .nonumberh2, .md .nonumberh3, .md .nonumberh4, .md .nonumberh5, .md .nonumberh6 { font-family: 'Artifakt Element', sans-serif; font-weight: 500; border: 0; } .md .tocHeader { margin: 0; padding: 0; border: none; font-size: inherit; } .md .longTOC p, .md .mediumTOC p, .md .shortTOC p { overflow: hidden; text-overflow: ellipsis; } .md .longTOC center, .md .mediumTOC center, .md .shortTOC center, .md .tocHeader { text-align: left; } .md .longTOC b, .md .mediumTOC b, .md .shortTOC b { font-weight: 500; font-size: 120%; } .md .longTOC a.level1, .md .mediumTOC a.level1, .md .shortTOC a.level1 { display: inline-block; color: rgba(255,255,255,.95); /*rgba(0,0,0,.95);*/ /*<@r-lyeh*/ font-weight: 500; margin-top: 7px; margin-bottom: 4px; } .md .longTOC a.level2, .md .mediumTOC a.level2, .md .shortTOC a.level2 { color: rgba(255,255,255,.9); /*rgba(0,0,0,.9);*/ /*<@r-lyeh*/ font-weight: 400; line-height: 130%; } /******************************************************************************/ /* Titles and headings /******************************************************************************/ /* Title style */ .md div.title { color: rgba(255,255,255,.7); /*rgba(0,0,0,.7);*/ /*<@r-lyeh*/ margin: 0.4em 0 20px 0; /*0.4em 0 20px 0;*/ /*<@r-lyeh*/ padding: 0; font-size: 230%; font-weight: 700; text-align: center; } /* Subtitle style */ .md div.subtitle { text-align: center; font-size: 95%; } /* Blue sections */ .md h1, .md .nonumberh1 { font-size: 150%; color: #029be5; } /* Grey sub-sections */ .md h2, .md .nonumberh2, .md h3, .md .nonumberh3 { font-size: 130%; color: rgba(255,255,255,.7); /*rgba(0,0,0,.7);*/ /*<@r-lyeh*/ } .md h3, .md .nonumberh3 { font-size: 115%; margin-bottom: 0; color: rgba(255,255,255,.75); /*rgba(0,0,0,.75);*/ /*<@r-lyeh*/ } /******************************************************************************/ /* Tables /******************************************************************************/ .md table.table { font-size: 90%; width: 100%; border: 1px solid rgb(30,30,30); /*(230,230,230)*/ /*<@r-lyeh*/ } .md table.table td { border: none; padding: 7px 7px 7px 7px; } /* Header row */ .md table.table th { border: none; background-color: rgb(0,207,156); /*(230,230,230)*/ /*<@r-lyeh*/ color: rgb(20,20,20); /*black;*/ /*<@r-lyeh*/ font-weight: 700; font-family: 'Artifakt Element', sans-serif; padding: 7px 7px 7px 7px; } /* Even table rows: 1, 3, ... */ .md table.table tr:nth-child(odd) { background-color: rgb(53,53,53); /*(247,247,247);*/ /*<@r-lyeh*/ } /* Odd table rows: 2, 4, ... */ .md table.table tr:nth-child(even) { background-color: rgb(47,47,47); /*(253,253,253);*/ /*<@r-lyeh*/ } .md table.table tr:hover { background-color: rgb(66,66,66); /*#f9f5d7;*/ /*<@r-lyeh*/ } /******************************************************************************/ /* Links /******************************************************************************/ html { scroll-behavior: smooth; /*<@r-lyeh*/ } .md a { font-family: 'Artifakt Element', sans-serif; /*'PT Serif';*/ /*<@r-lyeh*/ scroll-margin-top: 20px; /*<@r-lyeh*/ } .md a:link, .md a:visited { color: #00C0FF /* #0085c7; */ /*<@r-lyeh*/ } /* For print, make links black */ @media print { .md a:link, .md a:visited { color: black; } } /******************************************************************************/ /* Misc /******************************************************************************/ /* Code */ .md code { padding: 0; border: none; font-family: 'Roboto Mono', monospace; font-size: 88%; /*92%*/ /*<@r-lyeh*/ /*overflow-x: hidden;*/ /*<@r-lyeh*/ } .md pre.listing { background-color: transparent; font-size: 93%; background-color: rgb(250,250,250); border: 1px solid rgba(0,0,0,.05); padding: 6px 10px; text-align: left; /*overflow-x: hidden;*/ /*<@r-lyeh*/ width: 97%; /*hack, i dont know how to align this width with every other element <@r-lyeh*/ } /* Bibliography */ .md .bib { font-size: 90%; padding-left: 20px; text-indent: -20px; } .md .bib b { font-weight: inherit; font-style: italic; } hr.pagebreak { visibility: hidden; } .afterTitles { height: 50px !important; } /* Center short image captions */ .md div.table { margin: 0 0 30px 0; /*0 0 30px 0;*/ /*<@r-lyeh*/ } .md div.tablecaption { text-align: justify; } /* Center short image captions */ .md div.imagecaption { display: inline-block; margin: 7px 0 0 0; } .md img.markdeep { margin-top: 25px; } .md .subtitle img.markdeep { margin-top: 7px; } .md .imagecaption b { font-weight: 700; color: rgba(255,255,255,.85); /*rgba(0,0,0,.85);*/ /*<@r-lyeh*/ } /* Hack to place a caption below a table of images */ .shifted-caption { margin-top: -30px; text-align: center; } .shifted-caption .image { float: initial !important; margin: 0 !important; } .shifted-caption img { display: none; } .markdeepFooter { opacity: 0.4; } .md code .long { font-size: 88%; } /* For print, hide Markdeep footer */ @media print { .markdeepFooter { display: none; } } .md .admonition { background-color:rgba(68,138,255,0.45); } /* .15); }*/ /*<@r-lyeh*/ .md .admonition.tip { background-color:rgba(50,255,90,0.55); } /* .15); }*/ /*<@r-lyeh*/ .md .admonition.warn,.md .admonition.warning { background-color:rgba(255,125,0,0.85); } /* 255,145,0,0.15); }*/ /*<@r-lyeh*/ .md .admonition.error { background-color:rgba(255,23,68,0.65); } /* .15); }*/ /*<@r-lyeh*/ /* external link img, no unicode available */ a[target="_blank"]::after { filter: invert(80%); margin: 0 3px 0 5px; content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==); } /* Stylize details/summary html tags */ /* Credits: https://dev.to/vtrpldn/show-and-hide-content-easily-with-details-and-summary-html-tags-3eif */ /* The --padding variable help us control the <details> and <summary> spacing */ :root { --padding: 4px; /*16px;*/ /*<@r-lyeh*/ } details { padding: 0 var(--padding); box-shadow: inset 0 0 0 0px; /*4px;*/ /*<@r-lyeh*/ border-radius: 1px; /*4px*/ /*<@r-lyeh*/ background-color:#333; /*<@r-lyeh*/ margin: -15px 0 0 0; /*<@r-lyeh*/ /*fits all <details> together */ } summary { padding-left: 16px; /*<@r-lyeh*/ text-overflow: ellipsis; /* Both of the following are required for text-overflow */ white-space: nowrap; overflow: hidden; } details[open] { padding-bottom: var(--padding); box-shadow: inset 0 0 0 1px; /*<@r-lyeh*/ background-color:transparent; /*<@r-lyeh*/ } details > summary { display: flex; padding: var(--padding); margin: 0 calc(var(--padding) * -1); border-radius: 4px; /*font-size: 24px;*/ /*<@r-lyeh*/ cursor: pointer; justify-content: space-between; list-style: none; /* Hides the default arrow */ } details[open] > summary { box-shadow: 0 0px; /*4px;*/ /*<@r-lyeh*/ } /* Adds an (+) icon when the <details> is closed... */ details > summary::after { content: "⇕"; } /* ...and switches it when <details> is open (-) icon */ details[open] > summary::after { content: "⇕"; } /* Removes the ugly default arrow on Chrome */ details > summary::-webkit-details-marker { display: none; } /*<@r-lyeh*/ /*<!--link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/styles/base16/horizon-dark.min.css" /-->*/ /* .hljs-comment,.hljs-quote{color:#969896}.hljs-variable,.hljs-template-variable,.hljs-tag,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-deletion{color:#cc6666}.hljs-number,.hljs-built_in,.hljs-builtin-name,.hljs-literal,.hljs-type,.hljs-params,.hljs-meta,.hljs-link{color:#de935f}.hljs-attribute{color:#f0c674}.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#b5bd68}.hljs-title,.hljs-section{color:#81a2be}.hljs-keyword,.hljs-selector-tag{color:#b294bb}.hljs{display:block;overflow-x:auto;background:#1d1f21;color:#c5c8c6;padding:0.5em}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} */ /*.hljs{display:block;overflow-x:auto;padding:0.5em;background:#272822;color:#ddd}.hljs-tag,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-strong,.hljs-name{color:#f92672}.hljs-code{color:#66d9ef}.hljs-class .hljs-title{color:white}.hljs-attribute,.hljs-symbol,.hljs-regexp,.hljs-link{color:#bf79db}.hljs-string,.hljs-bullet,.hljs-subst,.hljs-title,.hljs-section,.hljs-emphasis,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-addition,.hljs-variable,.hljs-template-tag,.hljs-template-variable{color:#a6e22e}.hljs-comment,.hljs-quote,.hljs-deletion,.hljs-meta{color:#75715e}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-doctag,.hljs-title,.hljs-section,.hljs-type,.hljs-selector-id{font-weight:bold}*/ /*.hljs{display:block;overflow-x:auto;padding:0.5em;background:#333;color:white}.hljs-name,.hljs-strong{font-weight:bold}.hljs-code,.hljs-emphasis{font-style:italic}.hljs-tag{color:#62c8f3}.hljs-variable,.hljs-template-variable,.hljs-selector-id,.hljs-selector-class{color:#ade5fc}.hljs-string,.hljs-bullet{color:#a2fca2}.hljs-type,.hljs-title,.hljs-section,.hljs-attribute,.hljs-quote,.hljs-built_in,.hljs-builtin-name{color:#ffa}.hljs-number,.hljs-symbol,.hljs-bullet{color:#d36363}.hljs-keyword,.hljs-selector-tag,.hljs-literal{color:#fcc28c}.hljs-comment,.hljs-deletion,.hljs-code{color:#888}.hljs-regexp,.hljs-link{color:#c6b4f0}.hljs-meta{color:#fc9b9b}.hljs-deletion{background-color:#fc9b9b;color:#333}.hljs-addition{background-color:#a2fca2;color:#333}.hljs a{color:inherit}.hljs a:focus,.hljs a:hover{color:inherit;text-decoration:underline}*/ .hljs{display:block;overflow-x:auto;padding:.5em;background:#011627;color:#d6deeb}.hljs-keyword{color:#c792ea;font-style:italic}.hljs-built_in{color:#addb67;font-style:italic}.hljs-type{color:#82aaff}.hljs-literal{color:#ff5874}.hljs-number{color:#f78c6c}.hljs-regexp{color:#5ca7e4}.hljs-string{color:#ecc48d}.hljs-subst{color:#d3423e}.hljs-symbol{color:#82aaff}.hljs-class{color:#ffcb8b}.hljs-function{color:#82aaff}.hljs-title{color:#dcdcaa;font-style:italic}.hljs-params{color:#7fdbca}.hljs-comment{color:#637777;font-style:italic}.hljs-doctag{color:#7fdbca}.hljs-meta{color:#82aaff}.hljs-meta-keyword{color:#82aaff}.hljs-meta-string{color:#ecc48d}.hljs-section{color:#82b1ff}.hljs-builtin-name,.hljs-name,.hljs-tag{color:#7fdbca}.hljs-attr{color:#7fdbca}.hljs-attribute{color:#80cbc4}.hljs-variable{color:#addb67}.hljs-bullet{color:#d9f5dd}.hljs-code{color:#80cbc4}.hljs-emphasis{color:#c792ea;font-style:italic}.hljs-strong{color:#addb67;font-weight:700}.hljs-formula{color:#c792ea}.hljs-link{color:#ff869a}.hljs-quote{color:#697098;font-style:italic}.hljs-selector-tag{color:#ff6363}.hljs-selector-id{color:#fad430}.hljs-selector-class{color:#addb67;font-style:italic}.hljs-selector-attr,.hljs-selector-pseudo{color:#c792ea;font-style:italic}.hljs-template-tag{color:#c792ea}.hljs-template-variable{color:#addb67}.hljs-addition{color:#addb67ff;font-style:italic}.hljs-deletion{color:#ef535090;font-style:italic} /* Remove numbers from headers */ /* .md h1:before, .md h2:before, .md h3:before, .md h4:before, .md h5:before {content: none;} */ /* Examples background and text to match Observable Dark */ /*.md code { color:#f00; }*/ .md pre.listing.tilde, .md pre.listing.backtick {background-color:#333; color:#FFF;} /* Change color of diagrams and darken circle around open dots */ /*.md svg.diagram {stroke: #C5C5C5; fill: #C5C5C5;}*/ /*.md svg.diagram .opendot {stroke: #858585; fill: #FFF;}*/ /* Grey shade multi-block example */ /* .md code > .output {background: #979797;} */ /* highlight.js brighten function and title names */ .hljs-function .hljs-title {color: #00C0FF;} .hljs-class .hljs-title {color: #00FFC0;} .md code { color: rgb(255,255,235); } /* default unclassified #text and punctuation */ #id { width: 100%; text-align: center; display: inline-block; } #id img { width: 256px; transform: translateX(-50%); position: absolute; display: inline-block; } </style> <div id="logo"> <img src="/logo.png" alt="v4k logo"/> <p>Our go-to framework for game development is fully hackable, <strong>FOSS</strong>!</p> </div>