added content.svelte to handle page max width for specific elements; added alternative page banner
This commit is contained in:
72
src/lib/banner-title-alt.svelte
Normal file
72
src/lib/banner-title-alt.svelte
Normal file
@@ -0,0 +1,72 @@
|
||||
<script lang="ts">
|
||||
import SeparatorLine from "./separator-line.svelte";
|
||||
|
||||
let {
|
||||
title,
|
||||
subtitle = "",
|
||||
banner = "",
|
||||
}: {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
banner?: string;
|
||||
} = $props();
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="img-container">
|
||||
<img src="{banner}">
|
||||
</div>
|
||||
<div class="text-container">
|
||||
<h1 class="title">{title}</h1>
|
||||
{#if subtitle}
|
||||
<p class="subtitle">{subtitle}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SeparatorLine />
|
||||
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: var(--color-background-highlight);
|
||||
}
|
||||
|
||||
.img-container {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
width: 48%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.container img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: fit-content;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.6rem;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
10
src/lib/content.svelte
Normal file
10
src/lib/content.svelte
Normal file
@@ -0,0 +1,10 @@
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto 228px;
|
||||
}
|
||||
</style>
|
||||
@@ -52,6 +52,7 @@
|
||||
}
|
||||
|
||||
.entry {
|
||||
width: 100%;
|
||||
margin: 4px;
|
||||
padding-bottom: 20px;
|
||||
background-color: var(--color-background-highlight);
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 auto 228px;
|
||||
max-width: 1200px;
|
||||
|
||||
font-family: var(--font-sans-serif);
|
||||
font-size: 1.1rem;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Content from "$lib/content.svelte";
|
||||
import GamedevWebring from "$lib/webrings/gamedev.svelte";
|
||||
import Gallery from "$lib/lists/gallery-entry.svelte";
|
||||
import LinkList from "$lib/link-list.svelte";
|
||||
@@ -26,69 +27,71 @@
|
||||
<title>denizk0461's website</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1 class="gradient-title"><i>Moin!</i> ~ welcome to my website :)</h1>
|
||||
<Content>
|
||||
<h1 class="gradient-title"><i>Moin!</i> ~ welcome to my website :)</h1>
|
||||
|
||||
<div class="container">
|
||||
<div class="subcontainer">
|
||||
<Gallery entries={[
|
||||
{
|
||||
title: "Project N5 – devlog",
|
||||
subtitle: "my active game project about a girl finding herself in an unfamiliar future",
|
||||
fullWidth: true,
|
||||
img: "projects/projectn5/devlog/20250316/fishmonger.webp",
|
||||
link: "projects/projectn5/devlog",
|
||||
},
|
||||
{
|
||||
title: "Projects",
|
||||
subtitle: "an overview of what i do and have done",
|
||||
fullWidth: false,
|
||||
img: "projects/project-mix.webp",
|
||||
link: "projects",
|
||||
},
|
||||
{
|
||||
title: "Blog",
|
||||
subtitle: "more to come <i>soon</i>",
|
||||
fullWidth: false,
|
||||
img: "common/hypertext.webp",
|
||||
link: "",
|
||||
},
|
||||
]}/>
|
||||
<div class="container">
|
||||
<div class="subcontainer">
|
||||
<Gallery entries={[
|
||||
{
|
||||
title: "Project N5 – devlog",
|
||||
subtitle: "my active Godot game project about finding yourself in an unfamiliar future",
|
||||
fullWidth: true,
|
||||
img: "projects/projectn5/devlog/20250316/fishmonger.webp",
|
||||
link: "projects/projectn5/devlog",
|
||||
},
|
||||
{
|
||||
title: "Projects",
|
||||
subtitle: "an overview of what i do and have done",
|
||||
fullWidth: false,
|
||||
img: "projects/project-mix.webp",
|
||||
link: "projects",
|
||||
},
|
||||
{
|
||||
title: "Blog",
|
||||
subtitle: "more to come <i>soon</i>",
|
||||
fullWidth: false,
|
||||
img: "common/hypertext.webp",
|
||||
link: "",
|
||||
},
|
||||
]}/>
|
||||
</div>
|
||||
<div class="subcontainer">
|
||||
<h3>about ↬<img id="me-img" class="me-img" title="hi there" src={meImg} onclick={setPicture}>↫ me </h3>
|
||||
|
||||
<p>Hi! I'm Deniz. I'm a programmer, sometimes a music producer, and rarely a hard-working student in Northern Germany. Welcome to my webpage!</p>
|
||||
|
||||
<p>Here you can find information on things I like sharing. check out my projects, especially the devlog of the game I'm working on!</p>
|
||||
|
||||
<h3>where to find me</h3>
|
||||
|
||||
<LinkList entries={[
|
||||
{
|
||||
icon: "icons/bluesky.svg",
|
||||
text: "Bluesky",
|
||||
link: "https://bsky.app/profile/denizk0461.bsky.social",
|
||||
},
|
||||
{
|
||||
icon: "icons/codeberg.svg",
|
||||
text: "Codeberg",
|
||||
link: "https://codeberg.org/denizk0461",
|
||||
},
|
||||
{
|
||||
icon: "icons/github.svg",
|
||||
text: "GitHub",
|
||||
link: "https://github.com/denizk0461",
|
||||
},
|
||||
{
|
||||
icon: "icons/mailboxdotorg.svg",
|
||||
text: "E-Mail: denizk0461@mailbox.org",
|
||||
link: "",
|
||||
},
|
||||
]}/>
|
||||
|
||||
<GamedevWebring />
|
||||
</div>
|
||||
</div>
|
||||
<div class="subcontainer">
|
||||
<h3>about ↬<img id="me-img" class="me-img" title="hi there" src={meImg} onclick={setPicture}>↫ me </h3>
|
||||
|
||||
<p>Hi! I'm Deniz. I'm a programmer, sometimes a music producer, and rarely a hard-working student in Northern Germany. Welcome to my webpage!</p>
|
||||
|
||||
<p>Here you can find information on things I like sharing. check out my projects, especially the devlog of the game I'm working on!</p>
|
||||
|
||||
<h3>where to find me</h3>
|
||||
|
||||
<LinkList entries={[
|
||||
{
|
||||
icon: "icons/bluesky.svg",
|
||||
text: "Bluesky",
|
||||
link: "https://bsky.app/profile/denizk0461.bsky.social",
|
||||
},
|
||||
{
|
||||
icon: "icons/codeberg.svg",
|
||||
text: "Codeberg",
|
||||
link: "https://codeberg.org/denizk0461",
|
||||
},
|
||||
{
|
||||
icon: "icons/github.svg",
|
||||
text: "GitHub",
|
||||
link: "https://github.com/denizk0461",
|
||||
},
|
||||
{
|
||||
icon: "icons/mailboxdotorg.svg",
|
||||
text: "E-Mail: denizk0461@mailbox.org",
|
||||
link: "",
|
||||
},
|
||||
]}/>
|
||||
|
||||
<GamedevWebring />
|
||||
</div>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import BannerTitleAlt from "$lib/banner-title-alt.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import type { Project } from './projects';
|
||||
import { projects } from './projects';
|
||||
import LinkList from "$lib/link-list.svelte";
|
||||
@@ -20,21 +21,25 @@
|
||||
<title>Projects | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="My Disordered Projects" banner="/projects/banner.webp" />
|
||||
<BannerTitleAlt
|
||||
title="My Disordered Projects"
|
||||
banner="/projects/banner.webp"
|
||||
subtitle="Here's a listing of some of my more noteworthy projects that can be found on the web."
|
||||
/>
|
||||
|
||||
<p>This is a listing of some of my more noteworthy projects that can be found on the web.</p>
|
||||
<Content>
|
||||
<TableOfContents />
|
||||
|
||||
<TableOfContents />
|
||||
<h2>Active Projects</h2>
|
||||
{#each getActiveProjects(projects, true) as activeProject}
|
||||
{@render projectSummary({ project: activeProject })}
|
||||
{/each}
|
||||
|
||||
<h2>Active Projects</h2>
|
||||
{#each getActiveProjects(projects, true) as activeProject}
|
||||
{@render projectSummary({ project: activeProject })}
|
||||
{/each}
|
||||
|
||||
<h2>Past Projects</h2>
|
||||
{#each getActiveProjects(projects, false) as pastProject}
|
||||
{@render projectSummary({ project: pastProject })}
|
||||
{/each}
|
||||
<h2>Past Projects</h2>
|
||||
{#each getActiveProjects(projects, false) as pastProject}
|
||||
{@render projectSummary({ project: pastProject })}
|
||||
{/each}
|
||||
</Content>
|
||||
|
||||
{#snippet projectSummary({
|
||||
project
|
||||
@@ -60,6 +65,10 @@
|
||||
{/snippet}
|
||||
|
||||
<style>
|
||||
.asdf {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.subtitle {
|
||||
color: var(--color-highlight);
|
||||
font-weight: 700;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,105 +8,107 @@
|
||||
<title>Daisy FM Synth | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Daisy FM Synth" banner="/projects/daisyfm/banner.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Daisy FM Synth" banner="/projects/daisyfm/banner.webp" />
|
||||
|
||||
<img src="/projects/daisyfm/fullview.webp">
|
||||
<img src="/projects/daisyfm/fullview.webp">
|
||||
|
||||
<p>A friend showed me the <a href="https://electro-smith.com/products/daisy-seed">Daisy Seed</a>, an Arduino-compatible microcontroller made for developing audio equipment. With a little bit of motivation and absolutely no experience in either programming synthesisers or electronics in general, I quickly got my hands on one and started to toy around.</p>
|
||||
<p>A friend showed me the <a href="https://electro-smith.com/products/daisy-seed">Daisy Seed</a>, an Arduino-compatible microcontroller made for developing audio equipment. With a little bit of motivation and absolutely no experience in either programming synthesisers or electronics in general, I quickly got my hands on one and started to toy around.</p>
|
||||
|
||||
<p>So... <i>how did we get here?</i></p>
|
||||
<p>So... <i>how did we get here?</i></p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<h2 id="creation">How did I make this?</h2>
|
||||
<h2 id="creation">How did I make this?</h2>
|
||||
|
||||
<h3 id="components">Components</h3>
|
||||
<h3 id="components">Components</h3>
|
||||
|
||||
<p><a href="https://www.reichelt.de/my/2171501">Here's a list of the components</a> I used in this project.</p>
|
||||
<p><a href="https://www.reichelt.de/my/2171501">Here's a list of the components</a> I used in this project.</p>
|
||||
|
||||
<ul>
|
||||
<li>21 Cherry MX Low Profile Red switches, of which 15 are used for the playing keys, and 6 are used for the wavetable select (sine, square, saw) – 3 for the carrier signal, and another 3 for the modulator signal.</li>
|
||||
<li>11 rotating potentiometers RK11K113-LIN10K by Alps are used to adjust the volume ADSR curve as well as the effects.</li>
|
||||
<li>Two CD 4051BE multiplexers are used to connect further inputs, since the analogue inputs on the Daisy did not suffice. One of them connects the majority of the rotating potentiometers to Daisy, the other connects two potentiometers and the 6 wavetable keys. Takumi Ogata has a great guide on how to use these things with Daisy <a href="https://forum.electro-smith.com/t/cd4051-multiplexer-tutorial-is-here/3481">on the Daisy forum</a>!</li>
|
||||
<li>A toggle switch is used to toggle the flanger on and off.</li>
|
||||
<li>A 75mm sliding potentiometer is used to adjust the master volume.</li>
|
||||
<li>An audio jack breakout board provides means to connect the synth to an audio output. This can theoretically be replaced by any kind of analogue connector; this breakout board by Soldered just proved to be the most convenient for both soldering and mounting to the case.</li>
|
||||
<li>A USB-C breakout board, also by Soldered, is used for power and data transfer (flashing the synth). This isn't necessary, though since Daisy only provides a microUSB connector, I felt this was sorely needed.</li>
|
||||
<li>Two 5.1 kΩ, 0.25 W resistors are used as pulldown resistors to enable C-to-C functionality on the Daisy, making it compatible to the USB-C standard. Again, not necessary, though quite recommended if you're using a USB-C port.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>21 Cherry MX Low Profile Red switches, of which 15 are used for the playing keys, and 6 are used for the wavetable select (sine, square, saw) – 3 for the carrier signal, and another 3 for the modulator signal.</li>
|
||||
<li>11 rotating potentiometers RK11K113-LIN10K by Alps are used to adjust the volume ADSR curve as well as the effects.</li>
|
||||
<li>Two CD 4051BE multiplexers are used to connect further inputs, since the analogue inputs on the Daisy did not suffice. One of them connects the majority of the rotating potentiometers to Daisy, the other connects two potentiometers and the 6 wavetable keys. Takumi Ogata has a great guide on how to use these things with Daisy <a href="https://forum.electro-smith.com/t/cd4051-multiplexer-tutorial-is-here/3481">on the Daisy forum</a>!</li>
|
||||
<li>A toggle switch is used to toggle the flanger on and off.</li>
|
||||
<li>A 75mm sliding potentiometer is used to adjust the master volume.</li>
|
||||
<li>An audio jack breakout board provides means to connect the synth to an audio output. This can theoretically be replaced by any kind of analogue connector; this breakout board by Soldered just proved to be the most convenient for both soldering and mounting to the case.</li>
|
||||
<li>A USB-C breakout board, also by Soldered, is used for power and data transfer (flashing the synth). This isn't necessary, though since Daisy only provides a microUSB connector, I felt this was sorely needed.</li>
|
||||
<li>Two 5.1 kΩ, 0.25 W resistors are used as pulldown resistors to enable C-to-C functionality on the Daisy, making it compatible to the USB-C standard. Again, not necessary, though quite recommended if you're using a USB-C port.</li>
|
||||
</ul>
|
||||
|
||||
<p>I also bought <a href="https://www.amazon.de/dp/B07WTMGX6C">this 5-pack of 45mm sliding potentiometers</a> from Amazon. They're not of the highest quality and they don't have a covering protecting the resistance strips on the inside from debris, but they do snap to 50%, which I didn't know when I bought them, but turns out to be super convenient when used as a pitch slider!</p>
|
||||
<p>I also bought <a href="https://www.amazon.de/dp/B07WTMGX6C">this 5-pack of 45mm sliding potentiometers</a> from Amazon. They're not of the highest quality and they don't have a covering protecting the resistance strips on the inside from debris, but they do snap to 50%, which I didn't know when I bought them, but turns out to be super convenient when used as a pitch slider!</p>
|
||||
|
||||
<h3 id="pcb-assembly">PCB & Assembly</h3>
|
||||
<h3 id="pcb-assembly">PCB & Assembly</h3>
|
||||
|
||||
<h4 id="kicad">KiCad</h4>
|
||||
<h4 id="kicad">KiCad</h4>
|
||||
|
||||
<p>I designed the PCB in <a href="https://www.kicad.org/">KiCad</a>. I had no prior experience in designing PCBs, but designing one merely for interactable components was simple, as I didn't have to worry quite so much about electronic interference and similar issues commonly found in original PCB design utilising ICs and other complex components. I don't know much about this... but all of this is to say, learning KiCad for this project wasn't too difficult.</p>
|
||||
<p>I designed the PCB in <a href="https://www.kicad.org/">KiCad</a>. I had no prior experience in designing PCBs, but designing one merely for interactable components was simple, as I didn't have to worry quite so much about electronic interference and similar issues commonly found in original PCB design utilising ICs and other complex components. I don't know much about this... but all of this is to say, learning KiCad for this project wasn't too difficult.</p>
|
||||
|
||||
<p>I split the PCB into four layers, separating power, ground, digital signals (switches and toggle), and analogue signals (potentiometers, audio out). I made some exceptions, such as for the waveform buttons, since they cross the playing key traces.</p>
|
||||
<p>I split the PCB into four layers, separating power, ground, digital signals (switches and toggle), and analogue signals (potentiometers, audio out). I made some exceptions, such as for the waveform buttons, since they cross the playing key traces.</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/daisyfm/pcb-sketch.webp">
|
||||
<img src="/projects/daisyfm/pcb-empty.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/daisyfm/pcb-sketch.webp">
|
||||
<img src="/projects/daisyfm/pcb-empty.webp">
|
||||
</div>
|
||||
|
||||
<p>The PCB was manufactured by <a href="https://jlcpcb.com/">JLCPCB</a>.</p>
|
||||
<p>The PCB was manufactured by <a href="https://jlcpcb.com/">JLCPCB</a>.</p>
|
||||
|
||||
|
||||
<h4 id="usbc">USB-C</h4>
|
||||
<h4 id="usbc">USB-C</h4>
|
||||
|
||||
<p>If using a USB-C breakout board, wire in two 5.1 kΩ pulldown resistors by soldering a resistor between the pin CC1 and ground. Do the same for pin CC2 with a second resistor.</p>
|
||||
<p>If using a USB-C breakout board, wire in two 5.1 kΩ pulldown resistors by soldering a resistor between the pin CC1 and ground. Do the same for pin CC2 with a second resistor.</p>
|
||||
|
||||
<p>Alternatively, if your USB-C breakout board does not have CC pins exposed, there's a chance you could still connect pulldown resistors to make it compatible. On <a href="https://www.amazon.de/dp/B09FPZDDD9">this breakout board</a> I purchased on Amazon, I discovered that the third pin from the right exposes a CC connection. Wiring a resistor between this pin and ground enabled C-to-C functionality. If you want to test the functionality before soldering, you can hold a resistor between this pin and either the ground connector on the board or the USB port's outer shell, since that one's grounded as well.</p>
|
||||
<p>Alternatively, if your USB-C breakout board does not have CC pins exposed, there's a chance you could still connect pulldown resistors to make it compatible. On <a href="https://www.amazon.de/dp/B09FPZDDD9">this breakout board</a> I purchased on Amazon, I discovered that the third pin from the right exposes a CC connection. Wiring a resistor between this pin and ground enabled C-to-C functionality. If you want to test the functionality before soldering, you can hold a resistor between this pin and either the ground connector on the board or the USB port's outer shell, since that one's grounded as well.</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/daisyfm/usbc-breakout-small.webp">
|
||||
<img src="/projects/daisyfm/hand.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/daisyfm/usbc-breakout-small.webp">
|
||||
<img src="/projects/daisyfm/hand.webp">
|
||||
</div>
|
||||
|
||||
<p>Do keep in mind that this type of connector does not have mounting holes and requires either a more sophisticated mounting mechanism in the chassis, hot glue, or both. Also, soldering to this pin is insanely finicky, since it is VERY small, so I strongly recommend a breakout board such as <a href="https://www.reichelt.de/entwicklerboards-usb-typ-c-adapterboard-buchse-debo-usb-c-f-p376522.html">this one by Soldered</a> that exposes the CC pins.</p>
|
||||
<p>Do keep in mind that this type of connector does not have mounting holes and requires either a more sophisticated mounting mechanism in the chassis, hot glue, or both. Also, soldering to this pin is insanely finicky, since it is VERY small, so I strongly recommend a breakout board such as <a href="https://www.reichelt.de/entwicklerboards-usb-typ-c-adapterboard-buchse-debo-usb-c-f-p376522.html">this one by Soldered</a> that exposes the CC pins.</p>
|
||||
|
||||
<p>Actually, I later found out that this breakout board does expose CC solder pads on the back, where an SMD resistor such as <a href="https://www.reichelt.de/smd-widerstand-0402-5-1-kohm-63-mw-1--rnd-0402-1-5-1k-p182941.html">this one</a> can be placed. Since this is a 1mm long SMD component, however, and since I don't have a rework station or anything of the sort, it's safe to say I have not tried this yet.</p>
|
||||
<p>Actually, I later found out that this breakout board does expose CC solder pads on the back, where an SMD resistor such as <a href="https://www.reichelt.de/smd-widerstand-0402-5-1-kohm-63-mw-1--rnd-0402-1-5-1k-p182941.html">this one</a> can be placed. Since this is a 1mm long SMD component, however, and since I don't have a rework station or anything of the sort, it's safe to say I have not tried this yet.</p>
|
||||
|
||||
<p>Now, how do you connect the breakout to Daisy? Daisy does expose USB pins, but they require a little bit of setup. There's another way though, one that's simpler, if perhaps stupid: look for an old microUSB cable (one that carries data) and chop it up, then solder the wires of the end with the microUSB connector to the breakout board. The microUSB end can then be plugged straight into Daisy. By convention, the wiring is as follows:</p>
|
||||
<p>Now, how do you connect the breakout to Daisy? Daisy does expose USB pins, but they require a little bit of setup. There's another way though, one that's simpler, if perhaps stupid: look for an old microUSB cable (one that carries data) and chop it up, then solder the wires of the end with the microUSB connector to the breakout board. The microUSB end can then be plugged straight into Daisy. By convention, the wiring is as follows:</p>
|
||||
|
||||
<ul>
|
||||
<li>the red wire is power and goes to V or VUSB</li>
|
||||
<li>the black wire is ground and goes to G or GND</li>
|
||||
<li>the green wire is data+ and goes to D+</li>
|
||||
<li>the white wire is data- and goes to D-</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>the red wire is power and goes to V or VUSB</li>
|
||||
<li>the black wire is ground and goes to G or GND</li>
|
||||
<li>the green wire is data+ and goes to D+</li>
|
||||
<li>the white wire is data- and goes to D-</li>
|
||||
</ul>
|
||||
|
||||
<p>I used an angled microUSB cable for my chassis.</p>
|
||||
<p>I used an angled microUSB cable for my chassis.</p>
|
||||
|
||||
<h3 id="3d-print">Case & 3D Printing</h3>
|
||||
<h3 id="3d-print">Case & 3D Printing</h3>
|
||||
|
||||
<p>All components were printed using a <a href="https://eu.store.bambulab.com/collections/3d-printer/products/a1-mini?variant=49311552176476">Bambu Lab A1 mini printer</a> as well as Bambu Lab PLA Metal in the colours <a href="https://eu.store.bambulab.com/products/pla-metal?variant=46797850902876">Iron Gray</a> and <a href="https://eu.store.bambulab.com/products/pla-metal?variant=46797851099484">Iridium Gold</a>. These materials do not contain metal particles and are very easy to print.</p>
|
||||
<p>All components were printed using a <a href="https://eu.store.bambulab.com/collections/3d-printer/products/a1-mini?variant=49311552176476">Bambu Lab A1 mini printer</a> as well as Bambu Lab PLA Metal in the colours <a href="https://eu.store.bambulab.com/products/pla-metal?variant=46797850902876">Iron Gray</a> and <a href="https://eu.store.bambulab.com/products/pla-metal?variant=46797851099484">Iridium Gold</a>. These materials do not contain metal particles and are very easy to print.</p>
|
||||
|
||||
<p>The components were designed using <a href="https://www.autodesk.com/eu/products/fusion-360/overview">Autodesk Fusion</a>. Honestly, this program annoys me to no end sometimes, but it does prove to be quite useful. You can <a href="https://www.autodesk.com/education/edu-software/overview">get it for free</a> if you're a student, educator, or school IT admin, but they really make it difficult to find this page, I'm telling ya.</p>
|
||||
<p>The components were designed using <a href="https://www.autodesk.com/eu/products/fusion-360/overview">Autodesk Fusion</a>. Honestly, this program annoys me to no end sometimes, but it does prove to be quite useful. You can <a href="https://www.autodesk.com/education/edu-software/overview">get it for free</a> if you're a student, educator, or school IT admin, but they really make it difficult to find this page, I'm telling ya.</p>
|
||||
|
||||
<h3 id="programming">Programming</h3>
|
||||
<h3 id="programming">Programming</h3>
|
||||
|
||||
<p>The synth runs on a script written in the Arduino IDE using the <a href="https://electro-smith.github.io/DaisySP/index.html">DaisySP library</a>. Documentation was sparse... but it worked out. Finding the website wasn't actually all too easy, I found, though it proved to be my best resource.</p>
|
||||
<p>The synth runs on a script written in the Arduino IDE using the <a href="https://electro-smith.github.io/DaisySP/index.html">DaisySP library</a>. Documentation was sparse... but it worked out. Finding the website wasn't actually all too easy, I found, though it proved to be my best resource.</p>
|
||||
|
||||
<p>The synth essentially works by holding an array of 15 carrier oscillators and another 15 modulator oscillators. Each oscillator only plays when the volume is greater than 0, meaning that nothing is processed until a key is pressed. However, the load of processing 30 oscillators plus effects, if they are active, when pressing all the keys is too much and will cause Daisy to freeze and crash. This is not an issue during regular use, though.</p>
|
||||
<p>The synth essentially works by holding an array of 15 carrier oscillators and another 15 modulator oscillators. Each oscillator only plays when the volume is greater than 0, meaning that nothing is processed until a key is pressed. However, the load of processing 30 oscillators plus effects, if they are active, when pressing all the keys is too much and will cause Daisy to freeze and crash. This is not an issue during regular use, though.</p>
|
||||
|
||||
<p>Find the script on <a href="https://codeberg.org/denizk0461/daisy-fm-synth">my Codeberg page</a>!</p>
|
||||
<p>Find the script on <a href="https://codeberg.org/denizk0461/daisy-fm-synth">my Codeberg page</a>!</p>
|
||||
|
||||
<h2 id="features">What can it do?</h2>
|
||||
<h2 id="features">What can it do?</h2>
|
||||
|
||||
<h3 id="osc">Oscillators</h3>
|
||||
<h3 id="osc">Oscillators</h3>
|
||||
|
||||
<p>This synth offers 3 waveforms that can be played via the carrier oscillator: sine, square, saw. This oscillator can be modified using frequency modulation by using the modulator oscillator, which also offers sine, square, and saw waveforms. The modulator's pitch deviation from the carrier oscillator can be set, as well as its wet/dry mix.</p>
|
||||
<p>This synth offers 3 waveforms that can be played via the carrier oscillator: sine, square, saw. This oscillator can be modified using frequency modulation by using the modulator oscillator, which also offers sine, square, and saw waveforms. The modulator's pitch deviation from the carrier oscillator can be set, as well as its wet/dry mix.</p>
|
||||
|
||||
<h3 id="fx">Effects</h3>
|
||||
<h3 id="fx">Effects</h3>
|
||||
|
||||
<p>The synth has a flanger effect that can be enabled via a switch and tweaked using frequency, depth, and delay parameters. Distortion and sample reduction are also available.</p>
|
||||
<p>The synth has a flanger effect that can be enabled via a switch and tweaked using frequency, depth, and delay parameters. Distortion and sample reduction are also available.</p>
|
||||
|
||||
<h2 id="improvements">What could I have done better?</h2>
|
||||
<h2 id="improvements">What could I have done better?</h2>
|
||||
|
||||
<p>There are a few things I would add or do differently, if I was to create a second one of these:</p>
|
||||
<p>There are a few things I would add or do differently, if I was to create a second one of these:</p>
|
||||
|
||||
<p>The case has too few screw standoffs, which would result in the PCB flexing when buttons were pushed. I remedied this by gluing in some standoffs that lack screw holes, but it would of course be more ideal to model these into the actual case body. On that note, I would also add more screw holes in the PCB wherever possible, as the PCB didn't feature many holes, and the ones it did have were quite concentrated on the left side of the board.</p>
|
||||
<p>The case has too few screw standoffs, which would result in the PCB flexing when buttons were pushed. I remedied this by gluing in some standoffs that lack screw holes, but it would of course be more ideal to model these into the actual case body. On that note, I would also add more screw holes in the PCB wherever possible, as the PCB didn't feature many holes, and the ones it did have were quite concentrated on the left side of the board.</p>
|
||||
|
||||
<p>Some visual feedback would also be nice; a power LED could be nice. A display could have been even better, perhaps a small OLED display like <a href="https://www.reichelt.de/entwicklerboards-display-oled-0-96-128x64-pixel-blau-debo-oled5-0-96-p384685.html">this one</a>. It could have given feedback on individual parameters, such as a percentage on effects when the user turns a knob.</p>
|
||||
<p>Some visual feedback would also be nice; a power LED could be nice. A display could have been even better, perhaps a small OLED display like <a href="https://www.reichelt.de/entwicklerboards-display-oled-0-96-128x64-pixel-blau-debo-oled5-0-96-p384685.html">this one</a>. It could have given feedback on individual parameters, such as a percentage on effects when the user turns a knob.</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import type { DevlogPost } from "$lib/devlog-posts";
|
||||
import { posts } from "$lib/devlog-posts";
|
||||
</script>
|
||||
@@ -8,18 +9,19 @@
|
||||
<title>Project N5 Devlog | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5; Development Log" banner="/projects/projectn5/devlog/20240323/unity_overview.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5; Development Log" banner="/projects/projectn5/devlog/20240323/unity_overview.webp" />
|
||||
|
||||
<p>This is the development log for my game <strong>Project N5</strong>! It's an action-adventure jump-and-run game heavily inspired by games such as Ratchet & Clank. Development started on <b>2023-09-16</b>.</p>
|
||||
<p>This is the development log for my game <strong>Project N5</strong>! It's an action-adventure jump-and-run game heavily inspired by games such as Ratchet & Clank. Development started on <b>2023-09-16</b>.</p>
|
||||
|
||||
<p>2023 progress updates summarise an entire month's work, respectively. Progress updates thereafter denote noteworthy achievements in a more collected format.</p>
|
||||
|
||||
<div class="post-container">
|
||||
{#each posts as post}
|
||||
{@render devlogPost({post})}
|
||||
{/each}
|
||||
</div>
|
||||
<p>2023 progress updates summarise an entire month's work, respectively. Progress updates thereafter denote noteworthy achievements in a more collected format.</p>
|
||||
|
||||
<div class="post-container">
|
||||
{#each posts as post}
|
||||
{@render devlogPost({post})}
|
||||
{/each}
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
{#snippet devlogPost({post}: {post: DevlogPost})}
|
||||
<a href="/projects/projectn5/devlog/{post.date}/" class="post">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,90 +9,92 @@
|
||||
<title>2023-09 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-09" subtitle="" banner="/projects/projectn5/devlog/previews/202309.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-09" subtitle="" banner="/projects/projectn5/devlog/previews/202309.webp" />
|
||||
|
||||
<p>My progress in September 2023. Updates are shown in chronological order.</p>
|
||||
<p>My progress in September 2023. Updates are shown in chronological order.</p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<h2>One Small Step</h2>
|
||||
<p>A character has been added and the player can control them! It's influenced by gravity too, although it falls at an unnaturally rapid rate when thrown off the edge. This is because the downward velocity kept increasing even when grounded, and is fixed in a later version. Also, the character faces the wrong direction; moving forward results in the character facing the camera instead of forward. This is fixed once I replaced the character model with one where it's more obvious which side is forward.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_00.mp4" />
|
||||
<h2>One Small Step</h2>
|
||||
<p>A character has been added and the player can control them! It's influenced by gravity too, although it falls at an unnaturally rapid rate when thrown off the edge. This is because the downward velocity kept increasing even when grounded, and is fixed in a later version. Also, the character faces the wrong direction; moving forward results in the character facing the camera instead of forward. This is fixed once I replaced the character model with one where it's more obvious which side is forward.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_00.mp4" />
|
||||
|
||||
<h2>Gravity Functions As It Should</h2>
|
||||
<p>Gravity is fixed, and the camera angle has been adjusted, though not fixed to the character yet. It's kind of funny watching this little character move around.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_01.mp4" />
|
||||
<h2>Gravity Functions As It Should</h2>
|
||||
<p>Gravity is fixed, and the camera angle has been adjusted, though not fixed to the character yet. It's kind of funny watching this little character move around.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_01.mp4" />
|
||||
|
||||
<h2>Look Where You're Jumping!</h2>
|
||||
<p>The character can jump! Jump height is set unnaturally high as a test. The player can double jump, but only from a grounded state; falling off a cliff counts as the first jump, thus only allowing the player to jump once. Also, gravity is broken again. Also, a player-controllable camera! This was implemented with a custom third person camera plugin, which proved to be a bit jumpy.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_02.mp4" />
|
||||
<h2>Look Where You're Jumping!</h2>
|
||||
<p>The character can jump! Jump height is set unnaturally high as a test. The player can double jump, but only from a grounded state; falling off a cliff counts as the first jump, thus only allowing the player to jump once. Also, gravity is broken again. Also, a player-controllable camera! This was implemented with a custom third person camera plugin, which proved to be a bit jumpy.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_02.mp4" />
|
||||
|
||||
<h2>A Better Camera</h2>
|
||||
<p>The camera system has been replaced! This implementation simply uses <code>SpringArm3D</code> with a <code>Camera3D</code> as its child. This allows for the camera to not clip into walls (though it really likes clipping into the floor for some reason), and overall feels much more responsive. Not just that though – the player's movement input is now adjusted to where the camera points! When the player presses forward, they are now moving in the direction the camera is pointing. Previously, movement was independent from the camera's rotation, which of course wouldn't make sense for a game like this.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_03.mp4" />
|
||||
<h2>A Better Camera</h2>
|
||||
<p>The camera system has been replaced! This implementation simply uses <code>SpringArm3D</code> with a <code>Camera3D</code> as its child. This allows for the camera to not clip into walls (though it really likes clipping into the floor for some reason), and overall feels much more responsive. Not just that though – the player's movement input is now adjusted to where the camera points! When the player presses forward, they are now moving in the direction the camera is pointing. Previously, movement was independent from the camera's rotation, which of course wouldn't make sense for a game like this.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_03.mp4" />
|
||||
|
||||
<h2>Helicopter Ratchet</h2>
|
||||
<p>character go spinny</p>
|
||||
<p>The pause menu also makes a brief cameo! It's designed in a very simple way, and meant to replicate the pause menu from Ratchet & Clank 2002 while being legally distinct!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-23_00.mp4" />
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-23_01.webp">
|
||||
<h2>Helicopter Ratchet</h2>
|
||||
<p>character go spinny</p>
|
||||
<p>The pause menu also makes a brief cameo! It's designed in a very simple way, and meant to replicate the pause menu from Ratchet & Clank 2002 while being legally distinct!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-23_00.mp4" />
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-23_01.webp">
|
||||
|
||||
<h2>A Gun</h2>
|
||||
<p>The gun can shoot! Or can it? Well, the bullet doesn't exactly move…</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_00.mp4" />
|
||||
<p>Bullets have been converted into <code>RigidBody3D</code> which is great for collision but unfortunately initialises the bullets to be affected by gravity. Since the bullets are also parented to the player, it means that the fallen bullets move with the player. I don't think that's how guns are supposed to work.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_01.mp4" />
|
||||
<p>The gun now shoots properly! Not only do the bullets fly, but they fly in the correct direction as well! This is possible thanks to simple vector math, as the only thing needed to calculate a velocity vector for the bullet is to put two nodes on the gun, one at the front (where the bullet will fly from) and one further back, and calculate a vector between the two nodes!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_02.mp4" />
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-24_03.webp">
|
||||
<h2>A Gun</h2>
|
||||
<p>The gun can shoot! Or can it? Well, the bullet doesn't exactly move…</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_00.mp4" />
|
||||
<p>Bullets have been converted into <code>RigidBody3D</code> which is great for collision but unfortunately initialises the bullets to be affected by gravity. Since the bullets are also parented to the player, it means that the fallen bullets move with the player. I don't think that's how guns are supposed to work.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_01.mp4" />
|
||||
<p>The gun now shoots properly! Not only do the bullets fly, but they fly in the correct direction as well! This is possible thanks to simple vector math, as the only thing needed to calculate a velocity vector for the bullet is to put two nodes on the gun, one at the front (where the bullet will fly from) and one further back, and calculate a vector between the two nodes!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-24_02.mp4" />
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-24_03.webp">
|
||||
|
||||
<h2>Dialogue</h2>
|
||||
<p>The game now supports talking with NPCs. I only implemented this because I thought of something funny and I wanted to put it in the game.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-25.mp4" />
|
||||
<h2>Dialogue</h2>
|
||||
<p>The game now supports talking with NPCs. I only implemented this because I thought of something funny and I wanted to put it in the game.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-25.mp4" />
|
||||
|
||||
<h2>Conversation Camera</h2>
|
||||
<p>There's now a special camera angle for conversations with NPCs! Unfortunately, as the camera is bound to the player, and the player's position is unmodified when entering a conversation, this can result in blocking the NPC, or even facing a different direction entirely – how rude!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-28.mp4" />
|
||||
<h2>Conversation Camera</h2>
|
||||
<p>There's now a special camera angle for conversations with NPCs! Unfortunately, as the camera is bound to the player, and the player's position is unmodified when entering a conversation, this can result in blocking the NPC, or even facing a different direction entirely – how rude!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-28.mp4" />
|
||||
|
||||
<h2>Don't Waste Your Ammo!</h2>
|
||||
<p>Guns now have ammo counters! They can only fire for as long as they have ammunition left – as it should be. Unfortunately, unloading bullets unto Sans does nothing.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-29_00.mp4" />
|
||||
<h2>Don't Waste Your Ammo!</h2>
|
||||
<p>Guns now have ammo counters! They can only fire for as long as they have ammunition left – as it should be. Unfortunately, unloading bullets unto Sans does nothing.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-29_00.mp4" />
|
||||
|
||||
<h2>Smooth Player Movement</h2>
|
||||
<p>Using <code>lerp()</code> as well as <code>lerp_rotation()</code>, the player's movements are now smoother than before! The character rotates smoothly whenever pointing in a given direction and when strafing. Furthermore, the character now has a slight acceleration and deceleration in their movement.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-29_01.mp4" />
|
||||
<h2>Smooth Player Movement</h2>
|
||||
<p>Using <code>lerp()</code> as well as <code>lerp_rotation()</code>, the player's movements are now smoother than before! The character rotates smoothly whenever pointing in a given direction and when strafing. Furthermore, the character now has a slight acceleration and deceleration in their movement.</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-29_01.mp4" />
|
||||
|
||||
<h2>Language Options</h2>
|
||||
<p>The game now supports English and German as language options! Godot makes this very easy. All that's needed is to create a table with keys and the corresponding translations, export it as CSV, add them to the game (and don't forget to add the generated translation files in the project settings as well!), and then use <code>TranslationServer.setLocale(locale)</code> to set the language whenever needed – game defaults to English <code>en</code>. For UI elements, supplying the key in the text field suffices, and for strings in script, use <code>tr(key)</code>. Easy as that!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-30_00.mp4" />
|
||||
<h2>Language Options</h2>
|
||||
<p>The game now supports English and German as language options! Godot makes this very easy. All that's needed is to create a table with keys and the corresponding translations, export it as CSV, add them to the game (and don't forget to add the generated translation files in the project settings as well!), and then use <code>TranslationServer.setLocale(locale)</code> to set the language whenever needed – game defaults to English <code>en</code>. For UI elements, supplying the key in the text field suffices, and for strings in script, use <code>tr(key)</code>. Easy as that!</p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-30_00.mp4" />
|
||||
|
||||
<h2>Imposing dominance</h2> <!-- get it? -->
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-29.webp">
|
||||
<h2>Imposing dominance</h2> <!-- get it? -->
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-29.webp">
|
||||
|
||||
<h2>Learning to Model and Rig a Character</h2>
|
||||
<p>today's task: modelling and rigging a character from scratch</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_01.webp">
|
||||
<p>(Ratchet for scale)</p>
|
||||
<p>whaddya lookin at pinhead</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_02.webp">
|
||||
<p>is it a bird? is it a plane? no, it's arms</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_03.webp">
|
||||
<p>*Mii Maker theme intensifies*</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_04.webp">
|
||||
<p>feet are difficult</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_05.webp">
|
||||
<p>yoooo actually, not half bad</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_06.webp">
|
||||
<p>that one might hurt</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_07.webp">
|
||||
<p>we have a character!!</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_08.webp">
|
||||
<p><i>we've been rigged!</i></p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-30_09.mp4" />
|
||||
<p><code>we come in peace</code></p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_10.webp">
|
||||
<p>brief texture troubles</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_11.webp">
|
||||
<p>my character is now a playable character</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_12.webp">
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_13.webp">
|
||||
<h2>Learning to Model and Rig a Character</h2>
|
||||
<p>today's task: modelling and rigging a character from scratch</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_01.webp">
|
||||
<p>(Ratchet for scale)</p>
|
||||
<p>whaddya lookin at pinhead</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_02.webp">
|
||||
<p>is it a bird? is it a plane? no, it's arms</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_03.webp">
|
||||
<p>*Mii Maker theme intensifies*</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_04.webp">
|
||||
<p>feet are difficult</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_05.webp">
|
||||
<p>yoooo actually, not half bad</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_06.webp">
|
||||
<p>that one might hurt</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_07.webp">
|
||||
<p>we have a character!!</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_08.webp">
|
||||
<p><i>we've been rigged!</i></p>
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-30_09.mp4" />
|
||||
<p><code>we come in peace</code></p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_10.webp">
|
||||
<p>brief texture troubles</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_11.webp">
|
||||
<p>my character is now a playable character</p>
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_12.webp">
|
||||
<img src="/projects/projectn5/devlog/202309/2023-09-30_13.webp">
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,59 +9,61 @@
|
||||
<title>2023-10 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-10" subtitle="" banner="/projects/projectn5/devlog/previews/202310.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-10" subtitle="" banner="/projects/projectn5/devlog/previews/202310.webp" />
|
||||
|
||||
<p>My progress in October 2023. Updates are shown in chronological order.</p>
|
||||
<p>My progress in October 2023. Updates are shown in chronological order.</p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<h2>Implementing RigidBody3D Character Movement</h2>
|
||||
<p>Today's task: reimplementing my player character as a <code>RigidBody3D</code>. In the example below, it is using <code>CharacterController3D</code>. I wanted to make this change to get more natural feeling movement and physics, particularly in carrying momentum.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_00.mp4" />
|
||||
<p>oops i've had a bit of a tumble</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_01.mp4" />
|
||||
<p>This is the result of the <code>RigidBody3D</code> implementation in my character. I used a script from the following video, which served as a great base – the only good one I could find, in fact. Most people on the internet seem to want others to use <code>CharacterController3D</code>, and for good reasons; it's simple, it works, and it's easy to adjust and tweak, unlike a <code>RigidBody3D</code>. And so I had to admit: I wasn't happy with my implementation. I changed the script in large parts, only keeping a few segments, but it never felt quite like I wanted to. It felt too loose.</p>
|
||||
<p><a href="https://www.youtube.com/watch?v=ZLTYlZgZc-0&t=986s">Godot 4.0: I solved my CharacterBody3d issues by using RigidBody3d for character movement!</a></p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_02.mp4" />
|
||||
<p><code>RigidBody3D</code> also greeted me with some bugs I had encountered in Unity but was initially spared from when I switched to Godot and its <code>CharacterController3D</code> implementation. A significant issue was the double jump; the character would often not be able to recognise that it had been grounded, and thus it would not allow the player to jump again. Another issue was glitching; the video shows how the character sinks into the ground briefly before jumping up. I have no idea why this happened.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_03.mp4" />
|
||||
<p>Using a momentum-based character also introduces the issue of sliding up slopes and ramps with the carried momentum a little more than I would like.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_04.mp4" />
|
||||
<p>And so, after 10 hours of implementing RigidBody3D, I decided to go back to CharacterController3D. I played a bit of Ratchet & Clank for reference, and decided that they might be using a <code>RigidBody</code> implementation (did a <code>CharacterController</code> even exist back then? Did their engine support that even?), but I could get closer to their movement more easily using a <code>CharacterController</code> and emulating a few momentum-based movements using <code>lerp</code>s.</p>
|
||||
<p>The effort was not in vain, however! I implemented the ground <code>RayCast</code> that was necessary for my <code>RigidBody3D</code> implementation in my <code>CharacterController</code>, which, together with a plane calculation, allows for adjusting the character movement velocity when moving on slopes! This corrects the player's uphill speed, and it also prevents jumpy movement when running down a slope! It's currently a little glitch-prone though, crashing the game when standing on Sans, for example, but I'll fix that soon.</p>
|
||||
<h2>Healthy</h2>
|
||||
<p>We now have health points! As it is currently set up, the health bar supports up to 8 health points. For testing purposes, I set up the melee attack to drain health, and the gunshot to heal the player.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-07_00.mp4" />
|
||||
<p>The health bar even aligns properly for 5 and 6 max health points, reducing the max points displayed per line from 4 to 3!</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-07_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-07_02.webp">
|
||||
</div>
|
||||
<h2>Implementing RigidBody3D Character Movement</h2>
|
||||
<p>Today's task: reimplementing my player character as a <code>RigidBody3D</code>. In the example below, it is using <code>CharacterController3D</code>. I wanted to make this change to get more natural feeling movement and physics, particularly in carrying momentum.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_00.mp4" />
|
||||
<p>oops i've had a bit of a tumble</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_01.mp4" />
|
||||
<p>This is the result of the <code>RigidBody3D</code> implementation in my character. I used a script from the following video, which served as a great base – the only good one I could find, in fact. Most people on the internet seem to want others to use <code>CharacterController3D</code>, and for good reasons; it's simple, it works, and it's easy to adjust and tweak, unlike a <code>RigidBody3D</code>. And so I had to admit: I wasn't happy with my implementation. I changed the script in large parts, only keeping a few segments, but it never felt quite like I wanted to. It felt too loose.</p>
|
||||
<p><a href="https://www.youtube.com/watch?v=ZLTYlZgZc-0&t=986s">Godot 4.0: I solved my CharacterBody3d issues by using RigidBody3d for character movement!</a></p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_02.mp4" />
|
||||
<p><code>RigidBody3D</code> also greeted me with some bugs I had encountered in Unity but was initially spared from when I switched to Godot and its <code>CharacterController3D</code> implementation. A significant issue was the double jump; the character would often not be able to recognise that it had been grounded, and thus it would not allow the player to jump again. Another issue was glitching; the video shows how the character sinks into the ground briefly before jumping up. I have no idea why this happened.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_03.mp4" />
|
||||
<p>Using a momentum-based character also introduces the issue of sliding up slopes and ramps with the carried momentum a little more than I would like.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-03_04.mp4" />
|
||||
<p>And so, after 10 hours of implementing RigidBody3D, I decided to go back to CharacterController3D. I played a bit of Ratchet & Clank for reference, and decided that they might be using a <code>RigidBody</code> implementation (did a <code>CharacterController</code> even exist back then? Did their engine support that even?), but I could get closer to their movement more easily using a <code>CharacterController</code> and emulating a few momentum-based movements using <code>lerp</code>s.</p>
|
||||
<p>The effort was not in vain, however! I implemented the ground <code>RayCast</code> that was necessary for my <code>RigidBody3D</code> implementation in my <code>CharacterController</code>, which, together with a plane calculation, allows for adjusting the character movement velocity when moving on slopes! This corrects the player's uphill speed, and it also prevents jumpy movement when running down a slope! It's currently a little glitch-prone though, crashing the game when standing on Sans, for example, but I'll fix that soon.</p>
|
||||
<h2>Healthy</h2>
|
||||
<p>We now have health points! As it is currently set up, the health bar supports up to 8 health points. For testing purposes, I set up the melee attack to drain health, and the gunshot to heal the player.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-07_00.mp4" />
|
||||
<p>The health bar even aligns properly for 5 and 6 max health points, reducing the max points displayed per line from 4 to 3!</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-07_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-07_02.webp">
|
||||
</div>
|
||||
|
||||
<h2>What Are the Controls??</h2>
|
||||
<p>We have a controls screen! This task would have been easier if the game was specific to a console, thus necessitating only one controller layout. Instead, I used Godot's <code>Input.get_joy_name()</code> function to retrieve the first connected controller's name, and use that to display an appropriate screen. Current options are PlayStation (DualSense), Xbox (Series X/S), and Nintendo (Switch Pro Con). Keyboard/Mouse layout will follow soon(ish).</p>
|
||||
<p>Specifying controller layouts for different controllers is difficult though, since I don't know the controller's names (I currently only have the following strings: “PS5 Controller”, “XInput Gamepad” (through emulation using DS4Windows), and “Nintendo Switch Pro Controller”).</p>
|
||||
<p>Another difficulty is figuring out which controller layout to show if multiple controllers are connected, or when KBM is used even though a controller is connected. I currently check for the first connected controller, which means that, if multiple controllers are connected, the layout shown may be wrong. Furthermore, connecting a controller always overrides the KBM layout, since KBM is currently the default. A solution to this may be to check which controller last sent an input, and retrieving that controller's name.</p>
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_00.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_02.webp">
|
||||
<h2>What Are the Controls??</h2>
|
||||
<p>We have a controls screen! This task would have been easier if the game was specific to a console, thus necessitating only one controller layout. Instead, I used Godot's <code>Input.get_joy_name()</code> function to retrieve the first connected controller's name, and use that to display an appropriate screen. Current options are PlayStation (DualSense), Xbox (Series X/S), and Nintendo (Switch Pro Con). Keyboard/Mouse layout will follow soon(ish).</p>
|
||||
<p>Specifying controller layouts for different controllers is difficult though, since I don't know the controller's names (I currently only have the following strings: “PS5 Controller”, “XInput Gamepad” (through emulation using DS4Windows), and “Nintendo Switch Pro Controller”).</p>
|
||||
<p>Another difficulty is figuring out which controller layout to show if multiple controllers are connected, or when KBM is used even though a controller is connected. I currently check for the first connected controller, which means that, if multiple controllers are connected, the layout shown may be wrong. Furthermore, connecting a controller always overrides the KBM layout, since KBM is currently the default. A solution to this may be to check which controller last sent an input, and retrieving that controller's name.</p>
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_00.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-10_02.webp">
|
||||
|
||||
<h2>Quick Select</h2>
|
||||
<p>I've done some work on the quick select menu to get it functional. The goal is to emulate its behaviour in the Ratchet & Clank games (duh). Current functionality is as follows:</p>
|
||||
<p>The Quick Select menu opens when the E key (keyboard) or the North face button (controller) is pressed, and closes once the button is released. Using the Keyboard/Mouse control layout, the player is able to pick a weapon by hovering over it. The focussed weapon is equipped once the Quick Select menu is closed. Controller users point the left stick in the desired direction to focus on an item.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-14.mp4" />
|
||||
<h2>Quick Select</h2>
|
||||
<p>I've done some work on the quick select menu to get it functional. The goal is to emulate its behaviour in the Ratchet & Clank games (duh). Current functionality is as follows:</p>
|
||||
<p>The Quick Select menu opens when the E key (keyboard) or the North face button (controller) is pressed, and closes once the button is released. Using the Keyboard/Mouse control layout, the player is able to pick a weapon by hovering over it. The focussed weapon is equipped once the Quick Select menu is closed. Controller users point the left stick in the desired direction to focus on an item.</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-14.mp4" />
|
||||
|
||||
<h2>Heavy Weaponry</h2>
|
||||
<p>In order to get started with the 3D models I'll need to create for the game, I attempted to begin the process of modelling the weapon of the protagonist! It's supposed to become a battle axe, though I have not yet finalised whether I'll keep with the idea.</p>
|
||||
<div class="horizontally-centre-aligned width-restricted">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_02.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_04.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_05.webp">
|
||||
</div>
|
||||
<h2>Heavy Weaponry</h2>
|
||||
<p>In order to get started with the 3D models I'll need to create for the game, I attempted to begin the process of modelling the weapon of the protagonist! It's supposed to become a battle axe, though I have not yet finalised whether I'll keep with the idea.</p>
|
||||
<div class="horizontally-centre-aligned width-restricted">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_02.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_04.webp">
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-22_05.webp">
|
||||
</div>
|
||||
|
||||
<h2>Hot, Fresh Quality</h2>
|
||||
<p>In order to test animation and rigging of arbitrary 3D models, I created these bread-centred animations. This obsession with toast came to me after a friend of mine and I took a test that determined <a href="https://www.buzzfeed.com/mathewguiver/which-type-of-bread-are-you">which type of bread we are</a>. Despite vastly different answers, our end results were both 'vegan biscuit.'</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-25_00.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-25_01.mp4" />
|
||||
<p>I like my bread with bones, <i>thank you very much.</i></p>
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-25_02.webp">
|
||||
<h2>Hot, Fresh Quality</h2>
|
||||
<p>In order to test animation and rigging of arbitrary 3D models, I created these bread-centred animations. This obsession with toast came to me after a friend of mine and I took a test that determined <a href="https://www.buzzfeed.com/mathewguiver/which-type-of-bread-are-you">which type of bread we are</a>. Despite vastly different answers, our end results were both 'vegan biscuit.'</p>
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-25_00.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/202310/2023-10-25_01.mp4" />
|
||||
<p>I like my bread with bones, <i>thank you very much.</i></p>
|
||||
<img src="/projects/projectn5/devlog/202310/2023-10-25_02.webp">
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,64 +9,66 @@
|
||||
<title>2023-11 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-11" subtitle="" banner="/projects/projectn5/devlog/previews/202311.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-11" subtitle="" banner="/projects/projectn5/devlog/previews/202311.webp" />
|
||||
|
||||
<p>My progress in November 2023. Updates are shown in chronological order.</p>
|
||||
<p>My progress in November 2023. Updates are shown in chronological order.</p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<h2>Gearing Up</h2>
|
||||
<p>Lots of progress on the 3D models! I modelled the first weapon for the game, the N5 Blaster, from start to finish!</p>
|
||||
<p>The earliest version was based on an 8-sided cylinder. After some feedback from friends, I remade the weapon, using a 16-sided cylinder, and also adding more details to the weapon overall. More attention went into the grip, which now resembled a weapon grip more so than a stick.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-05_00.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-03_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-05_03.webp">
|
||||
</div>
|
||||
<p>Here's an overview of the first model.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-03_00.mp4" />
|
||||
<p>The final version of the weapon layers a black wireframe on top of the icosphere, so that in the game it's a bit more clearly visible that it rotates, and it uses smooth shading. I was against using smooth shading initially, as I wanted to go for a low-poly artstyle, but I think that approach just looked a bit cheap, considering my 3D models aren't exactly high-quality by themselves. Smooth shading gives the impression of smooth, high-poly models at a significant reduction in vertices.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-12-11.webp">
|
||||
<p>Here's the icon for the N5 Blaster that's to be used in the quick select menu, the item menu, and the HUD. The icon will be tinted in different colours when the weapon has been levelled up.</p>
|
||||
<p>In my first attempt at creating this icon, I took a picture of the wireframed icosphere that's in the weapon, and I tried to vectorise it using Inkscape. That didn't work the way I wanted, so I hand-traced all the lines from the icosphere. I was confused as to why it's not symmetrical, but I later realised that that's just how the icosphere looks.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/n5blaster_icon.webp">
|
||||
<p>I also continued work on the battle axe, giving it more character. It's still not close to being finished, but it's now a bit less of a rough draft.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_06.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_09.webp">
|
||||
</div>
|
||||
<p>I will admit though that I'm unsure whether I'll actually stick with the battle axe as the protagonist's main melee weapon.</p>
|
||||
<p>Another idea, though more as an unlockable extra, is Derek the crowbar.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-06_02.webp">
|
||||
<p>I also worked on the upgrade for the N5 Blaster, the N5 Cannon. Progress on that one has been a bit slow, since I have yet to figure out what kind of weapon I want the upgraded version to be.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_04.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_02.webp">
|
||||
</div>
|
||||
<p>And, as a bonus, here's the discarded, very-early-WIP draft I created for a rifle-type weapon. I don't think this type of weapon fits the type of game I'm making.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_00.webp">
|
||||
<p>And a draft of a rocket launcher with 9 barrels! This is heavily inspired by the <a href="https://ratchetandclank.fandom.com/wiki/R.Y.N.O._(2002_game)">R.Y.N.O. from Ratchet & Clank</a>. It's coloured blue because I was investigating issues with the mesh's normals at the time.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-02_01.webp">
|
||||
<h2>Gearing Up</h2>
|
||||
<p>Lots of progress on the 3D models! I modelled the first weapon for the game, the N5 Blaster, from start to finish!</p>
|
||||
<p>The earliest version was based on an 8-sided cylinder. After some feedback from friends, I remade the weapon, using a 16-sided cylinder, and also adding more details to the weapon overall. More attention went into the grip, which now resembled a weapon grip more so than a stick.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-05_00.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-03_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-05_03.webp">
|
||||
</div>
|
||||
<p>Here's an overview of the first model.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-03_00.mp4" />
|
||||
<p>The final version of the weapon layers a black wireframe on top of the icosphere, so that in the game it's a bit more clearly visible that it rotates, and it uses smooth shading. I was against using smooth shading initially, as I wanted to go for a low-poly artstyle, but I think that approach just looked a bit cheap, considering my 3D models aren't exactly high-quality by themselves. Smooth shading gives the impression of smooth, high-poly models at a significant reduction in vertices.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-12-11.webp">
|
||||
<p>Here's the icon for the N5 Blaster that's to be used in the quick select menu, the item menu, and the HUD. The icon will be tinted in different colours when the weapon has been levelled up.</p>
|
||||
<p>In my first attempt at creating this icon, I took a picture of the wireframed icosphere that's in the weapon, and I tried to vectorise it using Inkscape. That didn't work the way I wanted, so I hand-traced all the lines from the icosphere. I was confused as to why it's not symmetrical, but I later realised that that's just how the icosphere looks.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/n5blaster_icon.webp">
|
||||
<p>I also continued work on the battle axe, giving it more character. It's still not close to being finished, but it's now a bit less of a rough draft.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_01.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_06.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-01_09.webp">
|
||||
</div>
|
||||
<p>I will admit though that I'm unsure whether I'll actually stick with the battle axe as the protagonist's main melee weapon.</p>
|
||||
<p>Another idea, though more as an unlockable extra, is Derek the crowbar.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-06_02.webp">
|
||||
<p>I also worked on the upgrade for the N5 Blaster, the N5 Cannon. Progress on that one has been a bit slow, since I have yet to figure out what kind of weapon I want the upgraded version to be.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_04.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_02.webp">
|
||||
</div>
|
||||
<p>And, as a bonus, here's the discarded, very-early-WIP draft I created for a rifle-type weapon. I don't think this type of weapon fits the type of game I'm making.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_00.webp">
|
||||
<p>And a draft of a rocket launcher with 9 barrels! This is heavily inspired by the <a href="https://ratchetandclank.fandom.com/wiki/R.Y.N.O._(2002_game)">R.Y.N.O. from Ratchet & Clank</a>. It's coloured blue because I was investigating issues with the mesh's normals at the time.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-02_01.webp">
|
||||
|
||||
<h2>A Star is Born</h2>
|
||||
<p>I begun modelling my protagonist! I didn't progress far, as I currently lack a vision for where I really want my character to go in detail. I have slight ideas – inspirations are, for example, <a href="https://hero.fandom.com/wiki/Merc_and_Green">Merc & Green from Ratchet: Gladiator</a>, and <a href="/projects/projectn5/devlog/202311/denholm.webp">Denholm Reynholm</a>. I quite liked the idea of having glowing tubes on the character's back; I got the inspiration from a Blender tutorial that was randomly recommended to me one morning.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-11_05.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_01.webp">
|
||||
</div>
|
||||
<p>i love</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-11_09.mp4" />
|
||||
<h2>A Star is Born</h2>
|
||||
<p>I begun modelling my protagonist! I didn't progress far, as I currently lack a vision for where I really want my character to go in detail. I have slight ideas – inspirations are, for example, <a href="https://hero.fandom.com/wiki/Merc_and_Green">Merc & Green from Ratchet: Gladiator</a>, and <a href="/projects/projectn5/devlog/202311/denholm.webp">Denholm Reynholm</a>. I quite liked the idea of having glowing tubes on the character's back; I got the inspiration from a Blender tutorial that was randomly recommended to me one morning.</p>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-11_05.webp">
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-12_01.webp">
|
||||
</div>
|
||||
<p>i love</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-11_09.mp4" />
|
||||
|
||||
<h2>Real-World Testing</h2>
|
||||
<p>On a whim, I decided to import the N5 Blaster's model into my game. Doing that was honestly quite the motivational boost at the time, as it visualised my progress. I could actually play <i>my game</i> with <i>my weapon!</i> It's not finished at all, it has no proper mechanics implemented other than the shooting copied from the Purple Gun, and the glass is also not actually transparent.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-21.mp4" />
|
||||
<h2>Real-World Testing</h2>
|
||||
<p>On a whim, I decided to import the N5 Blaster's model into my game. Doing that was honestly quite the motivational boost at the time, as it visualised my progress. I could actually play <i>my game</i> with <i>my weapon!</i> It's not finished at all, it has no proper mechanics implemented other than the shooting copied from the Purple Gun, and the glass is also not actually transparent.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-21.mp4" />
|
||||
|
||||
<h2>Inventory System</h2>
|
||||
<p>I implemented an inventory system somewhat akin to Ratchet & Clank's. It shows the weapons the player has acquired, previewing the model in a 3D sub-viewport. Later, it will also show the weapon's name, remaining ammo, perhaps statistics such as damage, and a description. But that's a task for later.</p>
|
||||
<p>The only reason that the Purple Gun as well as the N5 Blaster show up multiple times is because I wanted to test all inventory slots, and I didn't have any weapons other than those two implemented.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-24.mp4" />
|
||||
<h2>Inventory System</h2>
|
||||
<p>I implemented an inventory system somewhat akin to Ratchet & Clank's. It shows the weapons the player has acquired, previewing the model in a 3D sub-viewport. Later, it will also show the weapon's name, remaining ammo, perhaps statistics such as damage, and a description. But that's a task for later.</p>
|
||||
<p>The only reason that the Purple Gun as well as the N5 Blaster show up multiple times is because I wanted to test all inventory slots, and I didn't have any weapons other than those two implemented.</p>
|
||||
<Video src="/projects/projectn5/devlog/202311/2023-11-24.mp4" />
|
||||
|
||||
<h2>My Best Friend JSON</h2>
|
||||
<p>It might seem simple (or look complicated), but I came up with the idea of creating a JSON-based lookup table for the weapon metadata. Using this, it's quite easy to retrieve any kind of information about any kind of weapon without needing to hardcode it into the weapon itself. Here's an early screenshot of the lookup table.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-25.webp">
|
||||
<h2>My Best Friend JSON</h2>
|
||||
<p>It might seem simple (or look complicated), but I came up with the idea of creating a JSON-based lookup table for the weapon metadata. Using this, it's quite easy to retrieve any kind of information about any kind of weapon without needing to hardcode it into the weapon itself. Here's an early screenshot of the lookup table.</p>
|
||||
<img src="/projects/projectn5/devlog/202311/2023-11-25.webp">
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,62 +9,64 @@
|
||||
<title>2023-12 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-12" subtitle="" banner="/projects/projectn5/devlog/previews/202312.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2023-12" subtitle="" banner="/projects/projectn5/devlog/previews/202312.webp" />
|
||||
|
||||
<p>My progress in December 2023. Updates are shown in chronological order.</p>
|
||||
<p>My progress in December 2023. Updates are shown in chronological order.</p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<h2>Identity Crisis</h2>
|
||||
<p>I started creating a logo for my game! I settled on the name <b>Project N5</b> as a working title, and perhaps as a final title for the game as well. Here's all the logos I created thus far:</p>
|
||||
<p>Logo #0 is just an outline using <a href="https://fonts.google.com/specimen/Kanit">Kanit</a>. This is the font I also decided on for all of the in-game menus and text. The 5 is special though; it is based on a part salvaged from a hard drive. On a slow day, my coworker disassembled some defective mechanical hard drives, and I got to keep the parts. I thought it would look quite cool as a highlight for the game's logo, and perhaps function as a part of the in-game antagonist company that I'm planning to write the story around.</p>
|
||||
<img class="image-block centred width-restricted light-background" src="/projects/projectn5/devlog/202312/projectn5-logo-outline.webp">
|
||||
<img src="/projects/projectn5/devlog/202312/hdd.webp">
|
||||
<p>Logo #1 gained a fill, wider stroke, and a pattern fill that's straight outta Inkscape.</p>
|
||||
<img class="image-block centred width-restricted light-background" src="/projects/projectn5/devlog/202312/projectn5-logo-fill-v1.webp">
|
||||
<p>#2 reserves the pattern fill for the N5 part and colours the 5 in the game's main yellow colour, #D4AB49. It's also much thicker.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v2.webp">
|
||||
<p>Version 3 is a complete overhaul, still using Kanit for the N, keeping the custom 5, but changing the font of the word 'Project' to <a href="https://www.collletttivo.it/typefaces/apfel-grotezk">Apfel Grotezk</a>. Unfortunately, that font doesn't really work well in all-caps. The J just stood out too poorly for my liking, and friends confirmed it.</p>
|
||||
<p>The hexagonal background behind the N5 actually was a fairly random addition, but I liked it so much that it continued to stick. I think this could also serve as part of the player's HUD. Maybe as an element that shows the level of the currently equipped weapon? I love when ideas sprout from random decisions like this!</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v3.webp">
|
||||
<p>I also tried <a href="https://fonts.google.com/specimen/Lato">Lato</a>, but that looked too standard, and not quite as expressive as I wanted it to. Relatively speaking, considering we're talking about regular sans-serif fonts, of course.</p>
|
||||
<p>A friend also suggested I cut apart the top part of the 5, leaving a gap, and I think that looked quite cool! I continued that trend for the HDD-inspired bits on the lower part of the 5, simplifying them, detaching them from the main bottom part, and even removing one element. The element that was removed actually served as the part that sticks out in the upper part of the lower part – if that makes sense. It's now located near the cutting point between the upper and lower parts of the digit.</p>
|
||||
<p>I also tore apart the N on my own volition. Thought it looked cool.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v4.webp">
|
||||
<p>This logo uses <a href="https://fonts.google.com/specimen/Montserrat">Monserrat ExtraBold</a>. I actually quite liked this font; it looked unified, bold, and actually quite fitting for my vision!</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v5.webp">
|
||||
<p>Then I inset the C into the T, creating a neat little cutout effect.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v6.webp">
|
||||
<p>I then decided to put a splash of colour behind the 'Project' wordmark, and highlighting the background with two hexagons.</p>
|
||||
<p>Do you think the comment is right? I'm unsure. Amongst all the people I've shown this logo to, the decision has been split 50/50. I just don't want people to consider this the 'dick logo.'</p>
|
||||
<p>I've also received comments from some people who are irked by the T in 'Project' overlapping with the background of the N5. I actually quite like that feature, but I'll take it into consideration, and maybe change it in the near future.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v7.webp">
|
||||
<p>And lastly, a little draft logo I created, based on #7, in <a href="https://www.getpaint.net/">Paint.net</a>, which is why it doesn't look as clean as the other ones, which are all vector-based logos created in Inkscape.</p>
|
||||
<p>I want my work to be transferrable and easily scale-able after all, you know?</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v7-sketch.webp">
|
||||
<h2>Identity Crisis</h2>
|
||||
<p>I started creating a logo for my game! I settled on the name <b>Project N5</b> as a working title, and perhaps as a final title for the game as well. Here's all the logos I created thus far:</p>
|
||||
<p>Logo #0 is just an outline using <a href="https://fonts.google.com/specimen/Kanit">Kanit</a>. This is the font I also decided on for all of the in-game menus and text. The 5 is special though; it is based on a part salvaged from a hard drive. On a slow day, my coworker disassembled some defective mechanical hard drives, and I got to keep the parts. I thought it would look quite cool as a highlight for the game's logo, and perhaps function as a part of the in-game antagonist company that I'm planning to write the story around.</p>
|
||||
<img class="image-block centred width-restricted light-background" src="/projects/projectn5/devlog/202312/projectn5-logo-outline.webp">
|
||||
<img src="/projects/projectn5/devlog/202312/hdd.webp">
|
||||
<p>Logo #1 gained a fill, wider stroke, and a pattern fill that's straight outta Inkscape.</p>
|
||||
<img class="image-block centred width-restricted light-background" src="/projects/projectn5/devlog/202312/projectn5-logo-fill-v1.webp">
|
||||
<p>#2 reserves the pattern fill for the N5 part and colours the 5 in the game's main yellow colour, #D4AB49. It's also much thicker.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v2.webp">
|
||||
<p>Version 3 is a complete overhaul, still using Kanit for the N, keeping the custom 5, but changing the font of the word 'Project' to <a href="https://www.collletttivo.it/typefaces/apfel-grotezk">Apfel Grotezk</a>. Unfortunately, that font doesn't really work well in all-caps. The J just stood out too poorly for my liking, and friends confirmed it.</p>
|
||||
<p>The hexagonal background behind the N5 actually was a fairly random addition, but I liked it so much that it continued to stick. I think this could also serve as part of the player's HUD. Maybe as an element that shows the level of the currently equipped weapon? I love when ideas sprout from random decisions like this!</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v3.webp">
|
||||
<p>I also tried <a href="https://fonts.google.com/specimen/Lato">Lato</a>, but that looked too standard, and not quite as expressive as I wanted it to. Relatively speaking, considering we're talking about regular sans-serif fonts, of course.</p>
|
||||
<p>A friend also suggested I cut apart the top part of the 5, leaving a gap, and I think that looked quite cool! I continued that trend for the HDD-inspired bits on the lower part of the 5, simplifying them, detaching them from the main bottom part, and even removing one element. The element that was removed actually served as the part that sticks out in the upper part of the lower part – if that makes sense. It's now located near the cutting point between the upper and lower parts of the digit.</p>
|
||||
<p>I also tore apart the N on my own volition. Thought it looked cool.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v4.webp">
|
||||
<p>This logo uses <a href="https://fonts.google.com/specimen/Montserrat">Monserrat ExtraBold</a>. I actually quite liked this font; it looked unified, bold, and actually quite fitting for my vision!</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v5.webp">
|
||||
<p>Then I inset the C into the T, creating a neat little cutout effect.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v6.webp">
|
||||
<p>I then decided to put a splash of colour behind the 'Project' wordmark, and highlighting the background with two hexagons.</p>
|
||||
<p>Do you think the comment is right? I'm unsure. Amongst all the people I've shown this logo to, the decision has been split 50/50. I just don't want people to consider this the 'dick logo.'</p>
|
||||
<p>I've also received comments from some people who are irked by the T in 'Project' overlapping with the background of the N5. I actually quite like that feature, but I'll take it into consideration, and maybe change it in the near future.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v7.webp">
|
||||
<p>And lastly, a little draft logo I created, based on #7, in <a href="https://www.getpaint.net/">Paint.net</a>, which is why it doesn't look as clean as the other ones, which are all vector-based logos created in Inkscape.</p>
|
||||
<p>I want my work to be transferrable and easily scale-able after all, you know?</p>
|
||||
<img src="/projects/projectn5/devlog/202312/projectn5-logo-v7-sketch.webp">
|
||||
|
||||
<h2>Glowing Weaponry</h2>
|
||||
<p>I was struggling for SO LONG to get this weapon to glow. Using a <code>WorldEnvironment</code> node just wouldn't work, the weapon never glowed. Then, I figured out that, at some point, I disabled glow in the entire scene... and after changing that – and trying other things for 1.5 hours before that point – the weapon was glowing! Not quite the way I want it to, but that's easy to tweak. Only downside is that my character started glowing as well, for some reason, but I'll figure that out another time.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-08.webp">
|
||||
<h2>Glowing Weaponry</h2>
|
||||
<p>I was struggling for SO LONG to get this weapon to glow. Using a <code>WorldEnvironment</code> node just wouldn't work, the weapon never glowed. Then, I figured out that, at some point, I disabled glow in the entire scene... and after changing that – and trying other things for 1.5 hours before that point – the weapon was glowing! Not quite the way I want it to, but that's easy to tweak. Only downside is that my character started glowing as well, for some reason, but I'll figure that out another time.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-08.webp">
|
||||
|
||||
<h2>Character II</h2>
|
||||
<p>For testing animations, I created a new rigged character. This character is segmented, using separate objects for its arms, fingers, legs, etc. The final protagonist will use completely separate objects, since the character will be a robot. This will also reduce the work I will need to do in weight painting, and make mesh bends trivial – which is to say, not necessary.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-12_00.webp">
|
||||
<p>Rigging remains as difficult as ever. The final model – which won't be based on this model but use a similar rig, hopefully the same so that animations can be carried over 1:1 – will have separate segments for the fingers, so that bends like this will never occur.</p>
|
||||
<p>Notice that the character only has four fingers per hand. This should reduce animation work somewhat. Also, I came to realise – why even put five fingers on a robot? It's not like we as humans even utilise our five fingers very efficiently. I've found myself struggling to keep my pinky out of my way countless times.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/2023-12-12_01.mp4" />
|
||||
<p><code>hello world! nice to meet you</code></p>
|
||||
<p>This uses 1-frame animations to achieve posing. My first attempt at using animations in Godot! Worked really well, actually. All I fear now is playing multiple animations at once. Is that even possible? I don't know yet.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/2023-12-12_02.mp4" />
|
||||
<p>And finally, a shot of the character holding the weapon correctly. This was actually super easy to achieve. The weapon is parented to a node that's attached to the right hand bone of the model. This makes posing and animations loads easier, since the equipped item does not have to be moved manually.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-12_03.webp">
|
||||
<h2>Character II</h2>
|
||||
<p>For testing animations, I created a new rigged character. This character is segmented, using separate objects for its arms, fingers, legs, etc. The final protagonist will use completely separate objects, since the character will be a robot. This will also reduce the work I will need to do in weight painting, and make mesh bends trivial – which is to say, not necessary.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-12_00.webp">
|
||||
<p>Rigging remains as difficult as ever. The final model – which won't be based on this model but use a similar rig, hopefully the same so that animations can be carried over 1:1 – will have separate segments for the fingers, so that bends like this will never occur.</p>
|
||||
<p>Notice that the character only has four fingers per hand. This should reduce animation work somewhat. Also, I came to realise – why even put five fingers on a robot? It's not like we as humans even utilise our five fingers very efficiently. I've found myself struggling to keep my pinky out of my way countless times.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/2023-12-12_01.mp4" />
|
||||
<p><code>hello world! nice to meet you</code></p>
|
||||
<p>This uses 1-frame animations to achieve posing. My first attempt at using animations in Godot! Worked really well, actually. All I fear now is playing multiple animations at once. Is that even possible? I don't know yet.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/2023-12-12_02.mp4" />
|
||||
<p>And finally, a shot of the character holding the weapon correctly. This was actually super easy to achieve. The weapon is parented to a node that's attached to the right hand bone of the model. This makes posing and animations loads easier, since the equipped item does not have to be moved manually.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/2023-12-12_03.webp">
|
||||
|
||||
<h2>Worldbuilding – Toasters</h2>
|
||||
<p>Adapted from the early animations, I present: Deniz' Quality Toasters! A fictitious toaster manufacturing company bearing my name – maybe they manufacture more than just toasters? The logo is using the font <a href="https://fonts.google.com/specimen/Pacifico">Pacifico</a>.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/dqt.webp">
|
||||
<p>I don't actually know whether I'll use this in any way, I just wanted to create this logo for the sake of it.</p>
|
||||
<h2>Worldbuilding – Toasters</h2>
|
||||
<p>Adapted from the early animations, I present: Deniz' Quality Toasters! A fictitious toaster manufacturing company bearing my name – maybe they manufacture more than just toasters? The logo is using the font <a href="https://fonts.google.com/specimen/Pacifico">Pacifico</a>.</p>
|
||||
<img src="/projects/projectn5/devlog/202312/dqt.webp">
|
||||
<p>I don't actually know whether I'll use this in any way, I just wanted to create this logo for the sake of it.</p>
|
||||
|
||||
<h2>Simultaneous Animations</h2>
|
||||
<p>I managed to implement the ability to play multiple animations at a time! The character can now walk + point its gun, or keep its arms down. There's no animation for standing still yet, so it perpetually walks, but this is huge progress, and more importantly, a huge fear of mine alleviated! I was really concerned that implementing multiple animations would be a tedious task, but with Godot's <code>AnimationTree</code> node, it's actually rather trivial.</p>
|
||||
<p>I followed <a href="https://www.youtube.com/watch?v=WY2cN9uG6W8">this</a> extremely useful and concise tutorial.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/simultaneous-animations.mp4" />
|
||||
<h2>Simultaneous Animations</h2>
|
||||
<p>I managed to implement the ability to play multiple animations at a time! The character can now walk + point its gun, or keep its arms down. There's no animation for standing still yet, so it perpetually walks, but this is huge progress, and more importantly, a huge fear of mine alleviated! I was really concerned that implementing multiple animations would be a tedious task, but with Godot's <code>AnimationTree</code> node, it's actually rather trivial.</p>
|
||||
<p>I followed <a href="https://www.youtube.com/watch?v=WY2cN9uG6W8">this</a> extremely useful and concise tutorial.</p>
|
||||
<Video src="/projects/projectn5/devlog/202312/simultaneous-animations.mp4" />
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,33 +8,35 @@
|
||||
<title>2024-02-10 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-02-10" subtitle="" banner="/projects/projectn5/devlog/previews/20240210.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-02-10" subtitle="" banner="/projects/projectn5/devlog/previews/20240210.webp" />
|
||||
|
||||
<p>My apologies for the lack of updates lately! Between being hard at work on the game's progress, lacking motivation, and university exams, I really didn't have the time to write a proper update. Instead, I figured it would now be a great time to do a bundled progress update, since I really did get a lot done that takes the game quite a few steps further!</p>
|
||||
<p>The most apparent change may be the new character! It's a temporary character once again – character number 3, to be exact – but this time it's rigged properly. There are no bends in the character, which sounds PS1-esque but is actually on purpose because the final character is supposed to be a robot.</p>
|
||||
<p>There are also new animations! Nothing finished, of course, but I created them to play around with Godot's <code>AnimationTree</code> and <code>Blend2D</code>, which worked very well to lay out and play even multiple animations at once. There are now animations for walking, standing still, pointing a gun, single jumping, and double jumping! What's missing is a falling animations, but that will be implemented once I figure out how to import NLA tracks instead of needing to re-import the entire character for every animation change.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240210/animations.mp4" />
|
||||
<p>The game also now has a proper sky! I used this <a href="https://godotshaders.com/shader/stylized-sky-with-procedural-sun-and-moon/">Procedural Sky with Procedural Sun and Moon shader</a> by krzmig and tweaked the colours and light to get the current look. I don't expect this to be final necessarily, but I'll definitely at the very least use this as a base. I do like the look though, so it might remain final after all!</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/sky.webp">
|
||||
<p>I fixed the glowing issues in the game at one point, but then screwed up again because glow wasn't working <i>at all</i> anymore. Only after over an hour of troubleshooting did I realise that I disabled glow in the <code>WorldEnvironment</code> node...</p>
|
||||
<p>In tweaking the <code>WorldEnvironment</code>, I even got shadows to work!</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/shadows.webp">
|
||||
<p>That red thing in the top right is an enemy. It doesn't move yet, and it can't take damage either (thus making it invulnerable), but it can be targetted, and it can damage the player too!</p>
|
||||
<p>It can be <i>targetted?</i> Yes! There's now an <code>AutoAimAgent</code> component available for all weapons that targets the nearest enemy that's inside a collision cone attached to the weapon. Once an enemy is inside this collision zone, a target is shown to let the player know which enemy is targetted, and the weapon fires in the precise direction of the enemy.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/target.webp">
|
||||
<p>The weapons received more updates! There's now a quick change function that allows for quickly switching between the 3 most recently used weapons by pressing the Quick Select button quickly.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/quickchange.webp">
|
||||
<p>That sperm rocket you're seeing in the picture above is the new rocket launcher. I wanted to implement the rocket launcher as a weapon type already, so I quickly whipped by a temporary model for launcher and rockets, and implemented the functionality. And it works! It even has particle effects for the rockets!</p>
|
||||
<p>overcompensation be like</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/rocketlauncher.webp">
|
||||
<Video src="/projects/projectn5/devlog/20240210/rockets.mp4" />
|
||||
<p>I really feared GPU particles because I figured they would be insanely difficult to implement, but Godot really made this a breeze. Now, making them look <i>good</i> is a different story, but that's more so due to my lacking creativity and skill.</p>
|
||||
<p>What you don't possess, you can buy. And what do you need to buy those things? Money.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/money.webp">
|
||||
<p>Aside from increasing a counter upon being collected, these totally-not-bolts don't do anything at the moment. But it's a start! In the future, the money can be used to buy things at the vendor that also already exists! But interacting with it only yields a blank menu at the moment.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/vendor.webp">
|
||||
<p>There's more that I can't really show visually though. I made huge progress with the character, for instance. Or rather, <i>I fixed some of the issues my own script caused.</i> I used to use a custom solution based on someone else's code to handle movement speed and sliding on slopes, but this introduced two massive issues. For one, stepping onto a steep slope while still half-standing on a surface that can be walked on caused the character to lose the ability to move until jumping, thus getting stuck. The other issue was that some abrupt slope angle changes caused the entire game to crash, probably caused by a faulty <code>RayCast</code> check.</p>
|
||||
<p>Now, how did I fix these issues? Well, I found out that Godot already offers these functions in the default <code>CharacterController3D</code>. Hence, I ripped out all the custom code, I essentially checked two boolean flags, and I had the same behaviour, minus the game-breaking bugs. Despite my stupidity, I felt very happy to have discovered that. My player script is now a lot cleaner!</p>
|
||||
<p>And so are other scripts! I cleaned up a few scripts, most recently the Inventory script. There used to be a lot of redundant function calls that essentially did the same thing except with one check that could be performed more centrally. I also double-checked item IDs unnecessarily. All gone now! Inventory is much more streamlined now.</p>
|
||||
<p>My next goals are to implement enemy health as well as a level travelling mechanic. To be able to test weapons, enemy movement, and balancing, I want to add an arena world with test challenges. Adding an arena is convenient anyways, since I aim to have an arena in the final game anyway, so I can feel free to dedicate more resources into the arena than if it only were for testing.</p>
|
||||
<p>Let's see how long it'll take me to get these things done! I really do love working on my game, but I often lack the motivation to <i>start</i> working on it. Once I'm in the flow, I can get a lot done, but getting into that flow, just getting out of bed to start something that can be considered "work" – that's the difficult part.</p>
|
||||
<p>My apologies for the lack of updates lately! Between being hard at work on the game's progress, lacking motivation, and university exams, I really didn't have the time to write a proper update. Instead, I figured it would now be a great time to do a bundled progress update, since I really did get a lot done that takes the game quite a few steps further!</p>
|
||||
<p>The most apparent change may be the new character! It's a temporary character once again – character number 3, to be exact – but this time it's rigged properly. There are no bends in the character, which sounds PS1-esque but is actually on purpose because the final character is supposed to be a robot.</p>
|
||||
<p>There are also new animations! Nothing finished, of course, but I created them to play around with Godot's <code>AnimationTree</code> and <code>Blend2D</code>, which worked very well to lay out and play even multiple animations at once. There are now animations for walking, standing still, pointing a gun, single jumping, and double jumping! What's missing is a falling animations, but that will be implemented once I figure out how to import NLA tracks instead of needing to re-import the entire character for every animation change.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240210/animations.mp4" />
|
||||
<p>The game also now has a proper sky! I used this <a href="https://godotshaders.com/shader/stylized-sky-with-procedural-sun-and-moon/">Procedural Sky with Procedural Sun and Moon shader</a> by krzmig and tweaked the colours and light to get the current look. I don't expect this to be final necessarily, but I'll definitely at the very least use this as a base. I do like the look though, so it might remain final after all!</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/sky.webp">
|
||||
<p>I fixed the glowing issues in the game at one point, but then screwed up again because glow wasn't working <i>at all</i> anymore. Only after over an hour of troubleshooting did I realise that I disabled glow in the <code>WorldEnvironment</code> node...</p>
|
||||
<p>In tweaking the <code>WorldEnvironment</code>, I even got shadows to work!</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/shadows.webp">
|
||||
<p>That red thing in the top right is an enemy. It doesn't move yet, and it can't take damage either (thus making it invulnerable), but it can be targetted, and it can damage the player too!</p>
|
||||
<p>It can be <i>targetted?</i> Yes! There's now an <code>AutoAimAgent</code> component available for all weapons that targets the nearest enemy that's inside a collision cone attached to the weapon. Once an enemy is inside this collision zone, a target is shown to let the player know which enemy is targetted, and the weapon fires in the precise direction of the enemy.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/target.webp">
|
||||
<p>The weapons received more updates! There's now a quick change function that allows for quickly switching between the 3 most recently used weapons by pressing the Quick Select button quickly.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/quickchange.webp">
|
||||
<p>That sperm rocket you're seeing in the picture above is the new rocket launcher. I wanted to implement the rocket launcher as a weapon type already, so I quickly whipped by a temporary model for launcher and rockets, and implemented the functionality. And it works! It even has particle effects for the rockets!</p>
|
||||
<p>overcompensation be like</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/rocketlauncher.webp">
|
||||
<Video src="/projects/projectn5/devlog/20240210/rockets.mp4" />
|
||||
<p>I really feared GPU particles because I figured they would be insanely difficult to implement, but Godot really made this a breeze. Now, making them look <i>good</i> is a different story, but that's more so due to my lacking creativity and skill.</p>
|
||||
<p>What you don't possess, you can buy. And what do you need to buy those things? Money.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/money.webp">
|
||||
<p>Aside from increasing a counter upon being collected, these totally-not-bolts don't do anything at the moment. But it's a start! In the future, the money can be used to buy things at the vendor that also already exists! But interacting with it only yields a blank menu at the moment.</p>
|
||||
<img src="/projects/projectn5/devlog/20240210/vendor.webp">
|
||||
<p>There's more that I can't really show visually though. I made huge progress with the character, for instance. Or rather, <i>I fixed some of the issues my own script caused.</i> I used to use a custom solution based on someone else's code to handle movement speed and sliding on slopes, but this introduced two massive issues. For one, stepping onto a steep slope while still half-standing on a surface that can be walked on caused the character to lose the ability to move until jumping, thus getting stuck. The other issue was that some abrupt slope angle changes caused the entire game to crash, probably caused by a faulty <code>RayCast</code> check.</p>
|
||||
<p>Now, how did I fix these issues? Well, I found out that Godot already offers these functions in the default <code>CharacterController3D</code>. Hence, I ripped out all the custom code, I essentially checked two boolean flags, and I had the same behaviour, minus the game-breaking bugs. Despite my stupidity, I felt very happy to have discovered that. My player script is now a lot cleaner!</p>
|
||||
<p>And so are other scripts! I cleaned up a few scripts, most recently the Inventory script. There used to be a lot of redundant function calls that essentially did the same thing except with one check that could be performed more centrally. I also double-checked item IDs unnecessarily. All gone now! Inventory is much more streamlined now.</p>
|
||||
<p>My next goals are to implement enemy health as well as a level travelling mechanic. To be able to test weapons, enemy movement, and balancing, I want to add an arena world with test challenges. Adding an arena is convenient anyways, since I aim to have an arena in the final game anyway, so I can feel free to dedicate more resources into the arena than if it only were for testing.</p>
|
||||
<p>Let's see how long it'll take me to get these things done! I really do love working on my game, but I often lack the motivation to <i>start</i> working on it. Once I'm in the flow, I can get a lot done, but getting into that flow, just getting out of bed to start something that can be considered "work" – that's the difficult part.</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,54 +9,56 @@
|
||||
<title>2024-03-12 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-12" subtitle="" banner="/projects/projectn5/devlog/previews/20240312.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-12" subtitle="" banner="/projects/projectn5/devlog/previews/20240312.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>I've unfortunately not gotten a lot done lately. Both an internship and many university courseworks had robbed me of much time, while the remainder of my free time had been taken up by a lack of motivation for working on my game. Despite this, I've still made a little bit of progress that I'm quite happy to share here!</p>
|
||||
<p>I've unfortunately not gotten a lot done lately. Both an internship and many university courseworks had robbed me of much time, while the remainder of my free time had been taken up by a lack of motivation for working on my game. Despite this, I've still made a little bit of progress that I'm quite happy to share here!</p>
|
||||
|
||||
<h2 id="titlescreen">Back to Title Screen</h2>
|
||||
<p>I needed a means to launch different levels quickly, so I created a basic title screen for the game! Behind this is a basic custom level manager that allows for launching and switching between different levels. Currently, there exist two of them – Unity and Arena. Unity is the original level that's been in the game since day 1, using Unity's (old) logo as a floor plane, mostly as a joke because I switched from Unity to Godot.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/titlescreen.webp">
|
||||
<h2 id="titlescreen">Back to Title Screen</h2>
|
||||
<p>I needed a means to launch different levels quickly, so I created a basic title screen for the game! Behind this is a basic custom level manager that allows for launching and switching between different levels. Currently, there exist two of them – Unity and Arena. Unity is the original level that's been in the game since day 1, using Unity's (old) logo as a floor plane, mostly as a joke because I switched from Unity to Godot.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/titlescreen.webp">
|
||||
|
||||
<h2 id="arena">Level 2: Arena</h2>
|
||||
<p>The arena level is a new addition, everyone welcome the arena! While I do intend to design a proper arena for the final game, this arena is intended to test enemies and the arena menu.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/arena.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">the blue sky gives the level such a different feel. the clouds move really quickly here compared to Unity's clouds, suggesting a stormy atmosphere on this planet.</span>
|
||||
</div>
|
||||
<p>The computer over there is the arena terminal. By interacting with it, you can select an arena challenge. Currently, it doesn't work. The menu does work! But the buttons don't do anything so far.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/arena-terminal.webp">
|
||||
<h2 id="arena">Level 2: Arena</h2>
|
||||
<p>The arena level is a new addition, everyone welcome the arena! While I do intend to design a proper arena for the final game, this arena is intended to test enemies and the arena menu.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/arena.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">the blue sky gives the level such a different feel. the clouds move really quickly here compared to Unity's clouds, suggesting a stormy atmosphere on this planet.</span>
|
||||
</div>
|
||||
<p>The computer over there is the arena terminal. By interacting with it, you can select an arena challenge. Currently, it doesn't work. The menu does work! But the buttons don't do anything so far.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/arena-terminal.webp">
|
||||
|
||||
<h2 id="thirdperson">Talking about yourself in the 3rd person</h2>
|
||||
<p>I discovered this great plugin for Godot called <a href="https://phantom-camera.dev/">Phantom Camera</a>. It's a plugin that allows you to use agents to control the game camera smoothly, efficiently, and hassle-free. In order to implement it in my game, I only had to do the totally easy task of ripping out my entire camera system. It totally didn't almost make me restart the project from scratch. But it works flawlessly now!</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/shoulder.webp">
|
||||
<p>It wasn't quite flawless from the start though. I had issues with the camera facing my character's front instead of their back. Turns out though, that's not the camera's fault; Phantom Camera's agent was specifically designed to look at the character's back – only problem was that my character model was facing the wrong way! Fixing that took a little bit of time, but I got it done, and now the camera works pretty decently. I even added two more fancy camera gizmos: the first one is a level overview camera, like in Ratchet & Clank! It shows an overview of the level when you enter it. It smootly transitions to the player once any input is made.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/overview.webp">
|
||||
<p>The other is an over-the-shoulder camera! This one allows for (allegedly) more precise aiming. Come to think of it, I should actually turn down the camera sensitivity when the player is in this mode...</p>
|
||||
<Video src="/projects/projectn5/devlog/20240312/shoulder.mp4" />
|
||||
<p>Funnily, due to initial collision issues, I first accidentally turned my game into a first person shooter. Actually looks kind of cool, I have to say. Maybe I'll implement a first person view as an alternative option to the over-the-shoulder view.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240312/firstperson.mp4" />
|
||||
<h2 id="thirdperson">Talking about yourself in the 3rd person</h2>
|
||||
<p>I discovered this great plugin for Godot called <a href="https://phantom-camera.dev/">Phantom Camera</a>. It's a plugin that allows you to use agents to control the game camera smoothly, efficiently, and hassle-free. In order to implement it in my game, I only had to do the totally easy task of ripping out my entire camera system. It totally didn't almost make me restart the project from scratch. But it works flawlessly now!</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/shoulder.webp">
|
||||
<p>It wasn't quite flawless from the start though. I had issues with the camera facing my character's front instead of their back. Turns out though, that's not the camera's fault; Phantom Camera's agent was specifically designed to look at the character's back – only problem was that my character model was facing the wrong way! Fixing that took a little bit of time, but I got it done, and now the camera works pretty decently. I even added two more fancy camera gizmos: the first one is a level overview camera, like in Ratchet & Clank! It shows an overview of the level when you enter it. It smootly transitions to the player once any input is made.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/overview.webp">
|
||||
<p>The other is an over-the-shoulder camera! This one allows for (allegedly) more precise aiming. Come to think of it, I should actually turn down the camera sensitivity when the player is in this mode...</p>
|
||||
<Video src="/projects/projectn5/devlog/20240312/shoulder.mp4" />
|
||||
<p>Funnily, due to initial collision issues, I first accidentally turned my game into a first person shooter. Actually looks kind of cool, I have to say. Maybe I'll implement a first person view as an alternative option to the over-the-shoulder view.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240312/firstperson.mp4" />
|
||||
|
||||
<h2 id="sketches">Can I offer you a nice sketch in this trying time?</h2>
|
||||
<p>When I'm not developing, I'm often doing something else related to my game. Sometimes, I sketch!</p>
|
||||
<p>I am by NO MEANS a skilled sketch artist, but it really helps to note down ideas to remember them, visualise them, and expand on them.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/sketches.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">don't judge</span>
|
||||
</div>
|
||||
<h2 id="sketches">Can I offer you a nice sketch in this trying time?</h2>
|
||||
<p>When I'm not developing, I'm often doing something else related to my game. Sometimes, I sketch!</p>
|
||||
<p>I am by NO MEANS a skilled sketch artist, but it really helps to note down ideas to remember them, visualise them, and expand on them.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/sketches.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">don't judge</span>
|
||||
</div>
|
||||
|
||||
<h2 id="kanban">Kanban for my TODOs</h2>
|
||||
<p>Perhaps as a small insight into my project management process: I'm using <a href="https://obsidian.md/">Obsidian</a>, a markdown editor, as my means of collecting and managing my projects' notes and ideas. Recently, I've also tried using the Kanban plugin to organise my TODOs (I have <i>a lot</i> of them), which is working quite well! I often create small notes on this board, saving sparks of ideas that I occasionally have, and I like adding extra information that will help me remember in the long term what those ideas were about.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/kanban.webp">
|
||||
<p>I can only recommend it – both Kanban as a means of project management as well as Obsidian as a note vault!</p>
|
||||
<h2 id="kanban">Kanban for my TODOs</h2>
|
||||
<p>Perhaps as a small insight into my project management process: I'm using <a href="https://obsidian.md/">Obsidian</a>, a markdown editor, as my means of collecting and managing my projects' notes and ideas. Recently, I've also tried using the Kanban plugin to organise my TODOs (I have <i>a lot</i> of them), which is working quite well! I often create small notes on this board, saving sparks of ideas that I occasionally have, and I like adding extra information that will help me remember in the long term what those ideas were about.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/kanban.webp">
|
||||
<p>I can only recommend it – both Kanban as a means of project management as well as Obsidian as a note vault!</p>
|
||||
|
||||
<h2 id="future">in hopes of more to come</h2>
|
||||
<p>Progress has been slow lately, but I have not stopped thinking about my game. I have big ambitions for this title – of course bearing in mind that I am only one person, and that this is also my first proper attempt at making a video game. Still, I think that, with enough time and dedication, I can pull off developing something that I will be quite proud of. Even right now, I am already proud of what I've accomplished. I have a large chunk of the basic game mechanics down already, and I did it all on my own (with the help of online documentation and a few tutorials, of course)!</p>
|
||||
<p>After every day of working on my game, I ask myself: "did I really accomplish much today?" Often, my immediate response is "no", but my second response is "of course I did!" Because while a lot of things that take me quite a bit of time are children's play for another person most likely, the fact that I worked through it and managed to successfully create or implement something is huge. I'm always quite happy once I realise this.</p>
|
||||
<p>And so, while my day-to-day motivation for working on my game directly is rather low, this is only a symptom of a general lack of motivation for anything. In the long term, I think I am quite dedicated to this game. When I'm not coding something, I'm coming up with ideas. I'm managing my notes. I'm designing something. Maybe I'm talking to someone about my ideas. That last point is actually something I would love to do more, but I don't really know any person that would enjoy listening to my ramblings.</p>
|
||||
<p>Let's see how far we get.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/alone.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">staring longingly into the sunset</span>
|
||||
</div>
|
||||
<h2 id="future">in hopes of more to come</h2>
|
||||
<p>Progress has been slow lately, but I have not stopped thinking about my game. I have big ambitions for this title – of course bearing in mind that I am only one person, and that this is also my first proper attempt at making a video game. Still, I think that, with enough time and dedication, I can pull off developing something that I will be quite proud of. Even right now, I am already proud of what I've accomplished. I have a large chunk of the basic game mechanics down already, and I did it all on my own (with the help of online documentation and a few tutorials, of course)!</p>
|
||||
<p>After every day of working on my game, I ask myself: "did I really accomplish much today?" Often, my immediate response is "no", but my second response is "of course I did!" Because while a lot of things that take me quite a bit of time are children's play for another person most likely, the fact that I worked through it and managed to successfully create or implement something is huge. I'm always quite happy once I realise this.</p>
|
||||
<p>And so, while my day-to-day motivation for working on my game directly is rather low, this is only a symptom of a general lack of motivation for anything. In the long term, I think I am quite dedicated to this game. When I'm not coding something, I'm coming up with ideas. I'm managing my notes. I'm designing something. Maybe I'm talking to someone about my ideas. That last point is actually something I would love to do more, but I don't really know any person that would enjoy listening to my ramblings.</p>
|
||||
<p>Let's see how far we get.</p>
|
||||
<img src="/projects/projectn5/devlog/20240312/alone.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">staring longingly into the sunset</span>
|
||||
</div>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,129 +9,131 @@
|
||||
<title>2024-03-23 | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-23" subtitle="" banner="/projects/projectn5/devlog/previews/20240323.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-23" subtitle="" banner="/projects/projectn5/devlog/previews/20240323.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>I have quite a bit of free time on my hands until the next semester starts (in a few days...), and this leisure time has allowed me to continue working on my game a lot more than usual! I made quite a bit of progress that makes this game prototype feel slightly more polished and I'm really happy to share it here and now.</p>
|
||||
<p>I have quite a bit of free time on my hands until the next semester starts (in a few days...), and this leisure time has allowed me to continue working on my game a lot more than usual! I made quite a bit of progress that makes this game prototype feel slightly more polished and I'm really happy to share it here and now.</p>
|
||||
|
||||
<h2 id="attraction">Attraction <3</h2>
|
||||
<p>Collectibles are now attracted by the player once they're within a certain range (specified by a spherical <code>CollisionShape3D</code>) and are collected once they get close enough to the player – which is to say, once they collide with another, smaller spherical <code>CollisionShape3D</code>. The first try didn't work out amazingly, as the collectibles didn't want my character to intrude on their personal space though...</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/personalspace.mp4" />
|
||||
<h2 id="attraction">Attraction <3</h2>
|
||||
<p>Collectibles are now attracted by the player once they're within a certain range (specified by a spherical <code>CollisionShape3D</code>) and are collected once they get close enough to the player – which is to say, once they collide with another, smaller spherical <code>CollisionShape3D</code>. The first try didn't work out amazingly, as the collectibles didn't want my character to intrude on their personal space though...</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/personalspace.mp4" />
|
||||
|
||||
<p>I fixed that issue, and lowered the attraction velocity to test, but that resulted in a spooky haunting effect.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/haunting.mp4" />
|
||||
<p>I fixed that issue, and lowered the attraction velocity to test, but that resulted in a spooky haunting effect.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/haunting.mp4" />
|
||||
|
||||
<p>Here's another demonstration of that! I played around with PhantomCamera's dampening, which makes the haunting effect more evident. Also something I only came to notice then: my player jumps INSANELY high. Like 8x their height. This will be fixed later.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/high.mp4" />
|
||||
<p>Here's another demonstration of that! I played around with PhantomCamera's dampening, which makes the haunting effect more evident. Also something I only came to notice then: my player jumps INSANELY high. Like 8x their height. This will be fixed later.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/high.mp4" />
|
||||
|
||||
<p>After tweaking the speed, I got some nice attracted collectibles.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/attraction_stuck.mp4" />
|
||||
<p>After tweaking the speed, I got some nice attracted collectibles.</p>
|
||||
<Video src="/projects/projectn5/devlog/20240323/attraction_stuck.mp4" />
|
||||
|
||||
<p>One issue still remains though: when moving, the collectibles don't attract all the way into the player, therefore they don't get collected and fly next to the player until they stop moving.</p>
|
||||
<p>I learned that <code>lerp()</code> was at fault (no offense!) – <code>lerp()</code> would work perfectly fine if the player were standing still, but since the player – and therefore, the target position – is moving, <code>lerp()</code> calculates a speed that cannot overcome the difference between the collectible position and the player.</p>
|
||||
<p>I overcame this issue by increasing the weight of <code>lerp()</code> on every frame, thus increasing the speed linearly. This resulted in a very smooth attraction transition.</p>
|
||||
<p>One issue still remains though: when moving, the collectibles don't attract all the way into the player, therefore they don't get collected and fly next to the player until they stop moving.</p>
|
||||
<p>I learned that <code>lerp()</code> was at fault (no offense!) – <code>lerp()</code> would work perfectly fine if the player were standing still, but since the player – and therefore, the target position – is moving, <code>lerp()</code> calculates a speed that cannot overcome the difference between the collectible position and the player.</p>
|
||||
<p>I overcame this issue by increasing the weight of <code>lerp()</code> on every frame, thus increasing the speed linearly. This resulted in a very smooth attraction transition.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/attraction_smooth.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/attraction_smooth.mp4" />
|
||||
|
||||
<h2 id="rockets">rocket go boom</h2>
|
||||
<p>I finally implemented enemy health – they can now take damage from weapons and die. But it felt so hollow without any impact. I wanted my rockets to explode. So I started working on that.</p>
|
||||
<h2 id="rockets">rocket go boom</h2>
|
||||
<p>I finally implemented enemy health – they can now take damage from weapons and die. But it felt so hollow without any impact. I wanted my rockets to explode. So I started working on that.</p>
|
||||
|
||||
<h3 id="rockets-1">Stage 1: Experimentation</h3>
|
||||
<h3 id="rockets-1">Stage 1: Experimentation</h3>
|
||||
|
||||
<p>I first implemented a fairly basic particle effect using cube meshes. Not exactly photorealistic, but it gets the message across.</p>
|
||||
<p>I first implemented a fairly basic particle effect using cube meshes. Not exactly photorealistic, but it gets the message across.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_0.mp4" />
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">boom</span>
|
||||
</div>
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_0.mp4" />
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">boom</span>
|
||||
</div>
|
||||
|
||||
<h3 id="rockets-2">Stage 2: Struggle Colliding</h3>
|
||||
<h3 id="rockets-2">Stage 2: Struggle Colliding</h3>
|
||||
|
||||
<p>I struggled EXTREMELY with getting the rockets to collide with the floor and walls. Oddly enough, they collided perfectly fine with the enemies! I was particularly confused because both the walls/floors and the enemies were types of <code>body</code> nodes, thus using the same piece of code to register a collision.</p>
|
||||
<p>I struggled EXTREMELY with getting the rockets to collide with the floor and walls. Oddly enough, they collided perfectly fine with the enemies! I was particularly confused because both the walls/floors and the enemies were types of <code>body</code> nodes, thus using the same piece of code to register a collision.</p>
|
||||
|
||||
<p>I looked up the issue online, to no avail, really, until I stumbled upon a thread about a completely different problem where someone advised to change the physics engine. I am, in fact, using a different physics engine – Jolt. So I figured, I'll go into the settings, and I'll change it, just to see what happens.</p>
|
||||
<p>I looked up the issue online, to no avail, really, until I stumbled upon a thread about a completely different problem where someone advised to change the physics engine. I am, in fact, using a different physics engine – Jolt. So I figured, I'll go into the settings, and I'll change it, just to see what happens.</p>
|
||||
|
||||
<p>I briefly checked out Jolt's settings page... and then I saw something.</p>
|
||||
<p>I briefly checked out Jolt's settings page... and then I saw something.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240323/joltsettings.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/joltsettings.webp">
|
||||
|
||||
<p>"Areas Detect Static Bodies." This setting was OFF by default. This could actually apply, I figured, because my rockets are <code>Area3D</code>s and the walls/floors are <code>StaticBody3D</code> nodes. I turned it on, and... my issue was solved. Slightly frustrated, but more so amused and relieved, I continued work, happy that my code was fine and my solution worked.</p>
|
||||
<p>"Areas Detect Static Bodies." This setting was OFF by default. This could actually apply, I figured, because my rockets are <code>Area3D</code>s and the walls/floors are <code>StaticBody3D</code> nodes. I turned it on, and... my issue was solved. Slightly frustrated, but more so amused and relieved, I continued work, happy that my code was fine and my solution worked.</p>
|
||||
|
||||
<p>I introduced an exported property that allows for setting the amount of collisions a projectile may experience before it despawns, thus allowing, for example, for the rocket to explode through a wall! I might use this in the future for the v3 rocket laucher.</p>
|
||||
<p>I introduced an exported property that allows for setting the amount of collisions a projectile may experience before it despawns, thus allowing, for example, for the rocket to explode through a wall! I might use this in the future for the v3 rocket laucher.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_wall.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_wall.mp4" />
|
||||
|
||||
<h3 id="rockets-3">Stage 3: Style</h3>
|
||||
<h3 id="rockets-3">Stage 3: Style</h3>
|
||||
|
||||
<p>One day after that, I was motivated to create a more convincing explosion. I watched a YouTube tutorial, and ultimately got something that looks quite nice:</p>
|
||||
<p>One day after that, I was motivated to create a more convincing explosion. I watched a YouTube tutorial, and ultimately got something that looks quite nice:</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_test.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_test.mp4" />
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_1.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/explosion_1.mp4" />
|
||||
|
||||
<p>Interesting observation: in Godot, you can use the "RAW" tab when picking a colour to set values above 100%. The explosions, for example, use red values between 300% and 500%, which, with my <code>WorldEnvironment</code> light setup, produces a glowing effect that's just perfect for explosions!</p>
|
||||
<p>Interesting observation: in Godot, you can use the "RAW" tab when picking a colour to set values above 100%. The explosions, for example, use red values between 300% and 500%, which, with my <code>WorldEnvironment</code> light setup, produces a glowing effect that's just perfect for explosions!</p>
|
||||
|
||||
<p>I also messed up my lighting setup in configuring this, which results in my character being extra shiny and the N5 Blaster to glow excessively, but that's ok, we can fix that later.</p>
|
||||
<p>I also messed up my lighting setup in configuring this, which results in my character being extra shiny and the N5 Blaster to glow excessively, but that's ok, we can fix that later.</p>
|
||||
|
||||
<p>In a strange coincidence, <a href="https://youtu.be/rXwo0qcKJDk">Masahiro Sakurai released a video</a> about particle effects and the "right level of detail" just one day after I had started working on my explosion particle effects. Interesting video, by the way – I was not aware of how important scale is when designing VFX.</p>
|
||||
<p>In a strange coincidence, <a href="https://youtu.be/rXwo0qcKJDk">Masahiro Sakurai released a video</a> about particle effects and the "right level of detail" just one day after I had started working on my explosion particle effects. Interesting video, by the way – I was not aware of how important scale is when designing VFX.</p>
|
||||
|
||||
<h2 id="shake">Camera Shake</h2>
|
||||
<h2 id="shake">Camera Shake</h2>
|
||||
|
||||
<p>Anyway, I got to work on camera shake! Through a tiny bug that has already been fixed, I briefly got to experience something resembling a camera shake in my game while I was firing a rocket. I thought that was super cool, so I looked up camera shake and implemented it.</p>
|
||||
<p>Anyway, I got to work on camera shake! Through a tiny bug that has already been fixed, I briefly got to experience something resembling a camera shake in my game while I was firing a rocket. I thought that was super cool, so I looked up camera shake and implemented it.</p>
|
||||
|
||||
<p>The tutorial I followed (a 2D tutorial, btw) used a strength value of 30. I figured that'd be too much, so I set it to 20, just in case.</p>
|
||||
<p>The tutorial I followed (a 2D tutorial, btw) used a strength value of 30. I figured that'd be too much, so I set it to 20, just in case.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/shake_0.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/shake_0.mp4" />
|
||||
|
||||
<p>...I later set down the strength value to about 0.35.</p>
|
||||
<p>...I later set down the strength value to about 0.35.</p>
|
||||
|
||||
<p>I also implemented distance fade for the camera shake strength! The strength now depends on how close the player is to the explosion origin. An explosion far away won't shake the camera, but one close up has much more impact!</p>
|
||||
<p>I also implemented distance fade for the camera shake strength! The strength now depends on how close the player is to the explosion origin. An explosion far away won't shake the camera, but one close up has much more impact!</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/shake_impact.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/shake_impact.mp4" />
|
||||
|
||||
<h2 id="new-weapon">A new weapon is in the works!</h2>
|
||||
<h2 id="new-weapon">A new weapon is in the works!</h2>
|
||||
|
||||
<p>I had a random burst inspiration recently while I was on the bus, and once I got home, I started modelling it. Introducing: a weapon that is unfinished and has no (finalised) name yet, but I'm still fairly proud of:</p>
|
||||
<p>I had a random burst inspiration recently while I was on the bus, and once I got home, I started modelling it. Introducing: a weapon that is unfinished and has no (finalised) name yet, but I'm still fairly proud of:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240323/venom_front.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/venom_back.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/venom_front.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/venom_back.webp">
|
||||
|
||||
<p>I'm thinking this could be a blaster of types, maybe similar to an N5 Blaster upgrade – two-handed. Though I think it should be separate from the N5 Blaster. It could also be a flamethrower, though I want the flamethrower to look a bit different, especially at the gun barrel.</p>
|
||||
<p>I'm thinking this could be a blaster of types, maybe similar to an N5 Blaster upgrade – two-handed. Though I think it should be separate from the N5 Blaster. It could also be a flamethrower, though I want the flamethrower to look a bit different, especially at the gun barrel.</p>
|
||||
|
||||
<p>I quite like the bolt at the back as well as the yellow gunmetal-ish colour of the bolt and the gun barrel. The body is far from finalised – I still have to figure out a fitting one. I do like the cutouts in the shape, however, so I'll probably keep them for the final body shape.</p>
|
||||
<p>I quite like the bolt at the back as well as the yellow gunmetal-ish colour of the bolt and the gun barrel. The body is far from finalised – I still have to figure out a fitting one. I do like the cutouts in the shape, however, so I'll probably keep them for the final body shape.</p>
|
||||
|
||||
<h2 id="camera">Camera Adjustments</h2>
|
||||
<h2 id="camera">Camera Adjustments</h2>
|
||||
|
||||
<p>I also worked quite a bit on the camera, specifically how it moves! This is the main thing that, in my opinion, makes the current build feel just a bit more polished than the previous ones – relatively speaking, of course.</p>
|
||||
<p>I also worked quite a bit on the camera, specifically how it moves! This is the main thing that, in my opinion, makes the current build feel just a bit more polished than the previous ones – relatively speaking, of course.</p>
|
||||
|
||||
<p>The camera now moves quicker and more smoothly in and out of the precision aiming mode, for example:</p>
|
||||
<p>The camera now moves quicker and more smoothly in and out of the precision aiming mode, for example:</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_precision.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_precision.mp4" />
|
||||
|
||||
<p>The level overview camera also moves in a much cooler way, using a quint transition type instead of the previous linear transition. I think using quint improves the look significantly.</p>
|
||||
<p>The level overview camera also moves in a much cooler way, using a quint transition type instead of the previous linear transition. I think using quint improves the look significantly.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_overview.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_overview.mp4" />
|
||||
|
||||
<p>Look at how smoothly the camera follows the player, even when the player jumps up a platform or falls down from one!</p>
|
||||
<p>Look at how smoothly the camera follows the player, even when the player jumps up a platform or falls down from one!</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_smooth.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240323/camera_smooth.mp4" />
|
||||
|
||||
<p>The camera now sticks to the ground briefly when the player jumps, but it returns to the player once the player exceeds a certain height above the jump origin or falls lower than the starting point.</p>
|
||||
<p>The camera now sticks to the ground briefly when the player jumps, but it returns to the player once the player exceeds a certain height above the jump origin or falls lower than the starting point.</p>
|
||||
|
||||
<p>Also notice how, at the end of the video, I struggle to jump up the (admittedly massive) wall, but ultimately make it. Why is that? It's because I:</p>
|
||||
<p>Also notice how, at the end of the video, I struggle to jump up the (admittedly massive) wall, but ultimately make it. Why is that? It's because I:</p>
|
||||
|
||||
<ol>
|
||||
<li>Adjusted the jump height to much more sensible values</li>
|
||||
<li>Implemented variable jump height, letting the player jump heigher the longer the jump button is pressed</li>
|
||||
</ol>
|
||||
<ol>
|
||||
<li>Adjusted the jump height to much more sensible values</li>
|
||||
<li>Implemented variable jump height, letting the player jump heigher the longer the jump button is pressed</li>
|
||||
</ol>
|
||||
|
||||
<p>Of course, obligatory <i>I accidentally turned my game into a first-person shooter</i>, again. This view of the N5 Blaster actually reminds me of Metroid.</p>
|
||||
<p>Of course, obligatory <i>I accidentally turned my game into a first-person shooter</i>, again. This view of the N5 Blaster actually reminds me of Metroid.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240323/firstperson.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/firstperson.webp">
|
||||
|
||||
<h2 id="unity">Looking down upon the mess I've created</h2>
|
||||
<h2 id="unity">Looking down upon the mess I've created</h2>
|
||||
|
||||
<p>I'm really happy with my progress. As a bonus, here's an overview of my current testing level Unity.</p>
|
||||
<p>I'm really happy with my progress. As a bonus, here's an overview of my current testing level Unity.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240323/unity_overview.webp">
|
||||
<img src="/projects/projectn5/devlog/20240323/unity_overview.webp">
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,96 +9,98 @@
|
||||
<title>The Arena Update | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-24" subtitle="The Arena Update" banner="/projects/projectn5/devlog/previews/20240324.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-03-24" subtitle="The Arena Update" banner="/projects/projectn5/devlog/previews/20240324.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>A new update <i>so</i> soon‽ Yes! I have things to share that I'm really excited about!</p>
|
||||
<p>A new update <i>so</i> soon‽ Yes! I have things to share that I'm really excited about!</p>
|
||||
|
||||
<h2 id="what">What did I actually do?</h2>
|
||||
<h2 id="what">What did I actually do?</h2>
|
||||
|
||||
<p>Today, while I was standing in the shower, I set out a goal for myself: implement the arena mechanic. This was actually a goal that I had set out for myself to complete months ago, and my ultimate goal was to have it done by April. A few weeks ago, I thought to myself that I had postponed it too much, and that I wouldn't be able to get it done by April anymore – especially concerning the lacking motivation I had back then.</p>
|
||||
<p>Today, while I was standing in the shower, I set out a goal for myself: implement the arena mechanic. This was actually a goal that I had set out for myself to complete months ago, and my ultimate goal was to have it done by April. A few weeks ago, I thought to myself that I had postponed it too much, and that I wouldn't be able to get it done by April anymore – especially concerning the lacking motivation I had back then.</p>
|
||||
|
||||
<p>So, did I actually get done what I had set out to do? Also yes! I worked on my game (with breaks in-between, even one I used to bake a small cake) for a whole 10 hours today, and I actually worked out a decent, modular arena challenge system.</p>
|
||||
<p>So, did I actually get done what I had set out to do? Also yes! I worked on my game (with breaks in-between, even one I used to bake a small cake) for a whole 10 hours today, and I actually worked out a decent, modular arena challenge system.</p>
|
||||
|
||||
<h2 id="product">The Finished Product</h2>
|
||||
<h2 id="product">The Finished Product</h2>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240324/demonstration.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240324/demonstration.mp4" />
|
||||
|
||||
<h2 id="good">The Good</h2>
|
||||
<h2 id="good">The Good</h2>
|
||||
|
||||
<ul>
|
||||
<li>Arenas are fully functional; challenges can be selected, enemies fought, and rounds finished</li>
|
||||
<li>The arena terminal automatically receives all arena challenges and creates an interactable menu with clickable buttons that can be used to start challenges</li>
|
||||
<li>Lots of components are easily reusable and meshes are able to be replaced with finished products with ease once the time comes</li>
|
||||
<li>Finishing a challenge successfully yields a monetary reward</li>
|
||||
<li>A new test enemy type has been added that can more appropriately attack the player and even move towards them, thus laying the groundwork for a general-purpose enemy behaviour script</li>
|
||||
<li>Adding new challenges to the arena terminal is insanely easy and intuitive</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Arenas are fully functional; challenges can be selected, enemies fought, and rounds finished</li>
|
||||
<li>The arena terminal automatically receives all arena challenges and creates an interactable menu with clickable buttons that can be used to start challenges</li>
|
||||
<li>Lots of components are easily reusable and meshes are able to be replaced with finished products with ease once the time comes</li>
|
||||
<li>Finishing a challenge successfully yields a monetary reward</li>
|
||||
<li>A new test enemy type has been added that can more appropriately attack the player and even move towards them, thus laying the groundwork for a general-purpose enemy behaviour script</li>
|
||||
<li>Adding new challenges to the arena terminal is insanely easy and intuitive</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="enemy">The New Enemy, Suzanne Cylinder</h3>
|
||||
<h3 id="enemy">The New Enemy, Suzanne Cylinder</h3>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240324/suzannecylinder.webp">
|
||||
<img src="/projects/projectn5/devlog/20240324/suzannecylinder.webp">
|
||||
|
||||
<p>Suzanne cylinder (called "test_monkey" in the game) is the first enemy that has movement code implemented, able to follow the player once close enough and attack once the player gets too close. Without gravity holding Suzanne cylinder to the ground, though, the situation gets spooky quickly.</p>
|
||||
<p>Suzanne cylinder (called "test_monkey" in the game) is the first enemy that has movement code implemented, able to follow the player once close enough and attack once the player gets too close. Without gravity holding Suzanne cylinder to the ground, though, the situation gets spooky quickly.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240324/haunted.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240324/haunted.mp4" />
|
||||
|
||||
<p>Initial movement tests were quite funny, because <code>look_at()</code> adjusts rotation on both the y axis (left-right rotation) as well as the x-axis (up-down rotation), which meant that the enemy kept looking up when the player was at a higher elevation than it.</p>
|
||||
<p>Initial movement tests were quite funny, because <code>look_at()</code> adjusts rotation on both the y axis (left-right rotation) as well as the x-axis (up-down rotation), which meant that the enemy kept looking up when the player was at a higher elevation than it.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20240324/lookingup.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">send help</span>
|
||||
</div>
|
||||
<img src="/projects/projectn5/devlog/20240324/lookingup.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">send help</span>
|
||||
</div>
|
||||
|
||||
<h3 id="challenges">Developing Arena Challenges</h3>
|
||||
<h3 id="challenges">Developing Arena Challenges</h3>
|
||||
|
||||
<p>To expand on the last point: I'm actually quite proud of the solution I implemented for creating arena challenges. The way this works right now is that the arena terminal contains a dictionary which stores all arena challenges, including any information that needs to be associated with them: round and enemy count and types, rewards, etc.</p>
|
||||
<p>To expand on the last point: I'm actually quite proud of the solution I implemented for creating arena challenges. The way this works right now is that the arena terminal contains a dictionary which stores all arena challenges, including any information that needs to be associated with them: round and enemy count and types, rewards, etc.</p>
|
||||
|
||||
<p>All that information looks a little like this:</p>
|
||||
<p>All that information looks a little like this:</p>
|
||||
|
||||
<pre class="code-block">
|
||||
const arena_challenges = {
|
||||
1099: {
|
||||
"reward": 7382,
|
||||
"rounds": [
|
||||
{
|
||||
"type": "regular",
|
||||
"spawner_count": 3,
|
||||
"enemies": [
|
||||
ENEMY_MONKEY,
|
||||
ENEMY_MONKEY,
|
||||
ENEMY_MONKEY,
|
||||
...
|
||||
],
|
||||
},
|
||||
...
|
||||
],
|
||||
},
|
||||
}</pre>
|
||||
<pre class="code-block">
|
||||
const arena_challenges = {
|
||||
1099: {
|
||||
"reward": 7382,
|
||||
"rounds": [
|
||||
{
|
||||
"type": "regular",
|
||||
"spawner_count": 3,
|
||||
"enemies": [
|
||||
ENEMY_MONKEY,
|
||||
ENEMY_MONKEY,
|
||||
ENEMY_MONKEY,
|
||||
...
|
||||
],
|
||||
},
|
||||
...
|
||||
],
|
||||
},
|
||||
}</pre>
|
||||
|
||||
<p><code>1099</code> is the unique ID by which the challenge is identified; this can later be used to save which challenges the player has already successfully completed. The ID is also used to fetch strings, such as the title of the challenge, and later the description and perhaps other useful information that could be displayed to the player in the arena terminal GUI.</p>
|
||||
<p><code>1099</code> is the unique ID by which the challenge is identified; this can later be used to save which challenges the player has already successfully completed. The ID is also used to fetch strings, such as the title of the challenge, and later the description and perhaps other useful information that could be displayed to the player in the arena terminal GUI.</p>
|
||||
|
||||
<p><code>reward</code> is the money count that is rewarded after completing a challenge; the option to receive items could be implemented later. A reward for completions after the first one should also be added later, so that the player doesn't receive an insane amount of money for completing the same challenge over and over again!</p>
|
||||
<p><code>reward</code> is the money count that is rewarded after completing a challenge; the option to receive items could be implemented later. A reward for completions after the first one should also be added later, so that the player doesn't receive an insane amount of money for completing the same challenge over and over again!</p>
|
||||
|
||||
<p><code>rounds</code> is an array that contains <code>round</code> objects which store the <code>type</code> of round – which is currently unused, but could be used later for boss rounds –, the <code>spawner_count</code>, defining how many of the current total of 8 spawners should be used for spawning enemies, and of course, <code>enemies</code>, which defines what types of enemies and how many should be spawned in the given round. <code>enemies</code> are defined simply by entering the string paths to their scene file (here, <code>ENEMY_MONKEY</code> is a constant string pointing to the enemy's <code>enemy.tscn</code> file).</p>
|
||||
<p><code>rounds</code> is an array that contains <code>round</code> objects which store the <code>type</code> of round – which is currently unused, but could be used later for boss rounds –, the <code>spawner_count</code>, defining how many of the current total of 8 spawners should be used for spawning enemies, and of course, <code>enemies</code>, which defines what types of enemies and how many should be spawned in the given round. <code>enemies</code> are defined simply by entering the string paths to their scene file (here, <code>ENEMY_MONKEY</code> is a constant string pointing to the enemy's <code>enemy.tscn</code> file).</p>
|
||||
|
||||
<p>This system is actually super easy to use; by defining a <code>spawner_count</code> and <code>enemies</code>, the arena script can figure out how many enemies should be spawned per spawner in order to balance out the spread of enemies. Spawners are picked at random, and enemies are shuffled before being spawned, so that the order entered in the challenge definition doesn't produce same results every time.</p>
|
||||
<p>This system is actually super easy to use; by defining a <code>spawner_count</code> and <code>enemies</code>, the arena script can figure out how many enemies should be spawned per spawner in order to balance out the spread of enemies. Spawners are picked at random, and enemies are shuffled before being spawned, so that the order entered in the challenge definition doesn't produce same results every time.</p>
|
||||
|
||||
<p>A challenge ends once all rounds have been cleared; a round ends once all enemies in a given round have been defeated.</p>
|
||||
<p>A challenge ends once all rounds have been cleared; a round ends once all enemies in a given round have been defeated.</p>
|
||||
|
||||
<h2 id="bad">The Bad</h2>
|
||||
<h2 id="bad">The Bad</h2>
|
||||
|
||||
<ul>
|
||||
<li>I have yet to implement handling for when the player dies during the challenge</li>
|
||||
<li>It all still looks a little janky – although that's to be expected, since I implemented this entire system just a few hours ago, as of writing this webpage</li>
|
||||
<li>It's a bit annoying to fight the enemies with the current, primitive roster of weapons</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>I have yet to implement handling for when the player dies during the challenge</li>
|
||||
<li>It all still looks a little janky – although that's to be expected, since I implemented this entire system just a few hours ago, as of writing this webpage</li>
|
||||
<li>It's a bit annoying to fight the enemies with the current, primitive roster of weapons</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="verdict">Verdict</h2>
|
||||
<h2 id="verdict">Verdict</h2>
|
||||
|
||||
<p>Very happy with my progress today – I got so much done. This was my most productive day in a <i>very</i> long time.</p>
|
||||
<p>Very happy with my progress today – I got so much done. This was my most productive day in a <i>very</i> long time.</p>
|
||||
|
||||
<p>The great thing is that, now that there's an arena challenge, and with it, a constantly spawning stream of enemies attacking the player, the game actually has a proper gameplay loop, in some way! In other words – there's actually something to do now!!</p>
|
||||
<p>The great thing is that, now that there's an arena challenge, and with it, a constantly spawning stream of enemies attacking the player, the game actually has a proper gameplay loop, in some way! In other words – there's actually something to do now!!</p>
|
||||
|
||||
<p>I think that's pretty <a href="https://youtu.be/DrQqajtiRt4">neat</a>.</p>
|
||||
<p>I think that's pretty <a href="https://youtu.be/DrQqajtiRt4">neat</a>.</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,83 +9,85 @@
|
||||
<title>The Behind-the-Scenes Update | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-04-01" subtitle="The Behind-the-Scenes Update" banner="/projects/projectn5/devlog/previews/20240401.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-04-01" subtitle="The Behind-the-Scenes Update" banner="/projects/projectn5/devlog/previews/20240401.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>This is my final update before the next semester begins! I'm actually quite sad about this. For the past few days, I've been really motivated to work on my game. The free time that I had after I finished my last few submissions for university gave me enough room to spend significant time developing. But now that the next semester is about to begin, I fear that university will rob me of a significant amount of my time, and that I will not be able to spend the rest of my time productively.</p>
|
||||
<p>This is my final update before the next semester begins! I'm actually quite sad about this. For the past few days, I've been really motivated to work on my game. The free time that I had after I finished my last few submissions for university gave me enough room to spend significant time developing. But now that the next semester is about to begin, I fear that university will rob me of a significant amount of my time, and that I will not be able to spend the rest of my time productively.</p>
|
||||
|
||||
<p>I do hope that I'll manage, though. A loose goal of mine is to work on my project every single day. I don't know if I'll succeed, but I think it would be beneficial. If I continue work on my game, I'll continue making progress. This progress will motivate me to work on my game, thus progressing development further. We'll see if it works out!</p>
|
||||
<p>I do hope that I'll manage, though. A loose goal of mine is to work on my project every single day. I don't know if I'll succeed, but I think it would be beneficial. If I continue work on my game, I'll continue making progress. This progress will motivate me to work on my game, thus progressing development further. We'll see if it works out!</p>
|
||||
|
||||
<p>This progress update is going to be interesting. I <i>have</i> made quite a bit of progress, but there aren't that many visual changes to show off! A lot of the changes I've implemented are behind-the-scenes stuff.</p>
|
||||
<p>This progress update is going to be interesting. I <i>have</i> made quite a bit of progress, but there aren't that many visual changes to show off! A lot of the changes I've implemented are behind-the-scenes stuff.</p>
|
||||
|
||||
<p>↠ <a href="#venom">Skip to the interesting stuff</a> ↞</p>
|
||||
<p>↠ <a href="#venom">Skip to the interesting stuff</a> ↞</p>
|
||||
|
||||
<h2 id="components">Component-based design</h2>
|
||||
<h2 id="components">Component-based design</h2>
|
||||
|
||||
<p>Like for example, I started implementing a composition-based approach for certain game functions. I've been meaning to implement this for a long time, but I've never really gotten around to it, until I had <a href="https://youtu.be/74y6zWZfQKk">this video by Bitlytic</a> recommended to me today.</p>
|
||||
<p>Like for example, I started implementing a composition-based approach for certain game functions. I've been meaning to implement this for a long time, but I've never really gotten around to it, until I had <a href="https://youtu.be/74y6zWZfQKk">this video by Bitlytic</a> recommended to me today.</p>
|
||||
|
||||
<p>In short, composition means that you have certain components – e.g. health, hitboxes, etc. – that you can attach to any entity that needs them. This is especially useful because it allows for combining components freely without needing to repeat lines of code!</p>
|
||||
<p>In short, composition means that you have certain components – e.g. health, hitboxes, etc. – that you can attach to any entity that needs them. This is especially useful because it allows for combining components freely without needing to repeat lines of code!</p>
|
||||
|
||||
<p>So for example, I have my player and my enemies. They are based on different scripts, but they should both have hitboxes and health handling. What I'm doing now is attaching the components <code>HealthComponent</code> and <code>HitboxComponent</code> to handle these functions.</p>
|
||||
<p>So for example, I have my player and my enemies. They are based on different scripts, but they should both have hitboxes and health handling. What I'm doing now is attaching the components <code>HealthComponent</code> and <code>HitboxComponent</code> to handle these functions.</p>
|
||||
|
||||
<p>I hesitated to implement this design approach in my game because I wasn't sure <i>how</i>, but the video I linked above really helped with its code examples. I took them, modified them (somewhat significantly), and edited a few other elements of my game to make them fit, and now they work quite nicely! On the note of editing other elements,</p>
|
||||
<p>I hesitated to implement this design approach in my game because I wasn't sure <i>how</i>, but the video I linked above really helped with its code examples. I took them, modified them (somewhat significantly), and edited a few other elements of my game to make them fit, and now they work quite nicely! On the note of editing other elements,</p>
|
||||
|
||||
<h2 id="refactoring">Refactoring</h2>
|
||||
<h2 id="refactoring">Refactoring</h2>
|
||||
|
||||
<p>There's no point working on my game if I inevitably end up losing track of the entire project! So, every now and then, I refactor functions, separating things out, and keeping general order. Part of this has been solved through composition, but other things have to be fixed in other ways. For example, a relic of my first few weeks of programming my game was that the <code>HealthBar</code> was handling not only the visual element of showing a health bar on the screen, but it was also responsible for keeping track of how much health the player had, registering healing processes and damage taken. This... didn't make much sense, as the <code>HealthBar</code> was pulling double duty. With the <code>HealthComponent</code> implemented, there was no need for <code>HealthBar</code> to keep track of health anymore, so it was refactored to only handle the displaying of health, simplifying its function significantly.</p>
|
||||
<p>There's no point working on my game if I inevitably end up losing track of the entire project! So, every now and then, I refactor functions, separating things out, and keeping general order. Part of this has been solved through composition, but other things have to be fixed in other ways. For example, a relic of my first few weeks of programming my game was that the <code>HealthBar</code> was handling not only the visual element of showing a health bar on the screen, but it was also responsible for keeping track of how much health the player had, registering healing processes and damage taken. This... didn't make much sense, as the <code>HealthBar</code> was pulling double duty. With the <code>HealthComponent</code> implemented, there was no need for <code>HealthBar</code> to keep track of health anymore, so it was refactored to only handle the displaying of health, simplifying its function significantly.</p>
|
||||
|
||||
<h2 id="preloading">Loading optimisations</h2>
|
||||
<h2 id="preloading">Loading optimisations</h2>
|
||||
|
||||
<p>I replaced a few <code>load()</code> calls with <code>preload()</code>. This is significant insofar that the use of <code>preload()</code> reduces runtime loads – and therefore load spikes – significantly, as resources are pre-loaded (hence the name) and only have to be instantiated at runtime. This yielded a massive performance improvement in the arena, for example, when a dozen enemies have to be spawned at once. Here's an example:</p>
|
||||
<p>I replaced a few <code>load()</code> calls with <code>preload()</code>. This is significant insofar that the use of <code>preload()</code> reduces runtime loads – and therefore load spikes – significantly, as resources are pre-loaded (hence the name) and only have to be instantiated at runtime. This yielded a massive performance improvement in the arena, for example, when a dozen enemies have to be spawned at once. Here's an example:</p>
|
||||
|
||||
<pre class="code-block">
|
||||
var enemies = ["path-to-enemy-0", "path-to-enemy-1", ...]
|
||||
<pre class="code-block">
|
||||
var enemies = ["path-to-enemy-0", "path-to-enemy-1", ...]
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
for enemy_path in enemies {
|
||||
enemy = load(enemy_path).instantiate()
|
||||
}</pre>
|
||||
for enemy_path in enemies {
|
||||
enemy = load(enemy_path).instantiate()
|
||||
}</pre>
|
||||
|
||||
<p>This was my old approach: enemies are declared as path strings and both loaded into memory as well as instantiated at runtime. This meant that, in a round of 12 enemies, the enemy resource(s) had to be loaded 12 times at exactly the moment the last enemy of the previous round died – which is to say, in the middle of gameplay. This caused significant lag. Here's the more optimised solution:</p>
|
||||
<p>This was my old approach: enemies are declared as path strings and both loaded into memory as well as instantiated at runtime. This meant that, in a round of 12 enemies, the enemy resource(s) had to be loaded 12 times at exactly the moment the last enemy of the previous round died – which is to say, in the middle of gameplay. This caused significant lag. Here's the more optimised solution:</p>
|
||||
|
||||
<pre class="code-block">
|
||||
var enemy0 = preload("path-to-enemy-0")
|
||||
var enemy1 = preload("path-to-enemy-1")
|
||||
<pre class="code-block">
|
||||
var enemy0 = preload("path-to-enemy-0")
|
||||
var enemy1 = preload("path-to-enemy-1")
|
||||
|
||||
var enemies = [enemy0, enemy0, enemy1, ...]
|
||||
var enemies = [enemy0, enemy0, enemy1, ...]
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
for enemy_resource in enemies {
|
||||
enemy = enemy_resource.instantiate()
|
||||
}</pre>
|
||||
for enemy_resource in enemies {
|
||||
enemy = enemy_resource.instantiate()
|
||||
}</pre>
|
||||
|
||||
<p>This yielded a great performance boost, as the <code>preload</code>s meant that the enemies were loaded much in advance. These resources could also be used manifold, as they aren't references to instantiated scenes – this only happens with the <code>instantiate()</code> call. So in this case, I could have 6 <code>enemy0</code> and 6 <code>enemy1</code>; both types would be preloaded once (so, two loads in total), and then they could be instantiated afterwards. Lag spikes be gone.</p>
|
||||
<p>This yielded a great performance boost, as the <code>preload</code>s meant that the enemies were loaded much in advance. These resources could also be used manifold, as they aren't references to instantiated scenes – this only happens with the <code>instantiate()</code> call. So in this case, I could have 6 <code>enemy0</code> and 6 <code>enemy1</code>; both types would be preloaded once (so, two loads in total), and then they could be instantiated afterwards. Lag spikes be gone.</p>
|
||||
|
||||
<p>There's more stuff I did: I fixed some memory leaks, visual mistakes, behavioural errors, etc., but writing this only makes me realise that it's probably more interesting to write than to read, so I'll continue with a few (hopefully) more visually appealing points of discussion.</p>
|
||||
<p>There's more stuff I did: I fixed some memory leaks, visual mistakes, behavioural errors, etc., but writing this only makes me realise that it's probably more interesting to write than to read, so I'll continue with a few (hopefully) more visually appealing points of discussion.</p>
|
||||
|
||||
<h2 id="venom">The Venom</h2>
|
||||
<h2 id="venom">The Venom</h2>
|
||||
|
||||
<p>Something visual to intersperse the dry code explanations:</p>
|
||||
<p>Something visual to intersperse the dry code explanations:</p>
|
||||
|
||||
<img alt="An image of an untextured work-in-progress 3D model of a blaster" src="/projects/projectn5/devlog/20240401/venom.webp">
|
||||
<img alt="An image of an untextured work-in-progress 3D model of a blaster" src="/projects/projectn5/devlog/20240401/venom.webp">
|
||||
|
||||
<p>This is an image for a weapon I've come up recently! It's supposed to be a slow-firing but strong blaster, contrasting the rapid-firing but weaker N5 Blaster (which recently changed to an automatic firing mode). The Venom originated from sketches like this, by the way:</p>
|
||||
<p>This is an image for a weapon I've come up recently! It's supposed to be a slow-firing but strong blaster, contrasting the rapid-firing but weaker N5 Blaster (which recently changed to an automatic firing mode). The Venom originated from sketches like this, by the way:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img alt="A REALLY crude sketch of a blaster." src="/projects/projectn5/devlog/20240401/dual_venom_sketch.webp">
|
||||
<img alt="A crude sketch of a blaster resembling the 3D model shown above." src="/projects/projectn5/devlog/20240401/venom_sketch.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img alt="A REALLY crude sketch of a blaster." src="/projects/projectn5/devlog/20240401/dual_venom_sketch.webp">
|
||||
<img alt="A crude sketch of a blaster resembling the 3D model shown above." src="/projects/projectn5/devlog/20240401/venom_sketch.webp">
|
||||
</div>
|
||||
|
||||
<p>The bolt visible in the first sketch actually makes me consider using <a href="/projects/projectn5/devlog/20240323/#new-weapon">the model I showed off recently</a> as the v2 for the Venom (which I would call Antidote by the way, in reference to <a href="https://youtu.be/fbafd6UV3w4">this song</a>).</p>
|
||||
<p>The bolt visible in the first sketch actually makes me consider using <a href="/projects/projectn5/devlog/20240323/#new-weapon">the model I showed off recently</a> as the v2 for the Venom (which I would call Antidote by the way, in reference to <a href="https://youtu.be/fbafd6UV3w4">this song</a>).</p>
|
||||
|
||||
<h2 id="n5-glow">N5 Blaster glow!</h2>
|
||||
<h2 id="n5-glow">N5 Blaster glow!</h2>
|
||||
|
||||
<p>The N5 Blaster got some visual flair! The lights now glow slightly differently, a bit dimmer than before. When the N5 Blaster is fired, its lights glow brightly for a split second, indicating that a shot has been fired! And when the gun is empty, the lights go out and the icosphere (which is meant to be the power source of the gun) is only dimly lit! I really like the effect.</p>
|
||||
<p>The N5 Blaster got some visual flair! The lights now glow slightly differently, a bit dimmer than before. When the N5 Blaster is fired, its lights glow brightly for a split second, indicating that a shot has been fired! And when the gun is empty, the lights go out and the icosphere (which is meant to be the power source of the gun) is only dimly lit! I really like the effect.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240401/n5-glow.mp4" />
|
||||
<img alt="An image of the N5 Blaster. Its lights are turned off, and the icosphere in the middle is dimly glowing." src="/projects/projectn5/devlog/20240401/n5-dim.webp">
|
||||
<Video src="/projects/projectn5/devlog/20240401/n5-glow.mp4" />
|
||||
<img alt="An image of the N5 Blaster. Its lights are turned off, and the icosphere in the middle is dimly glowing." src="/projects/projectn5/devlog/20240401/n5-dim.webp">
|
||||
|
||||
<p>Sorry about the sparse delivery of visually pretty things, but I hope the cool effects on the N5 Blaster make up for it somewhat! I can say for sure though that I'm progressing quite well, and I'm having fun doing so, even if this progress can't really be showed off in the same way I could show off a 3D model or a new enemy. There's lots to come in the future though, especially since I still have to design most of the 12 × 2 = 24 weapon models, a tonne of enemies, the player, and all the levels. There'll be lots to gawk at (hopefully)!</p>
|
||||
<p>Sorry about the sparse delivery of visually pretty things, but I hope the cool effects on the N5 Blaster make up for it somewhat! I can say for sure though that I'm progressing quite well, and I'm having fun doing so, even if this progress can't really be showed off in the same way I could show off a 3D model or a new enemy. There's lots to come in the future though, especially since I still have to design most of the 12 × 2 = 24 weapon models, a tonne of enemies, the player, and all the levels. There'll be lots to gawk at (hopefully)!</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,28 +8,30 @@
|
||||
<title>The WHERE HAVE I BEEN?? Update | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-07-13" subtitle="The WHERE HAVE I BEEN?? Update" banner="/projects/projectn5/devlog/previews/20240713.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-07-13" subtitle="The WHERE HAVE I BEEN?? Update" banner="/projects/projectn5/devlog/previews/20240713.webp" />
|
||||
|
||||
<p>University.</p>
|
||||
<p>University.</p>
|
||||
|
||||
<p>Things have been busy. I had more responsibilities than I assumed this semester. More importantly perhaps, I had more exams <i>during</i> the semester than I assumed. It robbed me of a lot of time and I have virtually not progressed with Project N5 or any other project of mine in the past 3 months.</p>
|
||||
<p>Things have been busy. I had more responsibilities than I assumed this semester. More importantly perhaps, I had more exams <i>during</i> the semester than I assumed. It robbed me of a lot of time and I have virtually not progressed with Project N5 or any other project of mine in the past 3 months.</p>
|
||||
|
||||
<p>I can't express how much I loathe it – I'd much rather work on meaningful, creative tasks than these worthless university submissions and exams, especially considering that I don't feel my university courses contribute anything of value to my education, at least in regards to my future job. In fact, I believe that my lack of time to work on creative projects might have made me forget how rewarding those can be, which in turn has robbed me of motivation to do just that.</p>
|
||||
<p>I can't express how much I loathe it – I'd much rather work on meaningful, creative tasks than these worthless university submissions and exams, especially considering that I don't feel my university courses contribute anything of value to my education, at least in regards to my future job. In fact, I believe that my lack of time to work on creative projects might have made me forget how rewarding those can be, which in turn has robbed me of motivation to do just that.</p>
|
||||
|
||||
<p>The semester has wrapped up, and all that's left is an exam next week (for which I am supposed to study right now – I am currently procrastinating), an oral exam in 3½ weeks, and two submissions due at the start of August and mid-September, respectively. Not exactly fulfilling tasks, I have to admit, but I'll have to push through.</p>
|
||||
<p>The semester has wrapped up, and all that's left is an exam next week (for which I am supposed to study right now – I am currently procrastinating), an oral exam in 3½ weeks, and two submissions due at the start of August and mid-September, respectively. Not exactly fulfilling tasks, I have to admit, but I'll have to push through.</p>
|
||||
|
||||
<p>If there's one positive thing I can report back with, it's that I've been doing pretty well in my exams. I've yet to receive a grade lower than 2.0 this semester (which likely will change once I receive my geography didactics exam grade, but still), and that's despite the fact that I've really not put in the appropriate amount of work for it. Just as my motivation for my creative projects has been dwindling, I've been procrastinating on all my university tasks hardcore.</p>
|
||||
<p>If there's one positive thing I can report back with, it's that I've been doing pretty well in my exams. I've yet to receive a grade lower than 2.0 this semester (which likely will change once I receive my geography didactics exam grade, but still), and that's despite the fact that I've really not put in the appropriate amount of work for it. Just as my motivation for my creative projects has been dwindling, I've been procrastinating on all my university tasks hardcore.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20240713/procrastination.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20240713/procrastination.mp4" />
|
||||
|
||||
<p>Project N5 is not cancelled, though! I'm still confident that work will commence soon! I just have to gather the motivation to actually start working on it again (which is much easier said than done).</p>
|
||||
<p>Project N5 is not cancelled, though! I'm still confident that work will commence soon! I just have to gather the motivation to actually start working on it again (which is much easier said than done).</p>
|
||||
|
||||
<p>Part of my problem, I think, is that I want to start with story and artistic content. For instance, I want to actually create my protagonist! I want to create the character so I can create animations, set up the proper node hierarchy, and just to take cool presentable screenshots of my work. Would it not be a lot cooler if all my devlog screenshots had a fully fleshed-out, poseable character instead of the T-posing temporary character?</p>
|
||||
<p>Part of my problem, I think, is that I want to start with story and artistic content. For instance, I want to actually create my protagonist! I want to create the character so I can create animations, set up the proper node hierarchy, and just to take cool presentable screenshots of my work. Would it not be a lot cooler if all my devlog screenshots had a fully fleshed-out, poseable character instead of the T-posing temporary character?</p>
|
||||
|
||||
<p>For what it's worth, here's a picture of something I printed a few weeks ago. It's an N5 Blaster magnet that's hanging on my PC! I printed it myself, using my new <a href="https://eu.store.bambulab.com/products/a1-mini?variant=49003631083868">Bambu A1 mini 3D printer</a>, and the filament I used is <a href="https://eu.store.bambulab.com/products/pla-galaxy?variant=47730388107612">PLA Galaxy green</a>.</p>
|
||||
<p>For what it's worth, here's a picture of something I printed a few weeks ago. It's an N5 Blaster magnet that's hanging on my PC! I printed it myself, using my new <a href="https://eu.store.bambulab.com/products/a1-mini?variant=49003631083868">Bambu A1 mini 3D printer</a>, and the filament I used is <a href="https://eu.store.bambulab.com/products/pla-galaxy?variant=47730388107612">PLA Galaxy green</a>.</p>
|
||||
|
||||
<img alt="A 3D-printed half of an N5 Blaster that's hanging on the side wall of a PC" src="/projects/projectn5/devlog/20240713/3dprint.webp">
|
||||
<img alt="A 3D-printed half of an N5 Blaster that's hanging on the side wall of a PC" src="/projects/projectn5/devlog/20240713/3dprint.webp">
|
||||
|
||||
<p>I'd love to 3D print more Project N5 weapons – though for that I'll have to design the weapons first!! And in order to do <i>that</i>, I'll have to come up with the ideas for the weapons, which is also proving difficult. A friend suggested to me a while back that I should consider which types of weapons <i>I</i> like in games, and which types I find fun to use.</p>
|
||||
<p>I'd love to 3D print more Project N5 weapons – though for that I'll have to design the weapons first!! And in order to do <i>that</i>, I'll have to come up with the ideas for the weapons, which is also proving difficult. A friend suggested to me a while back that I should consider which types of weapons <i>I</i> like in games, and which types I find fun to use.</p>
|
||||
|
||||
<p>As for now, I should get started with my studies – I'll write my next update once I have more things to present from Project N5, which will (hopefully) be in less than 3 months! Until then~</p>
|
||||
<p>As for now, I should get started with my studies – I'll write my next update once I have more things to present from Project N5, which will (hopefully) be in less than 3 months! Until then~</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,81 +8,83 @@
|
||||
<title>The Returnal Update | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-10-12" subtitle="The Returnal Update" banner="/projects/projectn5/devlog/previews/20241012.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-10-12" subtitle="The Returnal Update" banner="/projects/projectn5/devlog/previews/20241012.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>I'M BACK!!!!</p>
|
||||
<p>I'M BACK!!!!</p>
|
||||
|
||||
<p>For real this time!! I've been busy with university, then I started working on other projects including 3D prints, electronics, a different game, then got busy with university again, and now I FINALLY started work on Project N5 again. And, as I promised in <a href="/projects/projectn5/devlog/20240713/">my last update</a>, it would not take me another 3 months to get back to development – in fact, I undercut that deadline by a whole 24 hours!</p>
|
||||
<p>For real this time!! I've been busy with university, then I started working on other projects including 3D prints, electronics, a different game, then got busy with university again, and now I FINALLY started work on Project N5 again. And, as I promised in <a href="/projects/projectn5/devlog/20240713/">my last update</a>, it would not take me another 3 months to get back to development – in fact, I undercut that deadline by a whole 24 hours!</p>
|
||||
|
||||
<p>Since even though Project N5 was stalled, I gained some more knowledge about and mostly confidence with Godot through another game project I'm working on in parallel with friends, I've kicked off Project N5 development by restructuring a few things. This means there's not that much visual stuff to show so far, but there are some sorely needed mechanical and programmatical under-the-hood improvements.</p>
|
||||
<p>Since even though Project N5 was stalled, I gained some more knowledge about and mostly confidence with Godot through another game project I'm working on in parallel with friends, I've kicked off Project N5 development by restructuring a few things. This means there's not that much visual stuff to show so far, but there are some sorely needed mechanical and programmatical under-the-hood improvements.</p>
|
||||
|
||||
<h2 id="aim-helper">New 2D-Based Aim Helper</h2>
|
||||
<h2 id="aim-helper">New 2D-Based Aim Helper</h2>
|
||||
|
||||
<p>I overhauled the auto aim mechanism (which is now called aim helper). Previously, the aim helper worked by putting a 3D collision shape in front of the gun, registering all collisions within this cone, and determining a target by calculating the shortest distance between the player and the enemies. Here's a visual of the old cone at the tip of the N5 Blaster:</p>
|
||||
<p>I overhauled the auto aim mechanism (which is now called aim helper). Previously, the aim helper worked by putting a 3D collision shape in front of the gun, registering all collisions within this cone, and determining a target by calculating the shortest distance between the player and the enemies. Here's a visual of the old cone at the tip of the N5 Blaster:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241012/cone.webp">
|
||||
<img src="/projects/projectn5/devlog/20241012/cone.webp">
|
||||
|
||||
<p>This was a good solution, because it allowed for targetting enemies without much effort – add an enemy to the 'targetable' group and let the aim helper script take care of it. However, customisation proved difficult. Since the collider was a 3D shape, a new 3D shape would have to be created for every weapon and every upgrade that demanded a unique shape. While this offered flexibility, it proved cumbersome in execution. Cones could only be changed in scale uniformally, which means that, while they can be changed in size, no single dimension could be changed without causing bugs. Keeping X and Y while increasing the Z distance would mandate a whole new shape. Furthermore, the cone would have to be manually rotated and positioned in front of the gun every frame, which wasn't particularly elegant.</p>
|
||||
<p>This was a good solution, because it allowed for targetting enemies without much effort – add an enemy to the 'targetable' group and let the aim helper script take care of it. However, customisation proved difficult. Since the collider was a 3D shape, a new 3D shape would have to be created for every weapon and every upgrade that demanded a unique shape. While this offered flexibility, it proved cumbersome in execution. Cones could only be changed in scale uniformally, which means that, while they can be changed in size, no single dimension could be changed without causing bugs. Keeping X and Y while increasing the Z distance would mandate a whole new shape. Furthermore, the cone would have to be manually rotated and positioned in front of the gun every frame, which wasn't particularly elegant.</p>
|
||||
|
||||
<p>Thus, a new solution was born: a 2D approach to the aim helper!</p>
|
||||
<p>Thus, a new solution was born: a 2D approach to the aim helper!</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241012/aim_helper.webp">
|
||||
<img src="/projects/projectn5/devlog/20241012/aim_helper.webp">
|
||||
|
||||
<p>The way the new aim helper works is by putting a 2D collision shape on the screen of the player. All enemies contain a 2D shape as well, which is unprojected onto the screen by the player camera. This means that the 2D shapes are positioned on top of the 3D characters. As soon as the player's collision shape collides with one of the enemies', it's added to the list of collisions and the shortest distance is calculated. This procedure hasn't changed between the 3D and 2D approaches.</p>
|
||||
<p>The way the new aim helper works is by putting a 2D collision shape on the screen of the player. All enemies contain a 2D shape as well, which is unprojected onto the screen by the player camera. This means that the 2D shapes are positioned on top of the 3D characters. As soon as the player's collision shape collides with one of the enemies', it's added to the list of collisions and the shortest distance is calculated. This procedure hasn't changed between the 3D and 2D approaches.</p>
|
||||
|
||||
<p>Using this 2D shape is a lot simpler, however, because it allows for much easier changes of the collision shape. Using just a circle, the diameter can be changed by just changing one variable, and the max distance can be changed with another variable – much more easily configurable than modelling new cones! And new shapes can easily be created using 1-bit (black and white) bitmaps instead of 3D shapes.</p>
|
||||
<p>Using this 2D shape is a lot simpler, however, because it allows for much easier changes of the collision shape. Using just a circle, the diameter can be changed by just changing one variable, and the max distance can be changed with another variable – much more easily configurable than modelling new cones! And new shapes can easily be created using 1-bit (black and white) bitmaps instead of 3D shapes.</p>
|
||||
|
||||
<p>There's also a blue line shooting out of the gun in the picture above. That's a raycast spanning from the player to the targetted enemy, checking whether a wall is obstructing line of sight. Enemies can no longer be targetted if they're behind a wall or similar.</p>
|
||||
<p>There's also a blue line shooting out of the gun in the picture above. That's a raycast spanning from the player to the targetted enemy, checking whether a wall is obstructing line of sight. Enemies can no longer be targetted if they're behind a wall or similar.</p>
|
||||
|
||||
<h2 id="n5-icons">Overhauled N5 Weapon Icons</h2>
|
||||
<h2 id="n5-icons">Overhauled N5 Weapon Icons</h2>
|
||||
|
||||
<p>The N5 Blaster received an overhauled icon. The soon-to-be-implemented N5 Bomb Launcher also received its own icon!</p>
|
||||
<p>The N5 Blaster received an overhauled icon. The soon-to-be-implemented N5 Bomb Launcher also received its own icon!</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241012/n5-blaster-icon.webp">
|
||||
<img src="/projects/projectn5/devlog/20241012/n5-bomb-launcher-icon.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241012/n5-blaster-icon.webp">
|
||||
<img src="/projects/projectn5/devlog/20241012/n5-bomb-launcher-icon.webp">
|
||||
</div>
|
||||
|
||||
<p>I changed the icosphere by tracing its 3D counterpart (the ball inside the N5 Blaster's glass tube) from a different point of view. It wasn't symmetrical before – it is now.</p>
|
||||
<p>I changed the icosphere by tracing its 3D counterpart (the ball inside the N5 Blaster's glass tube) from a different point of view. It wasn't symmetrical before – it is now.</p>
|
||||
|
||||
<p>Admittedly, seeing the two icons side-by-side... they look damn similar. I think they might be difficult to tell apart in-game. One of these icons will be changed most likely. I'm also considering using the right icon for the N5 Blaster instead, maybe.</p>
|
||||
<p>Admittedly, seeing the two icons side-by-side... they look damn similar. I think they might be difficult to tell apart in-game. One of these icons will be changed most likely. I'm also considering using the right icon for the N5 Blaster instead, maybe.</p>
|
||||
|
||||
<p>The idea with these weapons is that they're both N5 series weapons – they are supposed to be similar in style to the protagonist and be default gear. Perhaps both of them will be available from the start of the game. They're basic weapons like the Lancer and Gravity Bomb in Ratchet & Clank 2, for instance.</p>
|
||||
<p>The idea with these weapons is that they're both N5 series weapons – they are supposed to be similar in style to the protagonist and be default gear. Perhaps both of them will be available from the start of the game. They're basic weapons like the Lancer and Gravity Bomb in Ratchet & Clank 2, for instance.</p>
|
||||
|
||||
<h2 id="minor-changes">Minor Changes</h2>
|
||||
<h2 id="minor-changes">Minor Changes</h2>
|
||||
|
||||
<h3 id="signal-bus">Hopping on the Signal Bus</h3>
|
||||
<h3 id="signal-bus">Hopping on the Signal Bus</h3>
|
||||
|
||||
<p>Minor change, but I overhauled the inventory by removing complicated signal lines and simplifying them through a <code>SignalBus</code> singleton.</p>
|
||||
<p>Minor change, but I overhauled the inventory by removing complicated signal lines and simplifying them through a <code>SignalBus</code> singleton.</p>
|
||||
|
||||
<p>Previously, in order to change weapons, the quick select menu would directly interact with the inventory; the weapons menu would signal to the pause menu, and the pause menu would thus interact with the inventory. This was unnecessarily complicated.</p>
|
||||
<p>Previously, in order to change weapons, the quick select menu would directly interact with the inventory; the weapons menu would signal to the pause menu, and the pause menu would thus interact with the inventory. This was unnecessarily complicated.</p>
|
||||
|
||||
<p>Instead, I'm now using a <code>SignalBus</code> containing a signal <code>on_player_equip()</code> that can easily be triggered by the quick select and weapons menus without a direct connection to the inventory. In order to receive these signals, the inventory connects one of its functions to the signal in <code>SignalBus</code>, consolidating functions such as <code>on_quick_select_item_equipped()</code>, <code>on_weapons_menu_item_equipped()</code>, etc.</p>
|
||||
<p>Instead, I'm now using a <code>SignalBus</code> containing a signal <code>on_player_equip()</code> that can easily be triggered by the quick select and weapons menus without a direct connection to the inventory. In order to receive these signals, the inventory connects one of its functions to the signal in <code>SignalBus</code>, consolidating functions such as <code>on_quick_select_item_equipped()</code>, <code>on_weapons_menu_item_equipped()</code>, etc.</p>
|
||||
|
||||
<p>This <code>SignalBus</code> isn't even new in my game; I've previously already used it for the aim helper described above! Using such a bus is genuinely useful for any kind of Godot game that needs to allow communication between nodes that have no direct connection to one another. It's much more convenient – and safe! – than fetching nodes directly by their path, like <code>get_node("/root/Main/Level/Player/CharacterBody3D/Inventory")</code>. Imagine you change just one of these nodes' names a few weeks down the line. Nightmare to debug.</p>
|
||||
<p>This <code>SignalBus</code> isn't even new in my game; I've previously already used it for the aim helper described above! Using such a bus is genuinely useful for any kind of Godot game that needs to allow communication between nodes that have no direct connection to one another. It's much more convenient – and safe! – than fetching nodes directly by their path, like <code>get_node("/root/Main/Level/Player/CharacterBody3D/Inventory")</code>. Imagine you change just one of these nodes' names a few weeks down the line. Nightmare to debug.</p>
|
||||
|
||||
<h3 id="strafing">Strafing Like a Gladiator</h3>
|
||||
<h3 id="strafing">Strafing Like a Gladiator</h3>
|
||||
|
||||
<p>Another minor change that affects gameplay more so than code: the player now strafes automatically when having a weapon equipped. This emulates the strafing behaviour in Ratchet: Gladiator, which may have been influenced by the fact that I've been playing this game a bunch these past few days... on Exterminator difficulty, no less. Not easy, but really fun.</p>
|
||||
<p>Another minor change that affects gameplay more so than code: the player now strafes automatically when having a weapon equipped. This emulates the strafing behaviour in Ratchet: Gladiator, which may have been influenced by the fact that I've been playing this game a bunch these past few days... on Exterminator difficulty, no less. Not easy, but really fun.</p>
|
||||
|
||||
<p>Conveniently, forcing strafing when holding a weapon elminiates the need to fix bugs related to strafing – for example, if the player doesn't strafe, or doesn't stop strafing. Though I may need to change this behaviour again if I decide to introduce gadgets.</p>
|
||||
<p>Conveniently, forcing strafing when holding a weapon elminiates the need to fix bugs related to strafing – for example, if the player doesn't strafe, or doesn't stop strafing. Though I may need to change this behaviour again if I decide to introduce gadgets.</p>
|
||||
|
||||
<h2 id="whats-next">What's Next?</h2>
|
||||
<h2 id="whats-next">What's Next?</h2>
|
||||
|
||||
<p>It's not quite certain, but I have ideas. Next on my agenda is, for example, continuing to clean up the project. I think there's a lot of streamlining I can do using signals, the <code>SignalBus</code>, and overall just writing more cohesive code. I've come a long way since I started this game project 13 or so months ago, after all.</p>
|
||||
<p>It's not quite certain, but I have ideas. Next on my agenda is, for example, continuing to clean up the project. I think there's a lot of streamlining I can do using signals, the <code>SignalBus</code>, and overall just writing more cohesive code. I've come a long way since I started this game project 13 or so months ago, after all.</p>
|
||||
|
||||
<p>I also want to implement more visual things. I've been meaning to 3D model again, creating crates, a new ammo pickup, and even some weapons. Of course, I'd also love to create a new, more final protagonist, but ideas are slow to come. Still, there are some I've newly come up with or written down. The N5 Bomb Launcher especially is something I want to implement soon. Since it's a thrower-type weapon, meaning it fires its shots in an arch and targetting the floor, there's a little bit of work involved to make that happen. I've been thinking about possible approaches to this lately, and I think I might settle on a pre-baked curve/collision mesh, because I think the PS2 Ratchet & Clank games may be using a similar approach.</p>
|
||||
<p>I also want to implement more visual things. I've been meaning to 3D model again, creating crates, a new ammo pickup, and even some weapons. Of course, I'd also love to create a new, more final protagonist, but ideas are slow to come. Still, there are some I've newly come up with or written down. The N5 Bomb Launcher especially is something I want to implement soon. Since it's a thrower-type weapon, meaning it fires its shots in an arch and targetting the floor, there's a little bit of work involved to make that happen. I've been thinking about possible approaches to this lately, and I think I might settle on a pre-baked curve/collision mesh, because I think the PS2 Ratchet & Clank games may be using a similar approach.</p>
|
||||
|
||||
<p>Here's a sneak peek at an ammo pickup I started working on recently:</p>
|
||||
<p>Here's a sneak peek at an ammo pickup I started working on recently:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241012/ammo.webp">
|
||||
<img src="/projects/projectn5/devlog/20241012/ammo.webp">
|
||||
|
||||
<p>And of course, there's always the struggle of motivation. With my new game project, I have the fortune of working with two other people who also do work. We can motivate one another, since we're all interested in developing the game further. I don't have this with Project N5. At least as far as I know, I'm the only one who's really interested in seeing this game flourish, so there's no real option for me to gain motivation through other people. It's difficult, and I don't quite know how to deal with it. I've also considered uploading snippets onto my Instagram, but even disregarding my dislike for the platform, I don't think anyone would really care – I've uploaded snippets in the past already, to little resonance. I don't blame other people, but it just illustrates that I need to have intrinsic motivation to continue work on Project N5.</p>
|
||||
<p>And of course, there's always the struggle of motivation. With my new game project, I have the fortune of working with two other people who also do work. We can motivate one another, since we're all interested in developing the game further. I don't have this with Project N5. At least as far as I know, I'm the only one who's really interested in seeing this game flourish, so there's no real option for me to gain motivation through other people. It's difficult, and I don't quite know how to deal with it. I've also considered uploading snippets onto my Instagram, but even disregarding my dislike for the platform, I don't think anyone would really care – I've uploaded snippets in the past already, to little resonance. I don't blame other people, but it just illustrates that I need to have intrinsic motivation to continue work on Project N5.</p>
|
||||
|
||||
<p>That's where my idea of adding visual things came from, by the way. By making visually (or sonically, for that matter) distinct changes, such as through introducing new meshes and models, I could <i>see</i> my progress much more clearly than I can now. Perhaps by gauging my progress through visuals, I could lift my motivation?</p>
|
||||
<p>That's where my idea of adding visual things came from, by the way. By making visually (or sonically, for that matter) distinct changes, such as through introducing new meshes and models, I could <i>see</i> my progress much more clearly than I can now. Perhaps by gauging my progress through visuals, I could lift my motivation?</p>
|
||||
|
||||
<p>Then again, in order to create visual things, I'll have to have motivation from the start, so we're in a bit of a pickle here.</p>
|
||||
<p>Then again, in order to create visual things, I'll have to have motivation from the start, so we're in a bit of a pickle here.</p>
|
||||
|
||||
<p>I can do this.</p>
|
||||
<p>I can do this.</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,140 +9,142 @@
|
||||
<title>The Visual Update | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-11-03" subtitle="The Visual Update" banner="/projects/projectn5/devlog/20241103/101-comparison.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-11-03" subtitle="The Visual Update" banner="/projects/projectn5/devlog/20241103/101-comparison.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>As promised, I've been working on a few visual things! There's not <i>that</i> much to show yet, but I have a model or two to show, plus a lot more to talk about in terms of where I want to take the game.</p>
|
||||
<p>As promised, I've been working on a few visual things! There's not <i>that</i> much to show yet, but I have a model or two to show, plus a lot more to talk about in terms of where I want to take the game.</p>
|
||||
|
||||
<p>Before this, though, here's some progress in the coding department (that's where I'm best at):</p>
|
||||
<p>Before this, though, here's some progress in the coding department (that's where I'm best at):</p>
|
||||
|
||||
<h2 id="node-chains">Simplifying Node Chains</h2>
|
||||
<h2 id="node-chains">Simplifying Node Chains</h2>
|
||||
|
||||
<p>Behind-the-scenes, I've been steadily working at overhauling and refactoring some of my code. I wrote the majority of my game's scripts 6 to 12 months ago, and some of it hasn't aged that well. Complicated code structures and wonky node paths such as <code>get_node("/root/Main/LevelParent/Level/Camera/AimRayCastContainer/AimRayCast3D")</code> aren't things I want to maintain, so I'm trying my best to implement more best-practices – or at least better-practices.</p>
|
||||
<p>Behind-the-scenes, I've been steadily working at overhauling and refactoring some of my code. I wrote the majority of my game's scripts 6 to 12 months ago, and some of it hasn't aged that well. Complicated code structures and wonky node paths such as <code>get_node("/root/Main/LevelParent/Level/Camera/AimRayCastContainer/AimRayCast3D")</code> aren't things I want to maintain, so I'm trying my best to implement more best-practices – or at least better-practices.</p>
|
||||
|
||||
<p>One challenge I faced was referencing a node that has no clear direct relationship to the one I'm calling it from. Picture this node chain:</p>
|
||||
<p>One challenge I faced was referencing a node that has no clear direct relationship to the one I'm calling it from. Picture this node chain:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/node_chain.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/node_chain.webp">
|
||||
|
||||
<p>Say, for example, that I'm writing a script in <code>Automatic</code> – that's the node that handles projectile spawning and their direction in automatic weapons, among other things – and I need to reference <code>AimRayCast3D</code> to determine in which direction the projectile needs to be fired. Reasonable use case, seen as the <code>RayCast3D</code> is attached to the <code>Camera3D</code> to point exactly where the player is facing – except there's no real path I can follow to get to that node. Their closest relative is <code>Level</code>, which is the root node of the level, and no less than <b>eight nodes away</b> from <code>Automatic</code>! It's possible to retrieve the node in this way, starting from <code>Automatic</code>, but it's not pretty...</p>
|
||||
<p>Say, for example, that I'm writing a script in <code>Automatic</code> – that's the node that handles projectile spawning and their direction in automatic weapons, among other things – and I need to reference <code>AimRayCast3D</code> to determine in which direction the projectile needs to be fired. Reasonable use case, seen as the <code>RayCast3D</code> is attached to the <code>Camera3D</code> to point exactly where the player is facing – except there's no real path I can follow to get to that node. Their closest relative is <code>Level</code>, which is the root node of the level, and no less than <b>eight nodes away</b> from <code>Automatic</code>! It's possible to retrieve the node in this way, starting from <code>Automatic</code>, but it's not pretty...</p>
|
||||
|
||||
<p><code>var _ray_cast = get_node("../../../../../../../../Camera/AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
<p><code>var _ray_cast = get_node("../../../../../../../../Camera/AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
|
||||
<p>Imagine if any of these nodes has their name changed – or worse, if the order of nodes is changed. It <i>could</i> spell disaster. This method grabs the node relative to <code>Automatic</code>, which means it relies on this specific count of nodes as well as the names of the nodes, starting at <code>Camera</code>. We could switch this around:</p>
|
||||
<p>Imagine if any of these nodes has their name changed – or worse, if the order of nodes is changed. It <i>could</i> spell disaster. This method grabs the node relative to <code>Automatic</code>, which means it relies on this specific count of nodes as well as the names of the nodes, starting at <code>Camera</code>. We could switch this around:</p>
|
||||
|
||||
<p><code>var _ray_cast = get_node("/root/Main/LevelParent/Level/Camera/AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
<p><code>var _ray_cast = get_node("/root/Main/LevelParent/Level/Camera/AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
|
||||
<p>...but now we're reliant on the order starting from the root node (from the top), plus we now have to be wary of even more node names, so this is no good either. For quick testing, sure, but not to be implemented in a production release – hopefully. How do we fix this? I thought of using a singleton script that holds references to the most important nodes (level parent, player, camera) to retrieve nodes relative to them:</p>
|
||||
<p>...but now we're reliant on the order starting from the root node (from the top), plus we now have to be wary of even more node names, so this is no good either. For quick testing, sure, but not to be implemented in a production release – hopefully. How do we fix this? I thought of using a singleton script that holds references to the most important nodes (level parent, player, camera) to retrieve nodes relative to them:</p>
|
||||
|
||||
<p><code>var _ray_cast = GlobalReferences.camera.get_node("AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
<p><code>var _ray_cast = GlobalReferences.camera.get_node("AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
|
||||
<p>This <i>is</i> a lot more streamlined, but... it doesn't work. You need to initialise the <code>camera</code> variable at some point after the level has loaded, but before the variable is used. If you use the variable in any <code>_ready()</code> call, then you're hosed, because you must initialise the variables in the level's <code>_ready()</code> and you cannot be certain that the level has its <code>_ready()</code> function called in time for the other node to retrieve a proper reference in <code>camera</code> instead of <code>null</code>.</p>
|
||||
<p>This <i>is</i> a lot more streamlined, but... it doesn't work. You need to initialise the <code>camera</code> variable at some point after the level has loaded, but before the variable is used. If you use the variable in any <code>_ready()</code> call, then you're hosed, because you must initialise the variables in the level's <code>_ready()</code> and you cannot be certain that the level has its <code>_ready()</code> function called in time for the other node to retrieve a proper reference in <code>camera</code> instead of <code>null</code>.</p>
|
||||
|
||||
<p>Instead, we can use the function <code>get_first_node_in_group()</code> on the <code>SceneTree</code> to retrieve <i>any</i> node! We just have to make sure that the node has a group name that is unique to it within the <code>SceneTree</code> – in the case of a level camera, that's a given. Having multiple nodes with this group name is also possible by using <code>get_nodes_in_group()</code> and then filtering the returned array by, for example, checking its class name.</p>
|
||||
<p>Instead, we can use the function <code>get_first_node_in_group()</code> on the <code>SceneTree</code> to retrieve <i>any</i> node! We just have to make sure that the node has a group name that is unique to it within the <code>SceneTree</code> – in the case of a level camera, that's a given. Having multiple nodes with this group name is also possible by using <code>get_nodes_in_group()</code> and then filtering the returned array by, for example, checking its class name.</p>
|
||||
|
||||
<p><code>var _ray_cast = get_tree().get_first_node_in_group("level_camera").get_node("AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
<p><code>var _ray_cast = get_tree().get_first_node_in_group("level_camera").get_node("AimRayCastContainer/AimRayCast3D")</code></p>
|
||||
|
||||
<p>Almost there! We can pretty this up by adding two more things:</p>
|
||||
<p>Almost there! We can pretty this up by adding two more things:</p>
|
||||
|
||||
<ul>
|
||||
<li>Turn <code>"level_camera"</code> into a constant. I did this by creating a global class called <code>Groups</code> and adding:<br><code>const LEVEL_CAMERA: String = "level_camera"</code><br>This simplifies changing group names, though keep in mind that this constant cannot be used inside the node's group assignment, meaning that, if you do change the name, you will have to change it in at least two places (the node and the constant).</li>
|
||||
<li>Remove the <code>get_node("AimRayCastContainer/AimRayCast3D")</code> call and replace it with a variable call. Inside the camera's script, we can add a variable referencing <code>AimRayCast3D</code> quite easily because it's a child of the camera. Add to the camera script: <br><code>@onready var aim_ray_cast: RayCast3D = $AimRayCastContainer/AimRayCast3D</code><br>And then use <code>camera.aim_ray_cast</code> to retrieve it. Remember to add <code>@onready</code> because the node cannot be retrieved before <code>_ready()</code> is called.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Turn <code>"level_camera"</code> into a constant. I did this by creating a global class called <code>Groups</code> and adding:<br><code>const LEVEL_CAMERA: String = "level_camera"</code><br>This simplifies changing group names, though keep in mind that this constant cannot be used inside the node's group assignment, meaning that, if you do change the name, you will have to change it in at least two places (the node and the constant).</li>
|
||||
<li>Remove the <code>get_node("AimRayCastContainer/AimRayCast3D")</code> call and replace it with a variable call. Inside the camera's script, we can add a variable referencing <code>AimRayCast3D</code> quite easily because it's a child of the camera. Add to the camera script: <br><code>@onready var aim_ray_cast: RayCast3D = $AimRayCastContainer/AimRayCast3D</code><br>And then use <code>camera.aim_ray_cast</code> to retrieve it. Remember to add <code>@onready</code> because the node cannot be retrieved before <code>_ready()</code> is called.</li>
|
||||
</ul>
|
||||
|
||||
<p>In the end, we have the following statement:</p>
|
||||
<p>In the end, we have the following statement:</p>
|
||||
|
||||
<p><code>var _ray_cast = get_tree().get_first_node_in_group(Groups.LEVEL_CAMERA).aim_ray_cast</code></p>
|
||||
<p><code>var _ray_cast = get_tree().get_first_node_in_group(Groups.LEVEL_CAMERA).aim_ray_cast</code></p>
|
||||
|
||||
<p>We can use this <i>anywhere</i> in our game to retrieve the node, as long as it exists within the scene tree!</p>
|
||||
<p>We can use this <i>anywhere</i> in our game to retrieve the node, as long as it exists within the scene tree!</p>
|
||||
|
||||
<h2 id="buttmuncher7">ButtMuncher7's Approach to Projectiles</h2>
|
||||
<h2 id="buttmuncher7">ButtMuncher7's Approach to Projectiles</h2>
|
||||
|
||||
<p>A while back, ButtMuncher7 on YouTube uploaded a video on <a href="https://youtu.be/0rTI_UUfB-E?t=89">projectiles in video games</a>. They use the Godot engine as well, so anything they implement, I can implement as well. The issue they faced was that projectiles often fly through walls a bit before colliding, since they may move past an object's surface between frames. I finally got around to implementing their solution, which worked quite well: you add a raycast to the projectile pointing from its current location to its last location, see if collides with anything, and if it does, you move the projectile to that position. It's quite a neat solution!</p>
|
||||
<p>A while back, ButtMuncher7 on YouTube uploaded a video on <a href="https://youtu.be/0rTI_UUfB-E?t=89">projectiles in video games</a>. They use the Godot engine as well, so anything they implement, I can implement as well. The issue they faced was that projectiles often fly through walls a bit before colliding, since they may move past an object's surface between frames. I finally got around to implementing their solution, which worked quite well: you add a raycast to the projectile pointing from its current location to its last location, see if collides with anything, and if it does, you move the projectile to that position. It's quite a neat solution!</p>
|
||||
|
||||
<h2 id="sky">Lighten the Mood</h2>
|
||||
<h2 id="sky">Lighten the Mood</h2>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/sky.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/sky.webp">
|
||||
|
||||
<p>I changed the sky to be brighter and more friendly in the Unity test level. This doesn't serve the game in its final form in any way, it's just a measure I took to <a href="/projects/projectn5/devlog/20241012/#whats-next">give myself the impression that a lot has changed</a>, since the game has visually changed.</p>
|
||||
<p>I changed the sky to be brighter and more friendly in the Unity test level. This doesn't serve the game in its final form in any way, it's just a measure I took to <a href="/projects/projectn5/devlog/20241012/#whats-next">give myself the impression that a lot has changed</a>, since the game has visually changed.</p>
|
||||
|
||||
<p>Interestingly though, this did give me ideas. This sky shader has a setting for cloud fuzziness, which, when turned down, gives the clouds a more toon-like aesthetic (pictured here). This is great, because this is actually an aesthetic direction I had recently decided to pursue with Project N5.</p>
|
||||
<p>Interestingly though, this did give me ideas. This sky shader has a setting for cloud fuzziness, which, when turned down, gives the clouds a more toon-like aesthetic (pictured here). This is great, because this is actually an aesthetic direction I had recently decided to pursue with Project N5.</p>
|
||||
|
||||
<h2 id="planets">Create New World</h2>
|
||||
<h2 id="planets">Create New World</h2>
|
||||
|
||||
<p>I discovered this <a href="https://deep-fold.itch.io/pixel-planet-generator">insanely cool planet generator</a> by Deep-Fold on itch.io. It's a <i>pixel</i> planet generator, strictly speaking, but since its output is just determined by generated noise (I think), the resolution can be increased much further to create sharp toon-like planets. Here's one I generated that I quite liked:</p>
|
||||
<p>I discovered this <a href="https://deep-fold.itch.io/pixel-planet-generator">insanely cool planet generator</a> by Deep-Fold on itch.io. It's a <i>pixel</i> planet generator, strictly speaking, but since its output is just determined by generated noise (I think), the resolution can be increased much further to create sharp toon-like planets. Here's one I generated that I quite liked:</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20241103/planet.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20241103/planet.mp4" />
|
||||
|
||||
<p>This shader made me think that I really do want planets to be present in my game similar to how Ratchet & Clank does it – on the starmap as well as when flying towards the planets. Maybe you could even see a planet if you look into the sky from another planet's surface?</p>
|
||||
<p>This shader made me think that I really do want planets to be present in my game similar to how Ratchet & Clank does it – on the starmap as well as when flying towards the planets. Maybe you could even see a planet if you look into the sky from another planet's surface?</p>
|
||||
|
||||
<p>I'm unsure how I feel about using someone else's generator in my own game, though, so I followed a <a href="https://docs.godotengine.org/en/stable/tutorials/shaders/using_viewport_as_texture.html">tutorial</a> I found in the Godot documentation by coincidence – I wanted to look up something for an entirely different game. The result:</p>
|
||||
<p>I'm unsure how I feel about using someone else's generator in my own game, though, so I followed a <a href="https://docs.godotengine.org/en/stable/tutorials/shaders/using_viewport_as_texture.html">tutorial</a> I found in the Godot documentation by coincidence – I wanted to look up something for an entirely different game. The result:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/planet-mine.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/planet-mine.webp">
|
||||
|
||||
<p>...it's a work-in-progress. A relatively decent start though! I think there's potential.</p>
|
||||
<p>...it's a work-in-progress. A relatively decent start though! I think there's potential.</p>
|
||||
|
||||
<p>The debate of "should I use someone else's work in my own?" is one I find myself debating frequently, actually. It's always been a problem with me, and I think it started with using other people's samples and synth patches in my music, which I did do, but tried to avoid rather frequently. This sentiment still holds true to this day, whether it's in music, 3D modelling, or... literally any of the rubbish generated by AI these days. I think a healthy dose of attempting to create things on your own is good though, because it allows you to both expand your own skillset and adapt the work to your own vision much more easily than if you had to modify an existing work you didn't create.</p>
|
||||
<p>The debate of "should I use someone else's work in my own?" is one I find myself debating frequently, actually. It's always been a problem with me, and I think it started with using other people's samples and synth patches in my music, which I did do, but tried to avoid rather frequently. This sentiment still holds true to this day, whether it's in music, 3D modelling, or... literally any of the rubbish generated by AI these days. I think a healthy dose of attempting to create things on your own is good though, because it allows you to both expand your own skillset and adapt the work to your own vision much more easily than if you had to modify an existing work you didn't create.</p>
|
||||
|
||||
<p>No harm in studying other people's work though – in fact, I'd say that's super beneficial! Don't fall into the trap of "good artists copy, great artists steal"; go for "great artists are inspired by other people's works and incorporate this into their own works" instead. Doesn't roll off the tongue quite as nicely though.</p>
|
||||
<p>No harm in studying other people's work though – in fact, I'd say that's super beneficial! Don't fall into the trap of "good artists copy, great artists steal"; go for "great artists are inspired by other people's works and incorporate this into their own works" instead. Doesn't roll off the tongue quite as nicely though.</p>
|
||||
|
||||
<h2 id="remeshing">Remeshing</h2>
|
||||
<h2 id="remeshing">Remeshing</h2>
|
||||
|
||||
<p>Continuing the streak of visual elements, I worked on the N5 Blaster... again. This time I didn't tweak its visuals much, however; I modelled it from scratch to fix its terrible meshes.</p>
|
||||
<p>Continuing the streak of visual elements, I worked on the N5 Blaster... again. This time I didn't tweak its visuals much, however; I modelled it from scratch to fix its terrible meshes.</p>
|
||||
|
||||
<p>Back when I modelled the N5 Blaster around a year ago, I didn't have much experience in using Blender. Thus, it wasn't modelled very well. The model consisted of 8 parts for the body, 3 or 4 parts for the grip, and the icosphere spinning in the middle of the gun. My goal today was to recreate the N5 Blaster with a more streamlined mesh, and I must say, I achieved my goal quite well: the gun now consists of one mesh for the body, one for the grip, and another for the icosphere.</p>
|
||||
<p>Back when I modelled the N5 Blaster around a year ago, I didn't have much experience in using Blender. Thus, it wasn't modelled very well. The model consisted of 8 parts for the body, 3 or 4 parts for the grip, and the icosphere spinning in the middle of the gun. My goal today was to recreate the N5 Blaster with a more streamlined mesh, and I must say, I achieved my goal quite well: the gun now consists of one mesh for the body, one for the grip, and another for the icosphere.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/101-comparison.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">left: new, right: old</span>
|
||||
</div>
|
||||
<img src="/projects/projectn5/devlog/20241103/101-comparison.webp">
|
||||
<div class="image-subtitle-container">
|
||||
<span class="image-subtitle">left: new, right: old</span>
|
||||
</div>
|
||||
|
||||
<p>With this change, I also adjusted the material slightly. The gun has a more matte look and the grip is more rounded. I should say that the blue glass is only a temporary material I assigned within Blender; it's transparent in-engine to display the icosphere hiding within.</p>
|
||||
<p>With this change, I also adjusted the material slightly. The gun has a more matte look and the grip is more rounded. I should say that the blue glass is only a temporary material I assigned within Blender; it's transparent in-engine to display the icosphere hiding within.</p>
|
||||
|
||||
<p>Also of note is the reduced tri count I achieved by optimising the model: I managed to push the tris down from 2,520 to... 2,510. Of course, reducing tri count wasn't the primary objective, I just thought this minuscule reduction was somewhat amusing.</p>
|
||||
<p>Also of note is the reduced tri count I achieved by optimising the model: I managed to push the tris down from 2,520 to... 2,510. Of course, reducing tri count wasn't the primary objective, I just thought this minuscule reduction was somewhat amusing.</p>
|
||||
|
||||
<p>Oh and, with this change, I think I decided on the upgraded version of the N5 Blaster: instead of changing into a bigger weapon, I think it'd be neat if the character would use two of the blasters when upgraded. I like the look of the two blasters side-by-side in the picture above.</p>
|
||||
<p>Oh and, with this change, I think I decided on the upgraded version of the N5 Blaster: instead of changing into a bigger weapon, I think it'd be neat if the character would use two of the blasters when upgraded. I like the look of the two blasters side-by-side in the picture above.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/101-profile.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/101-profile.webp">
|
||||
|
||||
<h2 id="canister">Need Some Ammo?</h2>
|
||||
<h2 id="canister">Need Some Ammo?</h2>
|
||||
|
||||
<p>After I introduced a <a href="/projects/projectn5/devlog/20241012/#whats-next">new ammo crate in the last devlog</a>, I completely overhauled its look. It's now quite different, more simplistic in its mesh, and it's so round, I stopped calling it crate and started naming it canister.</p>
|
||||
<p>After I introduced a <a href="/projects/projectn5/devlog/20241012/#whats-next">new ammo crate in the last devlog</a>, I completely overhauled its look. It's now quite different, more simplistic in its mesh, and it's so round, I stopped calling it crate and started naming it canister.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/canister.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/canister.webp">
|
||||
|
||||
<p>It's simple! But I kinda like it that way. Plus, neat feature: the canister displays the icon of the weapon for which it holds ammo! So far, only the N5 Bomb Launcher's icon is implemented, but others are easy to put in once I create icons for more weapons.</p>
|
||||
<p>It's simple! But I kinda like it that way. Plus, neat feature: the canister displays the icon of the weapon for which it holds ammo! So far, only the N5 Bomb Launcher's icon is implemented, but others are easy to put in once I create icons for more weapons.</p>
|
||||
|
||||
<h2 id="bomblauncher">A New Weapon</h2>
|
||||
<h2 id="bomblauncher">A New Weapon</h2>
|
||||
|
||||
<p>Introducing: the N5 Bomb Launcher.</p>
|
||||
<p>Introducing: the N5 Bomb Launcher.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/102-profile.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/102-profile.webp">
|
||||
|
||||
<p>Okay, it's not exactly a looker at this stage, but it's functionally largely implemented. This is an, as the name implies, bomb-launching device with ground targetting. This sets it apart from other weapons, and is the reason for why I was so hesitant to imlpement it: it meant I had to change my existing code to accommodate for this.</p>
|
||||
<p>Okay, it's not exactly a looker at this stage, but it's functionally largely implemented. This is an, as the name implies, bomb-launching device with ground targetting. This sets it apart from other weapons, and is the reason for why I was so hesitant to imlpement it: it meant I had to change my existing code to accommodate for this.</p>
|
||||
|
||||
<p>It also meant that I had to figure out how the projectile will fly. The problem: I wanted a projectile that follows a predictable curve and has ground targetting so that you can see where the bomb will land. I achieved the former through using a <a href="https://docs.godotengine.org/en/stable/classes/class_path3d.html"><code>Path3D</code></a> node and modelling a curve into it. The latter still proves a challenge, however; how do I retrieve a collision where the projectile is projected to land? I have not implemented anything of the sort yet. An idea solution would be a curved raycast, but that doesn't exist. Maybe a <code>ShapeCast3D</code> and retrieving the collision closest to the player? We'll see.</p>
|
||||
<p>It also meant that I had to figure out how the projectile will fly. The problem: I wanted a projectile that follows a predictable curve and has ground targetting so that you can see where the bomb will land. I achieved the former through using a <a href="https://docs.godotengine.org/en/stable/classes/class_path3d.html"><code>Path3D</code></a> node and modelling a curve into it. The latter still proves a challenge, however; how do I retrieve a collision where the projectile is projected to land? I have not implemented anything of the sort yet. An idea solution would be a curved raycast, but that doesn't exist. Maybe a <code>ShapeCast3D</code> and retrieving the collision closest to the player? We'll see.</p>
|
||||
|
||||
<p>I've been playing around with the explosion as well:</p>
|
||||
<p>I've been playing around with the explosion as well:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241103/102-explosion.webp">
|
||||
<img src="/projects/projectn5/devlog/20241103/102-explosion.webp">
|
||||
|
||||
<p>I like the idea of the explosion looking 'technical', if that makes sense. A quick explosion with a large wireframe icosphere. The colour definitely needs changing; I'm even considering changing it to blue, even if that doesn't match the N5 colours. Maybe for the V2 upgrade of the weapon.</p>
|
||||
<p>I like the idea of the explosion looking 'technical', if that makes sense. A quick explosion with a large wireframe icosphere. The colour definitely needs changing; I'm even considering changing it to blue, even if that doesn't match the N5 colours. Maybe for the V2 upgrade of the weapon.</p>
|
||||
|
||||
<p>The white stripes are strongly inspired by the art to Jaron's track <a href="https://youtu.be/M7Ng0hIzsIg">ONCE</a>. Looking at the art again, I actually quite like the colourshift effect, I <i>might</i> try to incorporate that as well. Then again, maybe the two effects (stripes and icosphere) don't match quite so well. I'll figure something out.</p>
|
||||
<p>The white stripes are strongly inspired by the art to Jaron's track <a href="https://youtu.be/M7Ng0hIzsIg">ONCE</a>. Looking at the art again, I actually quite like the colourshift effect, I <i>might</i> try to incorporate that as well. Then again, maybe the two effects (stripes and icosphere) don't match quite so well. I'll figure something out.</p>
|
||||
|
||||
<h2 id="inspiration">Character Inspiration</h2>
|
||||
<h2 id="inspiration">Character Inspiration</h2>
|
||||
|
||||
<p>In an effort to gain more inspiration for my project's visual direction, I've turned to a place I never thought I would voluntarily step foot in: Pinterest. Turns out, Pinterest is not only good for fashion and home furnishing inspo (though I also like it for that), but it has a slew of game art as well. I only created my account 10 hours ago, and I've already collected quite a lot of cool art <a href="https://de.pinterest.com/denizk0461/character-design/">here</a>!</p>
|
||||
<p>In an effort to gain more inspiration for my project's visual direction, I've turned to a place I never thought I would voluntarily step foot in: Pinterest. Turns out, Pinterest is not only good for fashion and home furnishing inspo (though I also like it for that), but it has a slew of game art as well. I only created my account 10 hours ago, and I've already collected quite a lot of cool art <a href="https://de.pinterest.com/denizk0461/character-design/">here</a>!</p>
|
||||
|
||||
<p>Using Pinterest for this purpose allows me to visually see lots of different options I could go for with my character, which is a huge improvement over just... trying to come up with something exclusively on my own.</p>
|
||||
<p>Using Pinterest for this purpose allows me to visually see lots of different options I could go for with my character, which is a huge improvement over just... trying to come up with something exclusively on my own.</p>
|
||||
|
||||
<p>Seeing all of this art gives me ideas for how I could design a robot character, for instance. It allows me to decide on a shading style – there's a pin of a <a href="https://de.pinterest.com/pin/999165867324583246/">toon-shaded character</a> in there that I quite like. It also makes me contemplate the direction of the character's identity. With designing a robot character, I find that falling into the stereotype of 'cool and strong male robot' is too easy. I've done it myself. Why does it have to be a <i>male</i>-looking robot, anyway? What made me reevaluate my ideas was <a href="https://de.pinterest.com/pin/999165867324583524/">this pin</a>. It's not of robots, but I like the aesthetic of those outfits and hope to integrate some of that into my character somehow. The idea from the start was to create relatively non-binary robots anyway; after all, they're robots living 600 years in the future, why should they confine to humanity's societal standards?</p>
|
||||
<p>Seeing all of this art gives me ideas for how I could design a robot character, for instance. It allows me to decide on a shading style – there's a pin of a <a href="https://de.pinterest.com/pin/999165867324583246/">toon-shaded character</a> in there that I quite like. It also makes me contemplate the direction of the character's identity. With designing a robot character, I find that falling into the stereotype of 'cool and strong male robot' is too easy. I've done it myself. Why does it have to be a <i>male</i>-looking robot, anyway? What made me reevaluate my ideas was <a href="https://de.pinterest.com/pin/999165867324583524/">this pin</a>. It's not of robots, but I like the aesthetic of those outfits and hope to integrate some of that into my character somehow. The idea from the start was to create relatively non-binary robots anyway; after all, they're robots living 600 years in the future, why should they confine to humanity's societal standards?</p>
|
||||
|
||||
<h2 id="retro">Retrospective</h2>
|
||||
<h2 id="retro">Retrospective</h2>
|
||||
|
||||
<p>It's been almost 14 months of working on Project N5 – sometimes actively, with occasional breaks in-between. Can you believe that this game started from <i>this?</i> (video from <a href="/projects/projectn5/devlog/202309/#header-0">2023-09-16</a>)</p>
|
||||
<p>It's been almost 14 months of working on Project N5 – sometimes actively, with occasional breaks in-between. Can you believe that this game started from <i>this?</i> (video from <a href="/projects/projectn5/devlog/202309/#header-0">2023-09-16</a>)</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_00.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/202309/2023-09-16_00.mp4" />
|
||||
|
||||
<p>Logically speaking, of course, that makes complete sense. I had to start from somewhere. But it's the fact that I managed to get so far already, working on my own, that I find crazy. I've already managed to implement many basics of this game, slowly but surely realising my vision. I think this really has potential. I should keep up the work.</p>
|
||||
<p>Logically speaking, of course, that makes complete sense. I had to start from somewhere. But it's the fact that I managed to get so far already, working on my own, that I find crazy. I've already managed to implement many basics of this game, slowly but surely realising my vision. I think this really has potential. I should keep up the work.</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,95 +8,97 @@
|
||||
<title>The Making of a Protagonist, Part I | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-11-27" subtitle="The Making of a Protagonist, Part I" banner="/projects/projectn5/devlog/20241127/hands.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-11-27" subtitle="The Making of a Protagonist, Part I" banner="/projects/projectn5/devlog/20241127/hands.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>I've been busy at work on this game! I've not done any programming work lately – which I feel a bit guilty about – <i>however!</i> I've been improving in the 3D modelling department. I started modelling a humanoid character, based on references and my personal ideas, to become my new protagonist for Project N5. Here's what I've been able to do so far, and how I managed to get to this point.</p>
|
||||
<p>I've been busy at work on this game! I've not done any programming work lately – which I feel a bit guilty about – <i>however!</i> I've been improving in the 3D modelling department. I started modelling a humanoid character, based on references and my personal ideas, to become my new protagonist for Project N5. Here's what I've been able to do so far, and how I managed to get to this point.</p>
|
||||
|
||||
<h2 id="laura">Laura</h2>
|
||||
<h2 id="laura">Laura</h2>
|
||||
|
||||
<p>My new protagonist is called Laura. This is a change from my original idea, where I would have a robot protagonist, but more on that further down.</p>
|
||||
<p>My new protagonist is called Laura. This is a change from my original idea, where I would have a robot protagonist, but more on that further down.</p>
|
||||
|
||||
<p>Laura is a 20-something year old human girl fitted with a mechanical right arm. This is supposed to affect gameplay as well, since Laura's left-handed, which reflects both in the way she holds weapons as well as in the game's aiming perspective, which will look over her left shoulder as opposed to her right. I think this is fairly uncommon, actually, so it might take a little bit of time to get used to, but I like the idea of straying from the norm ever so slightly.</p>
|
||||
<p>Laura is a 20-something year old human girl fitted with a mechanical right arm. This is supposed to affect gameplay as well, since Laura's left-handed, which reflects both in the way she holds weapons as well as in the game's aiming perspective, which will look over her left shoulder as opposed to her right. I think this is fairly uncommon, actually, so it might take a little bit of time to get used to, but I like the idea of straying from the norm ever so slightly.</p>
|
||||
|
||||
<p>With her mechanical right arm, Laura may also be able to perform actions such as using zip lines. I haven't entirely decided on that yet, though.</p>
|
||||
<p>With her mechanical right arm, Laura may also be able to perform actions such as using zip lines. I haven't entirely decided on that yet, though.</p>
|
||||
|
||||
<p>This is what I've created so far:</p>
|
||||
<p>This is what I've created so far:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-overview.webp">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-topology.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-overview.webp">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-topology.webp">
|
||||
</div>
|
||||
|
||||
<p>I'll admit, I'm actually quite proud of myself for being able to create this. This is a fairly representative humanoid body, with relatively decent topology and without using a massive amount of polygons – this model currently sits at 2,452 tris.</p>
|
||||
<p>I'll admit, I'm actually quite proud of myself for being able to create this. This is a fairly representative humanoid body, with relatively decent topology and without using a massive amount of polygons – this model currently sits at 2,452 tris.</p>
|
||||
|
||||
<p>The features aren't entirely fleshed out yet, though there are also a few things I want to keep in mind when creating this model:</p>
|
||||
<p>The features aren't entirely fleshed out yet, though there are also a few things I want to keep in mind when creating this model:</p>
|
||||
|
||||
<ul>
|
||||
<li>There won't be much character customisation. There'll be some outfits (more on that below) but those are, for the most part, bound to the story progression.</li>
|
||||
<li>I'll do some touchups on the joints to get them to bend better.</li>
|
||||
<li>There's no skeleton yet.</li>
|
||||
<li>The right arm is only in place because I'm using a mirror modifier on the whole body. I'll chop off the right arm once I get to modelling the mechanical arm replacement.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>There won't be much character customisation. There'll be some outfits (more on that below) but those are, for the most part, bound to the story progression.</li>
|
||||
<li>I'll do some touchups on the joints to get them to bend better.</li>
|
||||
<li>There's no skeleton yet.</li>
|
||||
<li>The right arm is only in place because I'm using a mirror modifier on the whole body. I'll chop off the right arm once I get to modelling the mechanical arm replacement.</li>
|
||||
</ul>
|
||||
|
||||
<p>The future vision is to give her two outfits: one in which she starts, which looks more like a casual outfit, wearing a hoodie with the right sleeve torn off. It's supposed to look like an outfit that's not really meant for combat, because it's the one she wore before her hibernation. The second outfit is supposed to be a more combat-suited outfit, perhaps a type of armour even.</p>
|
||||
<p>The future vision is to give her two outfits: one in which she starts, which looks more like a casual outfit, wearing a hoodie with the right sleeve torn off. It's supposed to look like an outfit that's not really meant for combat, because it's the one she wore before her hibernation. The second outfit is supposed to be a more combat-suited outfit, perhaps a type of armour even.</p>
|
||||
|
||||
<p>For the next progress update, I'll be able to show a largely finished model – I promise!</p>
|
||||
<p>For the next progress update, I'll be able to show a largely finished model – I promise!</p>
|
||||
|
||||
<h2 id="story">Story Changes</h2>
|
||||
<h2 id="story">Story Changes</h2>
|
||||
|
||||
<p>There's reason for these ideas I have for Laura, and it's all in the story I am developing.</p>
|
||||
<p>There's reason for these ideas I have for Laura, and it's all in the story I am developing.</p>
|
||||
|
||||
<h3 id="new-story">The New Storyline</h3>
|
||||
<h3 id="new-story">The New Storyline</h3>
|
||||
|
||||
<p>Laura is a young girl waking up from a hundred-years-long hibernation. Her home – Sol III (Earth) – has been devastated. Before her hibernation, she lost her right arm, which has been replaced with a mechanical arm by a robot at some point during her hibernation. She doesn't get to meet this robot immediately, as they're gone when she wakes up (or perhaps is taken away?).</p>
|
||||
<p>Laura is a young girl waking up from a hundred-years-long hibernation. Her home – Sol III (Earth) – has been devastated. Before her hibernation, she lost her right arm, which has been replaced with a mechanical arm by a robot at some point during her hibernation. She doesn't get to meet this robot immediately, as they're gone when she wakes up (or perhaps is taken away?).</p>
|
||||
|
||||
<p><i>Project N5</i> is the story of Laura rediscovering what caused the devastation of her home as well as what happened to the robot that saved her life.</p>
|
||||
<p><i>Project N5</i> is the story of Laura rediscovering what caused the devastation of her home as well as what happened to the robot that saved her life.</p>
|
||||
|
||||
<h3 id="old-story">How to Adapt the Old Storyline</h3>
|
||||
<h3 id="old-story">How to Adapt the Old Storyline</h3>
|
||||
|
||||
<p>Gone is the robot protagonist. Gone is the titular <i>Project N5</i>, for which the protagonist had been built. Gone is the company that the protagonist was built by, and against whom the protagonist swore revenge. I struggled massively with developing this storyline, even just coming up with a general plot that sounded interesting. I think this is good riddance. This wasn't going anywhere.</p>
|
||||
<p>Gone is the robot protagonist. Gone is the titular <i>Project N5</i>, for which the protagonist had been built. Gone is the company that the protagonist was built by, and against whom the protagonist swore revenge. I struggled massively with developing this storyline, even just coming up with a general plot that sounded interesting. I think this is good riddance. This wasn't going anywhere.</p>
|
||||
|
||||
<p>This isn't a full rework, however – many aspects remain. The weapons remain, the ideas for planets and space stations remain, etc. The idea of revolving the story around Sol III and basing the story on environmental ruin still very much remains!</p>
|
||||
<p>This isn't a full rework, however – many aspects remain. The weapons remain, the ideas for planets and space stations remain, etc. The idea of revolving the story around Sol III and basing the story on environmental ruin still very much remains!</p>
|
||||
|
||||
<h3 id="inspiration">Inspiration</h3>
|
||||
<h3 id="inspiration">Inspiration</h3>
|
||||
|
||||
<p>Believe it or not, most of the inspiration I was able to gather to come up with this new storyline stems from one song: <a href="https://acloudyskye.bandcamp.com/track/spill">acloudyskye – Spill</a>.</p>
|
||||
<p>Believe it or not, most of the inspiration I was able to gather to come up with this new storyline stems from one song: <a href="https://acloudyskye.bandcamp.com/track/spill">acloudyskye – Spill</a>.</p>
|
||||
|
||||
<p>The striking, saturated colours, the feeling of adventure, the sense of loneliness in a large world – all of these aspects combine beautifully in this song and its cover art. It gave me ideas which I want to realise in my game.</p>
|
||||
<p>The striking, saturated colours, the feeling of adventure, the sense of loneliness in a large world – all of these aspects combine beautifully in this song and its cover art. It gave me ideas which I want to realise in my game.</p>
|
||||
|
||||
<p>acloudyskye's music has inspired me quite a bit lately, especially their albums <a href="https://acloudyskye.bandcamp.com/album/what-do-you-want">What Do You Want!</a> and <a href="https://acloudyskye.bandcamp.com/album/there-must-be-something-here">There Must Be Something Here</a>. Absolutely recommend listening to them.</p>
|
||||
<p>acloudyskye's music has inspired me quite a bit lately, especially their albums <a href="https://acloudyskye.bandcamp.com/album/what-do-you-want">What Do You Want!</a> and <a href="https://acloudyskye.bandcamp.com/album/there-must-be-something-here">There Must Be Something Here</a>. Absolutely recommend listening to them.</p>
|
||||
|
||||
<h2 id="likelies">Likely Future Changes</h2>
|
||||
<h2 id="likelies">Likely Future Changes</h2>
|
||||
|
||||
<h3 id="title">Game Title</h3>
|
||||
<h3 id="title">Game Title</h3>
|
||||
|
||||
<p>I suppose the title <i>Project N5</i> inherently sounds like a work-in-progress title. A codename of sorts.</p>
|
||||
<p>I suppose the title <i>Project N5</i> inherently sounds like a work-in-progress title. A codename of sorts.</p>
|
||||
|
||||
<p>Since the whole idea of the in-game <i>Project N5</i> won't be developed any further, I figure this is the start of a goodbye. A new title will have to come. I haven't decided on one yet, and I think it'll be quite some time until I'll actually settle on a new title, perhaps not until much of the story has already been developed.</p>
|
||||
<p>Since the whole idea of the in-game <i>Project N5</i> won't be developed any further, I figure this is the start of a goodbye. A new title will have to come. I haven't decided on one yet, and I think it'll be quite some time until I'll actually settle on a new title, perhaps not until much of the story has already been developed.</p>
|
||||
|
||||
<p>For now, <i>Project N5</i> remains the working title. Don't get too attached to it!</p>
|
||||
<p>For now, <i>Project N5</i> remains the working title. Don't get too attached to it!</p>
|
||||
|
||||
<h3 id="aesthetics">Aesthetics</h3>
|
||||
<h3 id="aesthetics">Aesthetics</h3>
|
||||
|
||||
<p>As I'm moving from working on the game's logic to the aesthetic (which does NOT mean the logic is anywhere near finished!), I'm considering starting to implement shaders. I've decided that I'll likely use a toon-style shader, perhaps a variation of <a href="https://godotshaders.com/shader/flexible-toon-shader/">this one</a>. Looking forward to playing around with the visuals!</p>
|
||||
<p>As I'm moving from working on the game's logic to the aesthetic (which does NOT mean the logic is anywhere near finished!), I'm considering starting to implement shaders. I've decided that I'll likely use a toon-style shader, perhaps a variation of <a href="https://godotshaders.com/shader/flexible-toon-shader/">this one</a>. Looking forward to playing around with the visuals!</p>
|
||||
|
||||
<p>I also have a vision for the 3D models, which I may have already mentioned: I'm planning to use (almost?) exclusively materials for the models' visuals. I'm trying to avoid textures, for multiple reasons:</p>
|
||||
<p>I also have a vision for the 3D models, which I may have already mentioned: I'm planning to use (almost?) exclusively materials for the models' visuals. I'm trying to avoid textures, for multiple reasons:</p>
|
||||
|
||||
<ul>
|
||||
<li>Textures cannot be smoothly scaled up in resolution, whereas models that exclusively use materials and polygons for detail don't depend on an image's pixel resolution.</li>
|
||||
<li>Painting textures is hard!</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Textures cannot be smoothly scaled up in resolution, whereas models that exclusively use materials and polygons for detail don't depend on an image's pixel resolution.</li>
|
||||
<li>Painting textures is hard!</li>
|
||||
</ul>
|
||||
|
||||
<p>Some low-poly 3D modelling artists use textures for shadows, which I think is cool, although I'm planning to use shaders and generated shadows in my game instead, so painted shadows are likely unnecessary.</p>
|
||||
<p>Some low-poly 3D modelling artists use textures for shadows, which I think is cool, although I'm planning to use shaders and generated shadows in my game instead, so painted shadows are likely unnecessary.</p>
|
||||
|
||||
<h2 id="next">Next Steps</h2>
|
||||
<h2 id="next">Next Steps</h2>
|
||||
|
||||
<p>Next, I'll continue modelling Laura. I most recently worked on her head, where I'm still deciding whether to give her a half-face mask or a full face shield. Doing a half-face mask will enable Laura to emote with her eyes, but that means I'll have to implement eyes, which could be difficult, so using a full face shield that just completely blocks her face would be easier. I could make it work in the story too. I'll model her hair, add some ears (probably), and then I'll get to modelling her mechanical right arm. Afterwards, I'll likely rig it.</p>
|
||||
<p>Next, I'll continue modelling Laura. I most recently worked on her head, where I'm still deciding whether to give her a half-face mask or a full face shield. Doing a half-face mask will enable Laura to emote with her eyes, but that means I'll have to implement eyes, which could be difficult, so using a full face shield that just completely blocks her face would be easier. I could make it work in the story too. I'll model her hair, add some ears (probably), and then I'll get to modelling her mechanical right arm. Afterwards, I'll likely rig it.</p>
|
||||
|
||||
<p>Once I've done that, I'll save this model as a baseline 3D model and then edit a copy of it to add clothes – I want the clothes to be part of the model rather than go on top of the existing mesh, I think.</p>
|
||||
<p>Once I've done that, I'll save this model as a baseline 3D model and then edit a copy of it to add clothes – I want the clothes to be part of the model rather than go on top of the existing mesh, I think.</p>
|
||||
|
||||
<p>After that, I could start animating Laura, though I don't know whether I'll get to that in the next progress update. It could be cool! I'll have to find a way to add and update animations in Godot without re-importing the 3D model. I think a way exists using <a href="https://docs.godotengine.org/en/stable/tutorials/assets_pipeline/escn_exporter/animation.html">NLA tracks</a>, but I'll have to learn how to do this, and whether this works the way I imagine.</p>
|
||||
<p>After that, I could start animating Laura, though I don't know whether I'll get to that in the next progress update. It could be cool! I'll have to find a way to add and update animations in Godot without re-importing the 3D model. I think a way exists using <a href="https://docs.godotengine.org/en/stable/tutorials/assets_pipeline/escn_exporter/animation.html">NLA tracks</a>, but I'll have to learn how to do this, and whether this works the way I imagine.</p>
|
||||
|
||||
<p>I've already made sketches for how I want to style Laura; this could be fun!</p>
|
||||
<p>I've already made sketches for how I want to style Laura; this could be fun!</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,133 +8,135 @@
|
||||
<title>The Making of a Protagonist, Part II | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-12-22" subtitle="The Making of a Protagonist, Part II" banner="/projects/projectn5/devlog/20241222/laura-header.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2024-12-22" subtitle="The Making of a Protagonist, Part II" banner="/projects/projectn5/devlog/20241222/laura-header.webp" />
|
||||
|
||||
<p>I have lots progress to share!!</p>
|
||||
<p>I have lots progress to share!!</p>
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>First things first: Laura is, unlike I promised before, not yet finished. However, I have made <i>so much</i> progress in the past few weeks that I just wanted to get out already. Here's a comparison between my last progress update and the current iteration of Laura:</p>
|
||||
<p>First things first: Laura is, unlike I promised before, not yet finished. However, I have made <i>so much</i> progress in the past few weeks that I just wanted to get out already. Here's a comparison between my last progress update and the current iteration of Laura:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-overview.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241127/laura-overview.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura.webp">
|
||||
</div>
|
||||
|
||||
<p>She's become an actual proper character!! omg omg</p>
|
||||
<p>She's become an actual proper character!! omg omg</p>
|
||||
|
||||
<h2 id="how">How We Got Here</h2>
|
||||
<h2 id="how">How We Got Here</h2>
|
||||
|
||||
<p>So, what happened? How did I create this character?</p>
|
||||
<p>So, what happened? How did I create this character?</p>
|
||||
|
||||
<p>I think what's most crucial is that I gathered influence, references, knowledge, and ideas from all kinds of places. Here's some:</p>
|
||||
<p>I think what's most crucial is that I gathered influence, references, knowledge, and ideas from all kinds of places. Here's some:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://youtu.be/-XYryP_GU8o">Creating Stylized Low Poly Characters in Blender</a> by lacruzo. Shows the entire process of creating a low-poly character from scratch, and was the entire reason why my character got off the ground to begin with.</li>
|
||||
<li id="low-poly-easy"><a href="https://youtu.be/N7GVbdf4H_g">Creating a low-poly character is actually kinda easy</a> by SELS – topology of lower-poly characters. Also, how to create clothes and hair, UV unwrapping and texture painting, as well as rigging with a meta-rig.</li>
|
||||
<li><a href="https://topologyguides.com/loop-reduction">Optimal Edge Loop Reduction Flows</a> on topologyguides.com helps understand how to efficiently transition between spots that require more edge loops for detail (such as hands) and meshes that are less detailed (such as arms).</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="https://youtu.be/-XYryP_GU8o">Creating Stylized Low Poly Characters in Blender</a> by lacruzo. Shows the entire process of creating a low-poly character from scratch, and was the entire reason why my character got off the ground to begin with.</li>
|
||||
<li id="low-poly-easy"><a href="https://youtu.be/N7GVbdf4H_g">Creating a low-poly character is actually kinda easy</a> by SELS – topology of lower-poly characters. Also, how to create clothes and hair, UV unwrapping and texture painting, as well as rigging with a meta-rig.</li>
|
||||
<li><a href="https://topologyguides.com/loop-reduction">Optimal Edge Loop Reduction Flows</a> on topologyguides.com helps understand how to efficiently transition between spots that require more edge loops for detail (such as hands) and meshes that are less detailed (such as arms).</li>
|
||||
</ul>
|
||||
|
||||
<p>Aside from that, looking at reference images of people, clothes, hairstyles etc. on the internet just helped a lot. I've dragged plenty of images of random people into Blender to use as shape references. It's much easier than trying to imagine how a human is supposed to look, because, to be honest – even though we all look at humans all the time, making one from scratch without reference (and without much practice) is nigh impossible.</p>
|
||||
<p>Aside from that, looking at reference images of people, clothes, hairstyles etc. on the internet just helped a lot. I've dragged plenty of images of random people into Blender to use as shape references. It's much easier than trying to imagine how a human is supposed to look, because, to be honest – even though we all look at humans all the time, making one from scratch without reference (and without much practice) is nigh impossible.</p>
|
||||
|
||||
<p>Side note: Laura is <i>not</i> a low-poly character. Her mesh currently consists of about 8,600 tris. However, in trying to understand how topology works to create a humanoid shape, learning from low-poly character creation tutorials helps immensely imo. Low-poly characters rely on as few vertices as possible to display as much detail as needed. Going up in poly count is fairly straightforward – perhaps as simple as applying a subdivision modifier, if your model allows for it. Though for a video game character, I wouldn't necessarily recommend it unless you know what you're doing, because polygon count can quickly skyrocket that way.</p>
|
||||
<p>Side note: Laura is <i>not</i> a low-poly character. Her mesh currently consists of about 8,600 tris. However, in trying to understand how topology works to create a humanoid shape, learning from low-poly character creation tutorials helps immensely imo. Low-poly characters rely on as few vertices as possible to display as much detail as needed. Going up in poly count is fairly straightforward – perhaps as simple as applying a subdivision modifier, if your model allows for it. Though for a video game character, I wouldn't necessarily recommend it unless you know what you're doing, because polygon count can quickly skyrocket that way.</p>
|
||||
|
||||
<h2 id="changes">Changes During the Creation Process</h2>
|
||||
<h2 id="changes">Changes During the Creation Process</h2>
|
||||
|
||||
<h3 id="clothes">Clothes</h3>
|
||||
<h3 id="clothes">Clothes</h3>
|
||||
|
||||
<p>Laura was originally supposed to wear an orange sweatshirt as well as shorts. The orange sweatshirt was thrown out because the character reminded me of Velma from Scooby-Doo, and I changed it to green because I like green. Also, the shorts looked dorky. Here's a picture from 2024-12-01 – Laura oddly looks younger in this picture, I feel. The shorts and hair make a big difference.</p>
|
||||
<p>Laura was originally supposed to wear an orange sweatshirt as well as shorts. The orange sweatshirt was thrown out because the character reminded me of Velma from Scooby-Doo, and I changed it to green because I like green. Also, the shorts looked dorky. Here's a picture from 2024-12-01 – Laura oddly looks younger in this picture, I feel. The shorts and hair make a big difference.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-young.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-young.webp">
|
||||
|
||||
<h3 id="hair">Hair</h3>
|
||||
<h3 id="hair">Hair</h3>
|
||||
|
||||
<p>Modelling hair has proven... challenging. What style to go with? What modelling technique to use?</p>
|
||||
<p>Modelling hair has proven... challenging. What style to go with? What modelling technique to use?</p>
|
||||
|
||||
<p>The first try (seen above) was using the technique from <a href="#low-poly-easy">this video</a> – selecting faces from the character's head, duplicating them, separating them into their own mesh, changing the scale, adding a solidify modifier, and then adding faces. This... worked, but I didn't like the results. And I tried quite a few styles.</p>
|
||||
<p>The first try (seen above) was using the technique from <a href="#low-poly-easy">this video</a> – selecting faces from the character's head, duplicating them, separating them into their own mesh, changing the scale, adding a solidify modifier, and then adding faces. This... worked, but I didn't like the results. And I tried quite a few styles.</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-1.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-2.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-3.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-1.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-2.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-3.webp">
|
||||
</div>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-4.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-5.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-6.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-4.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-5.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-6.webp">
|
||||
</div>
|
||||
|
||||
<p>It always looked too flat, too shapeless, too boring, wrong cuts. It just didn't work.</p>
|
||||
<p>It always looked too flat, too shapeless, too boring, wrong cuts. It just didn't work.</p>
|
||||
|
||||
<p>Next up: a technique shown in these two videos: <a href="https://youtu.be/LU0BFThJIco">Blender: How to Make HAIR, Full Workflow</a> by 2AM, and <a href="https://youtu.be/BqWYgrXw7Jk"> Easiest Way To Create Hair in Blender – 5 Minute Tutorial</a> by YanSculpts.</p>
|
||||
<p>Next up: a technique shown in these two videos: <a href="https://youtu.be/LU0BFThJIco">Blender: How to Make HAIR, Full Workflow</a> by 2AM, and <a href="https://youtu.be/BqWYgrXw7Jk"> Easiest Way To Create Hair in Blender – 5 Minute Tutorial</a> by YanSculpts.</p>
|
||||
|
||||
<p>Essentially, you create a curve and a circle, use the circle's shape as a profile for the curve, then change the circle's shape as well as the position and scale of the curve's vertices to create individual hair strands. Shown well in the two videos linked above, this can look pretty amazing! Only one issue: I'm creating a <b>game</b> character, and this technique is quite expensive, as it creates a lot of polygons for all the individual hair strands and the detail that goes into them. To mitigate this, I lowered the resolution of the profiling and used only a few curves to create an entire head's worth of hair. This looked a little like this:</p>
|
||||
<p>Essentially, you create a curve and a circle, use the circle's shape as a profile for the curve, then change the circle's shape as well as the position and scale of the curve's vertices to create individual hair strands. Shown well in the two videos linked above, this can look pretty amazing! Only one issue: I'm creating a <b>game</b> character, and this technique is quite expensive, as it creates a lot of polygons for all the individual hair strands and the detail that goes into them. To mitigate this, I lowered the resolution of the profiling and used only a few curves to create an entire head's worth of hair. This looked a little like this:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-curves.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-curves-2.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-curves.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-curves-2.webp">
|
||||
</div>
|
||||
|
||||
<p>This hair mesh originally (left picture) consisted of three parts: two curves at the front (left/right) and one in the back. This... was okay, but scaling the curves made the hair look weird. Thinner strands, especially when there's only a few of them, made them look more like dreads, and scaling up the vertices to large scales, as seen in the front near the top of the head, makes the hair look as if it's ballooning. Getting the shape right was a mess too: using only a single curve in the back meant that I had exactly one curve to cover quite literally half the head, and making sure that this singular strand of hair covered the head stretching from one ear to another was a pain. I tried using five curves (right picture), so that I have three in the back, but it didn't improve anything.</p>
|
||||
<p>This hair mesh originally (left picture) consisted of three parts: two curves at the front (left/right) and one in the back. This... was okay, but scaling the curves made the hair look weird. Thinner strands, especially when there's only a few of them, made them look more like dreads, and scaling up the vertices to large scales, as seen in the front near the top of the head, makes the hair look as if it's ballooning. Getting the shape right was a mess too: using only a single curve in the back meant that I had exactly one curve to cover quite literally half the head, and making sure that this singular strand of hair covered the head stretching from one ear to another was a pain. I tried using five curves (right picture), so that I have three in the back, but it didn't improve anything.</p>
|
||||
|
||||
<p>I then went <i>back</i> to the first method of scaling up faces from the head, with more knowledge and several tries behind me, and you know what? It actually kind of worked out.</p>
|
||||
<p>I then went <i>back</i> to the first method of scaling up faces from the head, with more knowledge and several tries behind me, and you know what? It actually kind of worked out.</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-new-2.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-new-3.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-new-2.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/laura-hair-flat-new-3.webp">
|
||||
</div>
|
||||
|
||||
<p>The right picture is the current iteration of Laura's hair. I added a head band because I thought it looked nice, though that detail is not final.</p>
|
||||
<p>The right picture is the current iteration of Laura's hair. I added a head band because I thought it looked nice, though that detail is not final.</p>
|
||||
|
||||
<p>Even though I had created a hair style that looks fairly decent in a cel-shaded environment, I wasn't quite happy. So, today in fact, I checked out a tutorial on creating an <a href="https://youtu.be/kxWWBmIUxbc">anisotropic hair shader</a> made in Blender by Lighting Boy Studio. It's really impressive! And quite complicated. Also, it's a Blender tutorial. While this is quite cool, I need shaders for Godot, since I'm creating a game, not a movie. To my surprise, someone already created a similar toon hair shader for Godot – <a href="https://godotshaders.com/shader/simpletoonhair/">SimpleToonHair</a> by D3ZAX. It's <i>exactly</i> what I was looking for, and I really want to use this for Laura! Only one problem: this doesn't really work with her current hair mesh.</p>
|
||||
<p>Even though I had created a hair style that looks fairly decent in a cel-shaded environment, I wasn't quite happy. So, today in fact, I checked out a tutorial on creating an <a href="https://youtu.be/kxWWBmIUxbc">anisotropic hair shader</a> made in Blender by Lighting Boy Studio. It's really impressive! And quite complicated. Also, it's a Blender tutorial. While this is quite cool, I need shaders for Godot, since I'm creating a game, not a movie. To my surprise, someone already created a similar toon hair shader for Godot – <a href="https://godotshaders.com/shader/simpletoonhair/">SimpleToonHair</a> by D3ZAX. It's <i>exactly</i> what I was looking for, and I really want to use this for Laura! Only one problem: this doesn't really work with her current hair mesh.</p>
|
||||
|
||||
<p>I decided that I want to create a hair mesh more similar to that shown on the shader's images. This mesh consists of several strands of hair, each two quads wide to create individual strands. Making something like that look cohesive is actually fairly easy too, since the cel-shaded style actually hides a lot of overlaps between meshes of the same colour.</p>
|
||||
<p>I decided that I want to create a hair mesh more similar to that shown on the shader's images. This mesh consists of several strands of hair, each two quads wide to create individual strands. Making something like that look cohesive is actually fairly easy too, since the cel-shaded style actually hides a lot of overlaps between meshes of the same colour.</p>
|
||||
|
||||
<h3 id="hair-animation">Hair Animation</h3>
|
||||
<h3 id="hair-animation">Hair Animation</h3>
|
||||
|
||||
<p>To create flowing long hair, I want to use the <a href="https://godotengine.org/asset-library/asset/1595">JiggleBones</a> add-on. Using this add-on, I can add bones to the hair mesh in Blender, which will then be moved by the add-on whenever the character moves. It's essentially an inertia effect. I haven't tried this out yet, however.</p>
|
||||
<p>To create flowing long hair, I want to use the <a href="https://godotengine.org/asset-library/asset/1595">JiggleBones</a> add-on. Using this add-on, I can add bones to the hair mesh in Blender, which will then be moved by the add-on whenever the character moves. It's essentially an inertia effect. I haven't tried this out yet, however.</p>
|
||||
|
||||
<h3 id="mask">Her Mask / Face Shield</h3>
|
||||
<h3 id="mask">Her Mask / Face Shield</h3>
|
||||
|
||||
<p>Canonically, Laura is supposed to wear some type of respiratory device, because the hazardous conditions on her home planet do not allow her to sustain life without it anymore. I'm not quite sure yet whether this respiratory device will come in the shape of a full face shield or a partial face mask, covering her nose and mouth.</p>
|
||||
<p>Canonically, Laura is supposed to wear some type of respiratory device, because the hazardous conditions on her home planet do not allow her to sustain life without it anymore. I'm not quite sure yet whether this respiratory device will come in the shape of a full face shield or a partial face mask, covering her nose and mouth.</p>
|
||||
|
||||
<p>Part of why I want to integrate this is because... modelling is hard, and I imagine animating a face will be even more difficult. Realistically, I'm a single dev trying to make a game that's fairly large in scope, so I should try to reduce complexity if possible. However, I have not yet decided whether I want to give Laura eyes. Eyes would make her feel more alive, I think, but again, it adds additional complexity. Also, I'd have to create eyes without using any textures, since I set out to create a game with as few image textures as possible (hopefully 0) to, again, avoid some complexity that comes with creating textures. I think it would be doable.</p>
|
||||
<p>Part of why I want to integrate this is because... modelling is hard, and I imagine animating a face will be even more difficult. Realistically, I'm a single dev trying to make a game that's fairly large in scope, so I should try to reduce complexity if possible. However, I have not yet decided whether I want to give Laura eyes. Eyes would make her feel more alive, I think, but again, it adds additional complexity. Also, I'd have to create eyes without using any textures, since I set out to create a game with as few image textures as possible (hopefully 0) to, again, avoid some complexity that comes with creating textures. I think it would be doable.</p>
|
||||
|
||||
<h3 id="arm">Her Right Arm</h3>
|
||||
<h3 id="arm">Her Right Arm</h3>
|
||||
|
||||
<p>Laura's supposed to have a mechanical right arm – on the current model, however, I have applied a mirror modifier, which means her left and right arms are identical. The grey mesh in front of her right arm, however, is the work-in-progress mechanical arm.</p>
|
||||
<p>Laura's supposed to have a mechanical right arm – on the current model, however, I have applied a mirror modifier, which means her left and right arms are identical. The grey mesh in front of her right arm, however, is the work-in-progress mechanical arm.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241222/arm.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/arm.webp">
|
||||
|
||||
<p>I'm not entirely happy with this yet. The general shape of the arm is relatively decent, the hinge looks ok, but I feel it's missing something. I think I want to add LEDs to the arm, which in-game can serve to display Laura's health status (alongside a more clearly legible health UI element).</p>
|
||||
<p>I'm not entirely happy with this yet. The general shape of the arm is relatively decent, the hinge looks ok, but I feel it's missing something. I think I want to add LEDs to the arm, which in-game can serve to display Laura's health status (alongside a more clearly legible health UI element).</p>
|
||||
|
||||
<h3 id="pose">Modelling Pose</h3>
|
||||
<h3 id="pose">Modelling Pose</h3>
|
||||
|
||||
<p>Influenced while I was researching a tangential topic on a Blender forum, I read up on A-pose versus T-pose when modelling 3D characters. From what I could gather reading the forum, the T-pose is mostly used because it's convenient for modelling orthogonally. However, the A-pose is preferable, as it better preserves the shoulder mesh. When modelling in a T-pose, the character's shoulders are stretched fairly unnaturally, whereas the A-pose puts the arms further towards a more natural, relaxed pose, which means that the shoulder mesh is not stretched quite as significantly when the character has their arms hanging down.</p>
|
||||
<p>Influenced while I was researching a tangential topic on a Blender forum, I read up on A-pose versus T-pose when modelling 3D characters. From what I could gather reading the forum, the T-pose is mostly used because it's convenient for modelling orthogonally. However, the A-pose is preferable, as it better preserves the shoulder mesh. When modelling in a T-pose, the character's shoulders are stretched fairly unnaturally, whereas the A-pose puts the arms further towards a more natural, relaxed pose, which means that the shoulder mesh is not stretched quite as significantly when the character has their arms hanging down.</p>
|
||||
|
||||
<p>To illustrate my point (get it?), here are some pictures. Left is in T-pose, right is in A-pose:</p>
|
||||
<p>To illustrate my point (get it?), here are some pictures. Left is in T-pose, right is in A-pose:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/deform-1.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/deform-2.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20241222/deform-1.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/deform-2.webp">
|
||||
</div>
|
||||
|
||||
<p>However, after watching <a href="https://youtu.be/FXfc4Gyw6I0">this video on bind poses</a> by Doodley, it seems that... it doesn't really matter. Whether you use the T-pose, the A-pose, the lovingly-called hug-pose, or anything else really depends on what you plan to do with your character. Since Laura will mostly wield guns and keep her arms fairly low for most of the game, I decided to change Laura's modelling pose to an A-pose, with her arms pointed 30 degrees downward.</p>
|
||||
<p>However, after watching <a href="https://youtu.be/FXfc4Gyw6I0">this video on bind poses</a> by Doodley, it seems that... it doesn't really matter. Whether you use the T-pose, the A-pose, the lovingly-called hug-pose, or anything else really depends on what you plan to do with your character. Since Laura will mostly wield guns and keep her arms fairly low for most of the game, I decided to change Laura's modelling pose to an A-pose, with her arms pointed 30 degrees downward.</p>
|
||||
|
||||
<h2 id="next">What's Next</h2>
|
||||
<h2 id="next">What's Next</h2>
|
||||
|
||||
<ul>
|
||||
<li>Create a new hair mesh that looks and flows nicer and works better with the anisotropic toon hair shader.</li>
|
||||
<li>Adjust the hands (they look decent but I want them to look just a slight bit better).</li>
|
||||
<li>Finish the mechanical arm and attach it to Laura.</li>
|
||||
<li>Learn how to assign multiple meshes to a single skeleton – this will serve to swap between this more casual outfit and the eventual armour-type outfit.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Create a new hair mesh that looks and flows nicer and works better with the anisotropic toon hair shader.</li>
|
||||
<li>Adjust the hands (they look decent but I want them to look just a slight bit better).</li>
|
||||
<li>Finish the mechanical arm and attach it to Laura.</li>
|
||||
<li>Learn how to assign multiple meshes to a single skeleton – this will serve to swap between this more casual outfit and the eventual armour-type outfit.</li>
|
||||
</ul>
|
||||
|
||||
<p>I suppose that's mostly what I've been up to. There's not been much going on in the Godot project, though I'm preparing for bigger changes. I want to refactor the weapon scripts, for instance – I tried to make them more modular at one point, having different scripts for Throwers, Semiautos, Automatics, but it made things pretty convoluted. I'll see if I can fix this up to make adding weapons into the game more streamlined.</p>
|
||||
<p>I suppose that's mostly what I've been up to. There's not been much going on in the Godot project, though I'm preparing for bigger changes. I want to refactor the weapon scripts, for instance – I tried to make them more modular at one point, having different scripts for Throwers, Semiautos, Automatics, but it made things pretty convoluted. I'll see if I can fix this up to make adding weapons into the game more streamlined.</p>
|
||||
|
||||
<p>Also, I'm changing the way weapon stats are put into the game. Currently, data for the individual weapons such as damage, fire rate, vendor price, max ammo, etc. is stored in <b>three different places</b> – two different nodes attached to the weapon itself, as well as a singleton instance holding some additional data. My current idea was to transfer all of this data into a single CSV file, where I can neatly and easily add and change values as I see fit. This CSV data can then easily be imported into the game and used wherever needed I think that'll be a huge quality of life improvement during development.</p>
|
||||
<p>Also, I'm changing the way weapon stats are put into the game. Currently, data for the individual weapons such as damage, fire rate, vendor price, max ammo, etc. is stored in <b>three different places</b> – two different nodes attached to the weapon itself, as well as a singleton instance holding some additional data. My current idea was to transfer all of this data into a single CSV file, where I can neatly and easily add and change values as I see fit. This CSV data can then easily be imported into the game and used wherever needed I think that'll be a huge quality of life improvement during development.</p>
|
||||
|
||||
<p>For the time being, here's a picture of the soon-to-be-retired current protagonist character. Smoothly shaded for your viewing pleasure.</p>
|
||||
<p>For the time being, here's a picture of the soon-to-be-retired current protagonist character. Smoothly shaded for your viewing pleasure.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20241222/retiree.webp">
|
||||
<img src="/projects/projectn5/devlog/20241222/retiree.webp">
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
</script>
|
||||
|
||||
@@ -7,95 +8,97 @@
|
||||
<title>The Making of a Protagonist, Part III | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2025-02-03" subtitle="The Making of a Protagonist, Part III" banner="/projects/projectn5/devlog/20250203/lauras-imposing.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2025-02-03" subtitle="The Making of a Protagonist, Part III" banner="/projects/projectn5/devlog/20250203/lauras-imposing.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>While I've been busy working on another game with friends lately, I've managed to almost completely finish Laura. Here's what I've achieved!</p>
|
||||
<p>While I've been busy working on another game with friends lately, I've managed to almost completely finish Laura. Here's what I've achieved!</p>
|
||||
|
||||
<h2 id="eyes-hair">Visual Personality Adjustment</h2>
|
||||
<h2 id="eyes-hair">Visual Personality Adjustment</h2>
|
||||
|
||||
<p>As promised before, I've worked on Laura's head a bit more. Her full face shield has been replaced with a face mask / respirator covering only the bottom half of her face. Also, I finally got the hair into a state I'm actually happy with. Here's a comparison:</p>
|
||||
<p>As promised before, I've worked on Laura's head a bit more. Her full face shield has been replaced with a face mask / respirator covering only the bottom half of her face. Also, I finally got the hair into a state I'm actually happy with. Here's a comparison:</p>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/../20241222/laura-hair-flat-new-3.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-head-new.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/../20241222/laura-hair-flat-new-3.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-head-new.webp">
|
||||
</div>
|
||||
|
||||
<p>The eyes took some work to get right, but I'm pretty happy with the current result. They're not proper eyeballs, but instead they're embedded into the head, which visually isn't significant because the flat shading would hide these details anyway. She has a brown left eye with a small sparkle, as well as a right eye replacement. This implies that Laura sustained further damage to the right side of her body, which necessitated replacement of her eye in addition to her right arm.</p>
|
||||
<p>The eyes took some work to get right, but I'm pretty happy with the current result. They're not proper eyeballs, but instead they're embedded into the head, which visually isn't significant because the flat shading would hide these details anyway. She has a brown left eye with a small sparkle, as well as a right eye replacement. This implies that Laura sustained further damage to the right side of her body, which necessitated replacement of her eye in addition to her right arm.</p>
|
||||
|
||||
<p>It's actually the result of UV unwrapping her model. Previously, every colour was its own material, which I wanted to change by switching to a texture atlas. Initially, of course, the UVs were a bit messed up, which resulted in this look:</p>
|
||||
<p>It's actually the result of UV unwrapping her model. Previously, every colour was its own material, which I wanted to change by switching to a texture atlas. Initially, of course, the UVs were a bit messed up, which resulted in this look:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-uv.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-uv.webp">
|
||||
|
||||
<p>I still think this looks kind of cool.</p>
|
||||
<p>I still think this looks kind of cool.</p>
|
||||
|
||||
<h3 id="hair">New Hair 💇♀️</h3>
|
||||
<h3 id="hair">New Hair 💇♀️</h3>
|
||||
|
||||
<p>Her hair is now not a cohesive mesh anymore, but rather made up of something between 15 and 20 individual strands using custom normals to get a flat look. It also has a faint gradient, changing from a brighter colour at the top to a darker shade at the bottom.</p>
|
||||
<p>Her hair is now not a cohesive mesh anymore, but rather made up of something between 15 and 20 individual strands using custom normals to get a flat look. It also has a faint gradient, changing from a brighter colour at the top to a darker shade at the bottom.</p>
|
||||
|
||||
<p>I added earrings too:</p>
|
||||
<p>I added earrings too:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20250203/earrings.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/earrings.webp">
|
||||
|
||||
<p>Just some small metallic rings that I thought looked cool. For positioning these correctly, I hid Laura's back hair at one point, which gave me the idea to model a ponytail / tied-up alternative hair look for Laura. I think it'd look really cool. I haven't created this yet, but I've laid some groundwork to make it work:</p>
|
||||
<p>Just some small metallic rings that I thought looked cool. For positioning these correctly, I hid Laura's back hair at one point, which gave me the idea to model a ponytail / tied-up alternative hair look for Laura. I think it'd look really cool. I haven't created this yet, but I've laid some groundwork to make it work:</p>
|
||||
|
||||
<p>Laura's hair is now separate from her main mesh. The main mesh is rigged using a metarig generated through Rigify, whereas the hair has a manually-created armature. Also, the hair is split into the front part and the back part, separated by the hair band (which is part of the main mesh). This allows me to replace the flowing back hair with a ponytail easily in-engine without swapping out the entire character.</p>
|
||||
<p>Laura's hair is now separate from her main mesh. The main mesh is rigged using a metarig generated through Rigify, whereas the hair has a manually-created armature. Also, the hair is split into the front part and the back part, separated by the hair band (which is part of the main mesh). This allows me to replace the flowing back hair with a ponytail easily in-engine without swapping out the entire character.</p>
|
||||
|
||||
<p>This is pretty cool, because I can now create scenes for each hairstyle, set them up with <a href="/projects/projectn5/devlog/20241222/#hair-animation">jiggle bones</a> to create flowing hair, and essentially add a toggle to switch between them in-game!</p>
|
||||
<p>This is pretty cool, because I can now create scenes for each hairstyle, set them up with <a href="/projects/projectn5/devlog/20241222/#hair-animation">jiggle bones</a> to create flowing hair, and essentially add a toggle to switch between them in-game!</p>
|
||||
|
||||
<h2 id="rigify">Rigging and Using Blender's Rigify</h2>
|
||||
<h2 id="rigify">Rigging and Using Blender's Rigify</h2>
|
||||
|
||||
<p>Rigify is really cool for rigging characters easily. However, you need to know some things that I didn't before you start using it:</p>
|
||||
<p>Rigify is really cool for rigging characters easily. However, you need to know some things that I didn't before you start using it:</p>
|
||||
|
||||
<ul>
|
||||
<li>When adding a Rigify armature to the scene, <i>do not parent the rig to the model</i>. You need to place the rig as intended, then click on "Generate rig", and then parent the <i>new</i> armature with the mesh and weight paint that way. I made the mistake of weight painting before generating the rig, which isn't transferrable because the metarig adds extra bones which require individual weight painting (e.g. the thighs being made up of two bones instead of just one).</li>
|
||||
<li>Know how to switch between forward kinematics (FK) and inverse kinematics (IK). At the top right of the editor, there'll be a window with a slider to switch between FK and IK, as well as buttons to transfer an FK pose to IK and vice-versa. Don't be confused if posing a specific control doesn't work – you might need to switch to FK or IK, respectively.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>When adding a Rigify armature to the scene, <i>do not parent the rig to the model</i>. You need to place the rig as intended, then click on "Generate rig", and then parent the <i>new</i> armature with the mesh and weight paint that way. I made the mistake of weight painting before generating the rig, which isn't transferrable because the metarig adds extra bones which require individual weight painting (e.g. the thighs being made up of two bones instead of just one).</li>
|
||||
<li>Know how to switch between forward kinematics (FK) and inverse kinematics (IK). At the top right of the editor, there'll be a window with a slider to switch between FK and IK, as well as buttons to transfer an FK pose to IK and vice-versa. Don't be confused if posing a specific control doesn't work – you might need to switch to FK or IK, respectively.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="face">Facial Animations and Shape Keys</h2>
|
||||
<h2 id="face">Facial Animations and Shape Keys</h2>
|
||||
|
||||
<h2 id="animation">Animation and Framerate</h2>
|
||||
<h2 id="animation">Animation and Framerate</h2>
|
||||
|
||||
<p>I've been playing around with the idea of using a lower framerate for the animations. I got the idea from <a href="https://www.youtube.com/watch?v=_KRb_qV9P4g">Noodle's video on animation</a>. Not sure whether I'll go through with this, but if I do, I think I'll go with 15fps or 20fps animation, since that's easily implementable a 60fps environment.</p>
|
||||
<p>I've been playing around with the idea of using a lower framerate for the animations. I got the idea from <a href="https://www.youtube.com/watch?v=_KRb_qV9P4g">Noodle's video on animation</a>. Not sure whether I'll go through with this, but if I do, I think I'll go with 15fps or 20fps animation, since that's easily implementable a 60fps environment.</p>
|
||||
|
||||
<p>I already adjusted the jiggle bone script, which was easy to do since it runs in Godot's <code>_physics_process(delta)</code> function. This runs 60 times per second, so having code run only 15 times per second, for example, is as easy as wrapping the code in question in <code>if Engine.get_physics_frames() % 4 == 0:</code>, which makes a code block run only once every 4 frames – 60fps/4 == 15fps.</p>
|
||||
<p>I already adjusted the jiggle bone script, which was easy to do since it runs in Godot's <code>_physics_process(delta)</code> function. This runs 60 times per second, so having code run only 15 times per second, for example, is as easy as wrapping the code in question in <code>if Engine.get_physics_frames() % 4 == 0:</code>, which makes a code block run only once every 4 frames – 60fps/4 == 15fps.</p>
|
||||
|
||||
<h2 id="in-engine">Laura In-Engine</h2>
|
||||
<h2 id="in-engine">Laura In-Engine</h2>
|
||||
|
||||
<p>Since the shader I'm using in Blender is quite different from the one I am planning to use in Godot, here's a shot of Laura with the Godot shader:</p>
|
||||
<p>Since the shader I'm using in Blender is quite different from the one I am planning to use in Godot, here's a shot of Laura with the Godot shader:</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-shader-inengine.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/laura-shader-inengine.webp">
|
||||
|
||||
<p>I've been thinking of adding an option (perhaps as a cheat code) to change her outfit's colour – hair band, sweatshirt, and the rings on her right prosthetic fingers. I first didn't know how to implement this, but now that I've learnt a bit on how to use shaders, I think this could be achieved with a custom UV mask and a parameter that determines at which position the UV is sampled from – the UV would then contain several colour options.</p>
|
||||
<p>I've been thinking of adding an option (perhaps as a cheat code) to change her outfit's colour – hair band, sweatshirt, and the rings on her right prosthetic fingers. I first didn't know how to implement this, but now that I've learnt a bit on how to use shaders, I think this could be achieved with a custom UV mask and a parameter that determines at which position the UV is sampled from – the UV would then contain several colour options.</p>
|
||||
|
||||
<h2 id="pics">Some Funny Pictures</h2>
|
||||
<h2 id="pics">Some Funny Pictures</h2>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/ok.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/dance.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/naruto.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/shock.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/reprehension.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/disgust.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/ok.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/dance.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/naruto.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="/projects/projectn5/devlog/20250203/shock.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/reprehension.webp">
|
||||
<img src="/projects/projectn5/devlog/20250203/disgust.webp">
|
||||
</div>
|
||||
|
||||
<h2 id="future">The Future of this Devlog</h2>
|
||||
<h2 id="future">The Future of this Devlog</h2>
|
||||
|
||||
<p>I feel that this blog-like format makes me think that the content here should be educational; that someone may read this and learn from it. It's likely not the case, but either way, perhaps it would make sense to limit the progress updates to a mere "here's what I made!" and only a little bit of background, if it's interesting.</p>
|
||||
<p>I feel that this blog-like format makes me think that the content here should be educational; that someone may read this and learn from it. It's likely not the case, but either way, perhaps it would make sense to limit the progress updates to a mere "here's what I made!" and only a little bit of background, if it's interesting.</p>
|
||||
|
||||
<p>Most times, I find myself struggling to explain my progress anyway, mostly since I'm learning as I go and because I publish progress updates pretty rarely. For example, I added eyes to Laura's model on 2025-01-01, there's no way I'll remember everything I did and thought of over a month ago.</p>
|
||||
<p>Most times, I find myself struggling to explain my progress anyway, mostly since I'm learning as I go and because I publish progress updates pretty rarely. For example, I added eyes to Laura's model on 2025-01-01, there's no way I'll remember everything I did and thought of over a month ago.</p>
|
||||
|
||||
<p>Switching to a more short-form content format might help in publishing updates more regularly, and being more in the style of: "hey look at this cool thing I made!" It would also focus on visual changes, possibly helping me to keep a better schedule, merely because I can see my progress more steadily and be motivated more frequently.</p>
|
||||
<p>Switching to a more short-form content format might help in publishing updates more regularly, and being more in the style of: "hey look at this cool thing I made!" It would also focus on visual changes, possibly helping me to keep a better schedule, merely because I can see my progress more steadily and be motivated more frequently.</p>
|
||||
|
||||
<p>I've been thinking of creating an Instagram account for that – though I despise Meta (and Instagram by extension). It feels like a decent platform for my idea, though: presenting progress mostly through visuals. I also know more people who are on Instagram who may follow my progress... maybe. Bluesky <i>may</i> be an option, though it's more text-focussed and more short-form than Instagram.</p>
|
||||
<p>I've been thinking of creating an Instagram account for that – though I despise Meta (and Instagram by extension). It feels like a decent platform for my idea, though: presenting progress mostly through visuals. I also know more people who are on Instagram who may follow my progress... maybe. Bluesky <i>may</i> be an option, though it's more text-focussed and more short-form than Instagram.</p>
|
||||
|
||||
<p>Either way, I'd lose out on the progress I've already shared here.</p>
|
||||
<p>Either way, I'd lose out on the progress I've already shared here.</p>
|
||||
|
||||
<p>Or maybe I just don't share my stuff at all and don't stress out about it lol, no one's seeing this anyway and I'm not a social media person anyway.</p>
|
||||
<p>Or maybe I just don't share my stuff at all and don't stress out about it lol, no one's seeing this anyway and I'm not a social media person anyway.</p>
|
||||
|
||||
<p>idk</p>
|
||||
<p>idk</p>
|
||||
|
||||
<p>Maybe it's time to change the format of the devlog on this website?</p>
|
||||
<p>Maybe it's time to change the format of the devlog on this website?</p>
|
||||
</Content>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import BannerTitle from "$lib/banner-title.svelte";
|
||||
import Content from "$lib/content.svelte";
|
||||
import TableOfContents from "$lib/table-of-contents.svelte";
|
||||
import Video from "$lib/video.svelte";
|
||||
</script>
|
||||
@@ -8,172 +9,174 @@
|
||||
<title>Refactoring | denizk0461</title>
|
||||
</svelte:head>
|
||||
|
||||
<BannerTitle title="Project N5 Progress Update: 2025-03-16" subtitle="Refactoring" banner="/projects/projectn5/devlog/20250316/fishmonger.webp" />
|
||||
<Content>
|
||||
<BannerTitle title="Project N5 Progress Update: 2025-03-16" subtitle="Refactoring" banner="/projects/projectn5/devlog/20250316/fishmonger.webp" />
|
||||
|
||||
<TableOfContents />
|
||||
<TableOfContents />
|
||||
|
||||
<p>I've been making a lot of progress in a lot of different areas, so I won't be able to elaborate on every little detail, but I'll focus on more major things. Excited to share what I've been working on!</p>
|
||||
<p>I've been making a lot of progress in a lot of different areas, so I won't be able to elaborate on every little detail, but I'll focus on more major things. Excited to share what I've been working on!</p>
|
||||
|
||||
<h2 id="laura">Introducing: Laura</h2>
|
||||
<h2 id="laura">Introducing: Laura</h2>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20250316/laura.webp">
|
||||
<img src="/projects/projectn5/devlog/20250316/laura.webp">
|
||||
|
||||
<p>Laura is finally, <i>FINALLY</i> a playable character in the game!! I cannot overstate how cool this is. To finally see the character I've been creating for actual MONTHS in my game is HUGE.</p>
|
||||
<p>Laura is finally, <i>FINALLY</i> a playable character in the game!! I cannot overstate how cool this is. To finally see the character I've been creating for actual MONTHS in my game is HUGE.</p>
|
||||
|
||||
<p>As you can see in the screenshot above, Laura has a toon shader applied – it's <a href="https://godotengine.org/asset-library/asset/1900">this one again</a>.</p>
|
||||
<p>As you can see in the screenshot above, Laura has a toon shader applied – it's <a href="https://godotengine.org/asset-library/asset/1900">this one again</a>.</p>
|
||||
|
||||
<p>With the implementation of Laura came some other changes as well. The over-the-shoulder camera had already been adjusted to fly over the character's left shoulder, but now Laura also holds the weapon in her left hand. Plus, the camera was changed, because Laura is smaller than the chunky robot I had in her place before.</p>
|
||||
<p>With the implementation of Laura came some other changes as well. The over-the-shoulder camera had already been adjusted to fly over the character's left shoulder, but now Laura also holds the weapon in her left hand. Plus, the camera was changed, because Laura is smaller than the chunky robot I had in her place before.</p>
|
||||
|
||||
<img src="/projects/projectn5/devlog/20250316/laura-spinning.gif" style="max-width: 400px; object-fit: cover;">
|
||||
<img src="/projects/projectn5/devlog/20250316/laura-spinning.gif" style="max-width: 400px; object-fit: cover;">
|
||||
|
||||
<p>I even added swooshy hair using the JiggleBones plugin, though I've already removed that plugin from the project, which I'll elaborate on later.</p>
|
||||
<p>I even added swooshy hair using the JiggleBones plugin, though I've already removed that plugin from the project, which I'll elaborate on later.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/hair-swoosh.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/hair-swoosh.mp4" />
|
||||
|
||||
<p>I was also able to implement <code>LookAtModifier3D</code> to make Laura look at any enemy she's targetting. In the video, however, you can also notice that Laura's irises don't follow her head. That's a bug and it'll be fixed soon-ish.</p>
|
||||
<p>I was also able to implement <code>LookAtModifier3D</code> to make Laura look at any enemy she's targetting. In the video, however, you can also notice that Laura's irises don't follow her head. That's a bug and it'll be fixed soon-ish.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/look-at.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/look-at.mp4" />
|
||||
|
||||
<h3 id="not-happy">...and I'm not happy about it?</h3>
|
||||
<h3 id="not-happy">...and I'm not happy about it?</h3>
|
||||
|
||||
<p>I want to change Laura.</p>
|
||||
<p>I want to change Laura.</p>
|
||||
|
||||
<p>While I'm super happy that I was able to create a relatively decent mesh (topology-wise) that even animates fairly alright, I think Laura in her current form is boring. She <i>is</i> meant to be a 'regular girl' just being thrown into this dystopian world and unfamiliar (combat) situations, but... it doesn't have to mean that she has to look boring. Consider her clothes in particular; right now, her clothes are straight, clean, uneventful, and it's even worse on the back (where you, as the player, will consistently see her), since I've primarily focussed on modelling her from the front. There's <i>nothing</i> interesting in the back, by which I mean something akin to Ratchet carrying Clank on his back, Banjo carrying Kazooie, or even just a neat backpack or belt.</p>
|
||||
<p>While I'm super happy that I was able to create a relatively decent mesh (topology-wise) that even animates fairly alright, I think Laura in her current form is boring. She <i>is</i> meant to be a 'regular girl' just being thrown into this dystopian world and unfamiliar (combat) situations, but... it doesn't have to mean that she has to look boring. Consider her clothes in particular; right now, her clothes are straight, clean, uneventful, and it's even worse on the back (where you, as the player, will consistently see her), since I've primarily focussed on modelling her from the front. There's <i>nothing</i> interesting in the back, by which I mean something akin to Ratchet carrying Clank on his back, Banjo carrying Kazooie, or even just a neat backpack or belt.</p>
|
||||
|
||||
<p>I think Laura (being born in the 28th century) should look more futuristic, more interesting, and just overall more unique! I also want to make changes to aspects such as her hair, because while I have found out how to animate it in-game, it looks pretty unappealing. Plus, laying the back hair was kind of difficult; making it follow the flow of her shoulders meant that it would not deform properly when running. Making it straight would mean it clips through her torso when standing still. I <i>do</i> have an idea for how to fix that – by modelling it straight and then placing a capsule as collision shape for the <code>SpringBoneSimulator3D</code> – but this didn't even exist when I modelled Laura.</p>
|
||||
<p>I think Laura (being born in the 28th century) should look more futuristic, more interesting, and just overall more unique! I also want to make changes to aspects such as her hair, because while I have found out how to animate it in-game, it looks pretty unappealing. Plus, laying the back hair was kind of difficult; making it follow the flow of her shoulders meant that it would not deform properly when running. Making it straight would mean it clips through her torso when standing still. I <i>do</i> have an idea for how to fix that – by modelling it straight and then placing a capsule as collision shape for the <code>SpringBoneSimulator3D</code> – but this didn't even exist when I modelled Laura.</p>
|
||||
|
||||
<p>Also, I think I want to go with <a href="/projects/projectn5/devlog/20250203/#hair">tied-up hair</a> instead. Not only does it animate much easier without clipping, but it'll give Laura a more unique silhouette, I believe!</p>
|
||||
<p>Also, I think I want to go with <a href="/projects/projectn5/devlog/20250203/#hair">tied-up hair</a> instead. Not only does it animate much easier without clipping, but it'll give Laura a more unique silhouette, I believe!</p>
|
||||
|
||||
<p>I've been doing some sketching in a new B5-sized (much better size than A5 for sketches, I reckon) notebook, and I'm quite excited for this.</p>
|
||||
<p>I've been doing some sketching in a new B5-sized (much better size than A5 for sketches, I reckon) notebook, and I'm quite excited for this.</p>
|
||||
|
||||
<p>While I do wonder whether I'll be able to successfully execute upon my ideas, I believe that I'll be able to create something quite cool. Not only do I now have plenty of experience creating a character, but I'm also not creating one from literally nothing anymore. I have the current Laura model as a base to work off of – though I likely will not recycle many parts, since I want to make improvements to the mesh and loop cuts for better bends. I also have <b><i>ideas!</i></b> I was struggling <i>so hard</i> to come up with ideas for Laura before, <i>especially</i> concerning her clothes!</p>
|
||||
<p>While I do wonder whether I'll be able to successfully execute upon my ideas, I believe that I'll be able to create something quite cool. Not only do I now have plenty of experience creating a character, but I'm also not creating one from literally nothing anymore. I have the current Laura model as a base to work off of – though I likely will not recycle many parts, since I want to make improvements to the mesh and loop cuts for better bends. I also have <b><i>ideas!</i></b> I was struggling <i>so hard</i> to come up with ideas for Laura before, <i>especially</i> concerning her clothes!</p>
|
||||
|
||||
<p>I am confident that Laura 2.0 will be awesome.</p>
|
||||
<p>I am confident that Laura 2.0 will be awesome.</p>
|
||||
|
||||
<h2 id="weapons">New Firepower</h2>
|
||||
<h2 id="weapons">New Firepower</h2>
|
||||
|
||||
<p>I added two new weapons to the game! Neither one currently has a proper model, being relegated to primitive shapes, so they're not worth showing, BUT I'm quite happy about the fact I've been able to implement their basic functionality already.</p>
|
||||
<p>I added two new weapons to the game! Neither one currently has a proper model, being relegated to primitive shapes, so they're not worth showing, BUT I'm quite happy about the fact I've been able to implement their basic functionality already.</p>
|
||||
|
||||
<h3 id="igniter">Igniter / Flamethrower</h3>
|
||||
<h3 id="igniter">Igniter / Flamethrower</h3>
|
||||
|
||||
<p>The Igniter is a flamethrower with a rapid firing rate. Here is it in action:</p>
|
||||
<p>The Igniter is a flamethrower with a rapid firing rate. Here is it in action:</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/106.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/106.mp4" />
|
||||
|
||||
<p>The particle effect is a single .webp that was originally meant to have a blur effect, but I used Alpha Scissoring as the transparency mode in the <code>StandardMaterial3D</code> and kind of liked the effect, so I kept it. The fire effect is BY NO MEANS finished though.</p>
|
||||
<p>The particle effect is a single .webp that was originally meant to have a blur effect, but I used Alpha Scissoring as the transparency mode in the <code>StandardMaterial3D</code> and kind of liked the effect, so I kept it. The fire effect is BY NO MEANS finished though.</p>
|
||||
|
||||
<p>I was initially writing custom logic for the Igniter, which, <a href="#weapon-code">as you will see</a>, I wasn't super fond of, though I later was able to reel back the project and integrate it into automatic3.gd quite nicely. There's still a remainder of custom logic for the sfx, since the audio for the Igniter loops instead of one-off firing, but I think that can be integrated into the regular sfx script as well.</p>
|
||||
<p>I was initially writing custom logic for the Igniter, which, <a href="#weapon-code">as you will see</a>, I wasn't super fond of, though I later was able to reel back the project and integrate it into automatic3.gd quite nicely. There's still a remainder of custom logic for the sfx, since the audio for the Igniter loops instead of one-off firing, but I think that can be integrated into the regular sfx script as well.</p>
|
||||
|
||||
<p>I've been meaning to implement the Igniter for a while, because I thought a flamethrower could be a neat addition to the roster, but given the direction I've been meaning to take <a href="#story">the game's story</a>, I think a flamethrower is unsuitable and overly brutal, especially considering that Laura's is supposed to be a 'regular girl' thrown into this ruined world. Expecting her to use a flamethrower doesn't match her character, I find.</p>
|
||||
<p>I've been meaning to implement the Igniter for a while, because I thought a flamethrower could be a neat addition to the roster, but given the direction I've been meaning to take <a href="#story">the game's story</a>, I think a flamethrower is unsuitable and overly brutal, especially considering that Laura's is supposed to be a 'regular girl' thrown into this ruined world. Expecting her to use a flamethrower doesn't match her character, I find.</p>
|
||||
|
||||
<p>Then again, you could say the same thing about the other weapons, but I think they can work better as strategic items rather than merciless killing devices.</p>
|
||||
<p>Then again, you could say the same thing about the other weapons, but I think they can work better as strategic items rather than merciless killing devices.</p>
|
||||
|
||||
<p>This, by the way, also means that the arena will likely not make it into the final game, unless I integrate it on the premise of, for example, it serving as a colosseum of sorts where Laura can become a gladiator and risk her life for a reward.</p>
|
||||
<p>This, by the way, also means that the arena will likely not make it into the final game, unless I integrate it on the premise of, for example, it serving as a colosseum of sorts where Laura can become a gladiator and risk her life for a reward.</p>
|
||||
|
||||
<h3 id="rifle">Unnamed Rifle</h3>
|
||||
<h3 id="rifle">Unnamed Rifle</h3>
|
||||
|
||||
<p>The second weapon I've added is a rifle-type weapon! Whether it'll just be a rifle or a <i>sniper</i> rifle, I haven't decided yet.</p>
|
||||
<p>The second weapon I've added is a rifle-type weapon! Whether it'll just be a rifle or a <i>sniper</i> rifle, I haven't decided yet.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/107.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/107.mp4" />
|
||||
|
||||
<p>This rifle, unlike the Igniter, fits the ideas I've had for the story much better. I can imagine Laura using this as a long-range weapon from behind covers, possibly paired with a sliding mechanic that allows her to quickly and stealthily move between hiding spots, leaning over them to take shots... could be cool.</p>
|
||||
<p>This rifle, unlike the Igniter, fits the ideas I've had for the story much better. I can imagine Laura using this as a long-range weapon from behind covers, possibly paired with a sliding mechanic that allows her to quickly and stealthily move between hiding spots, leaning over them to take shots... could be cool.</p>
|
||||
|
||||
<p>The projectile ray takes a while to spawn after pressing the fire button. This happens because the projectile uses a <code>RayCast3D</code> to register a collision with a prop or an enemy so that the projectile stops exactly where the hit occurred instead of extending further. The <code>RayCast3D</code>, however, takes a while to process collisions after being moved, so the projectile overall has 3 frames of buffer time between being created and visibly appearing to calculate its end position. This creates a short delay. Not sure 1. whether I'll fix it, and 2. how I'd fix it, though I assume it would require some reworking and potentially scrapping the <code>RayCast3D</code> idea.</p>
|
||||
<p>The projectile ray takes a while to spawn after pressing the fire button. This happens because the projectile uses a <code>RayCast3D</code> to register a collision with a prop or an enemy so that the projectile stops exactly where the hit occurred instead of extending further. The <code>RayCast3D</code>, however, takes a while to process collisions after being moved, so the projectile overall has 3 frames of buffer time between being created and visibly appearing to calculate its end position. This creates a short delay. Not sure 1. whether I'll fix it, and 2. how I'd fix it, though I assume it would require some reworking and potentially scrapping the <code>RayCast3D</code> idea.</p>
|
||||
|
||||
<p>The projectile also... doesn't exactly hit where the crosshair is pointing. I'm pretty sure this has to do with the <code>RayCast3D</code> responsible for finding the collision point being attached to the player instead of the camera (which I've intentionally changed very recently – it used to be attached to the camera!), so it doesn't actually point where the crosshair is pointing. I'll get around to it eventually.</p>
|
||||
<p>The projectile also... doesn't exactly hit where the crosshair is pointing. I'm pretty sure this has to do with the <code>RayCast3D</code> responsible for finding the collision point being attached to the player instead of the camera (which I've intentionally changed very recently – it used to be attached to the camera!), so it doesn't actually point where the crosshair is pointing. I'll get around to it eventually.</p>
|
||||
|
||||
<p>The good news: it has nothing to do with the rifle, so the rifle isn't broken. The bad news: it affects every weapon, so technically, all weapons are broken.</p>
|
||||
<p>The good news: it has nothing to do with the rifle, so the rifle isn't broken. The bad news: it affects every weapon, so technically, all weapons are broken.</p>
|
||||
|
||||
<h3 id="preview">Item Preview Window</h3>
|
||||
<h3 id="preview">Item Preview Window</h3>
|
||||
|
||||
<p>I upgraded the item preview window slightly. Previously, the weapons just spun aimlessly, but now they can be tilted using the right analogue stick or the mouse to gaze upon them better! It's a small change but I'm proud of it, so here it is:</p>
|
||||
<p>I upgraded the item preview window slightly. Previously, the weapons just spun aimlessly, but now they can be tilted using the right analogue stick or the mouse to gaze upon them better! It's a small change but I'm proud of it, so here it is:</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/item-preview.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/item-preview.mp4" />
|
||||
|
||||
<p>I also fixed a long-running bug where the <code>DirectionalLight3D</code> of this preview would cast light on the gameplay world. This was caused by the preview being in the same physical space as the rest of the world (unavoidable) and being on the same visual layer (totally avoidable). I changed the layers, adjusted the light so that it doesn't contribute to the sky (very important with a shader that takes the scene's main light into consideration!), and it relieved a great headache that caused oddities such as two specular highlights on every model that received light.</p>
|
||||
<p>I also fixed a long-running bug where the <code>DirectionalLight3D</code> of this preview would cast light on the gameplay world. This was caused by the preview being in the same physical space as the rest of the world (unavoidable) and being on the same visual layer (totally avoidable). I changed the layers, adjusted the light so that it doesn't contribute to the sky (very important with a shader that takes the scene's main light into consideration!), and it relieved a great headache that caused oddities such as two specular highlights on every model that received light.</p>
|
||||
|
||||
<h3 id="weapon-icons">Please Appreciate These Wonderful Temporary Weapon Icons</h3>
|
||||
<h3 id="weapon-icons">Please Appreciate These Wonderful Temporary Weapon Icons</h3>
|
||||
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/104-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/106-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/107-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/108-icon.webp">
|
||||
</div>
|
||||
<div class="horizontally-centre-aligned">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/104-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/106-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/107-icon.webp">
|
||||
<img src="
|
||||
/projects/projectn5/devlog/20250316/108-icon.webp">
|
||||
</div>
|
||||
|
||||
<h2 id="code">Grand Code Overhaul</h2>
|
||||
<h2 id="code">Grand Code Overhaul</h2>
|
||||
|
||||
<p>In (re)starting work on my game, I've been confronted with a lot of... <i>legacy code?</i> Lots of code that I was unhappy with, at the very least.</p>
|
||||
<p>In (re)starting work on my game, I've been confronted with a lot of... <i>legacy code?</i> Lots of code that I was unhappy with, at the very least.</p>
|
||||
|
||||
<p>I've found that a lot of the code I've written – which at this point is up to 1.5 years old – isn't really up to par with what I want to write. It's inflexible, verbose, doesn't always follow standards and best practices, and overall really needed some overhauling. So, I've been doing just that.</p>
|
||||
<p>I've found that a lot of the code I've written – which at this point is up to 1.5 years old – isn't really up to par with what I want to write. It's inflexible, verbose, doesn't always follow standards and best practices, and overall really needed some overhauling. So, I've been doing just that.</p>
|
||||
|
||||
<p>I simplified logic, standardised scenes and code for game objects that share logic, implemented both inheritance and component-based designs where appropriate, and just yesterday, I've moved the code for fading in/out a black screen as well as the message handler displaying text such as "Collected 12 N5 Blaster ammo" and "Open vendor" into autoloads – I learned <i>this morning</i> that autoloads can be full scenes (.tscn) instead of just code (.gd). It makes a lot of sense, retrospectively, but now I'm just happy to have simplified some areas where I was unnecessarily passing references. For instance, displaying a text such as "Collected ammo" required the node response for collecting that ammo to have had a reference to the player, who in turn had a reference to the message handler and thus could display messages. This approach was overly convoluted.</p>
|
||||
<p>I simplified logic, standardised scenes and code for game objects that share logic, implemented both inheritance and component-based designs where appropriate, and just yesterday, I've moved the code for fading in/out a black screen as well as the message handler displaying text such as "Collected 12 N5 Blaster ammo" and "Open vendor" into autoloads – I learned <i>this morning</i> that autoloads can be full scenes (.tscn) instead of just code (.gd). It makes a lot of sense, retrospectively, but now I'm just happy to have simplified some areas where I was unnecessarily passing references. For instance, displaying a text such as "Collected ammo" required the node response for collecting that ammo to have had a reference to the player, who in turn had a reference to the message handler and thus could display messages. This approach was overly convoluted.</p>
|
||||
|
||||
<h3 id="godot-4-4">Godot 4.4 Changes</h3>
|
||||
<h3 id="godot-4-4">Godot 4.4 Changes</h3>
|
||||
|
||||
<p>If you haven't heard, Godot 4.4 is out! And that meant quite a few changes for my game:</p>
|
||||
<p>If you haven't heard, Godot 4.4 is out! And that meant quite a few changes for my game:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/godotengine/godot/pull/99895">Jolt is now integrated into the engine!</a> Since my use of the physics engine is relatively basic and does not rely on Jolt features that haven't been implemented in the engine yet, I switched immediately and was able to remove a dependency. The work that went into this is insane, I recommend checking out the pull request.</li>
|
||||
<li>Godot 4.4 added a new node called <a href="https://docs.godotengine.org/en/stable/classes/class_springbonesimulator3d.html"><code>SpringBoneSimulator3D</code></a>, which can be used for jiggle physics in a similar manner to <a href="https://godotengine.org/asset-library/asset/1595">JiggleBones</a>. I replaced my JiggleBones implementation with <code>SpringBoneSimulator3D</code> and was thus able to remove another dependency. I like the <code>SpringBoneSimulator3D</code> setup better, though I'm not as happy with the current result. I'll have to spend more time tweaking it and learning how to use it properly; it involves a bit more setup than JiggleBones, but it's more reliable, especially since it has better support for collision shapes (JiggleBones only supports spheres, but it's very rudimentary support, and they have to be sized way larger than expected to work at all. It's very unreliable. <a href="https://docs.godotengine.org/en/stable/classes/class_springbonecollision3d.html#class-springbonecollision3d"><code>SpringBoneCollision3D</code></a> works <i>so much better</i> and supports capsules and planes as well).</li>
|
||||
<li>Physics interpolation is now available for 3D, which fixed <a href="https://phantom-camera.dev/support/faq#i-m-seeing-jitter-what-can-i-do">an issue that caused nodes tracked with a Phantom Camera to jitter</a>.</li>
|
||||
<li>Godot has typed <code>Dictionary</code> support in <code>@export</code> properties now, which in <i>my world</i> is a <b>huge</b> deal. It means you can do <code>@export var dict: Dictionary[int, String]</code> and dynamically add to the Dictionary in the inspector. This, of course, allows for custom <code>Resource</code>s as well. I use this, for example, in the item statistics, where I have a <code>Dictionary</code> holding item statistics as a custom <code>Resource</code> associated with the item's ID. This <code>Resource</code> has nested <code>Resource</code>s for individual weapon levels. It's <i>so</i> cool! I'm disproportionately happy about this change.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="https://github.com/godotengine/godot/pull/99895">Jolt is now integrated into the engine!</a> Since my use of the physics engine is relatively basic and does not rely on Jolt features that haven't been implemented in the engine yet, I switched immediately and was able to remove a dependency. The work that went into this is insane, I recommend checking out the pull request.</li>
|
||||
<li>Godot 4.4 added a new node called <a href="https://docs.godotengine.org/en/stable/classes/class_springbonesimulator3d.html"><code>SpringBoneSimulator3D</code></a>, which can be used for jiggle physics in a similar manner to <a href="https://godotengine.org/asset-library/asset/1595">JiggleBones</a>. I replaced my JiggleBones implementation with <code>SpringBoneSimulator3D</code> and was thus able to remove another dependency. I like the <code>SpringBoneSimulator3D</code> setup better, though I'm not as happy with the current result. I'll have to spend more time tweaking it and learning how to use it properly; it involves a bit more setup than JiggleBones, but it's more reliable, especially since it has better support for collision shapes (JiggleBones only supports spheres, but it's very rudimentary support, and they have to be sized way larger than expected to work at all. It's very unreliable. <a href="https://docs.godotengine.org/en/stable/classes/class_springbonecollision3d.html#class-springbonecollision3d"><code>SpringBoneCollision3D</code></a> works <i>so much better</i> and supports capsules and planes as well).</li>
|
||||
<li>Physics interpolation is now available for 3D, which fixed <a href="https://phantom-camera.dev/support/faq#i-m-seeing-jitter-what-can-i-do">an issue that caused nodes tracked with a Phantom Camera to jitter</a>.</li>
|
||||
<li>Godot has typed <code>Dictionary</code> support in <code>@export</code> properties now, which in <i>my world</i> is a <b>huge</b> deal. It means you can do <code>@export var dict: Dictionary[int, String]</code> and dynamically add to the Dictionary in the inspector. This, of course, allows for custom <code>Resource</code>s as well. I use this, for example, in the item statistics, where I have a <code>Dictionary</code> holding item statistics as a custom <code>Resource</code> associated with the item's ID. This <code>Resource</code> has nested <code>Resource</code>s for individual weapon levels. It's <i>so</i> cool! I'm disproportionately happy about this change.</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="node-refs">$</h3>
|
||||
<h3 id="node-refs">$</h3>
|
||||
|
||||
<p>Yesterday, I replaced a lot of $ node references with <code>@export</code> properties for performance reasons. I watched <a href="https://www.youtube.com/watch?v=fb68YXIBinc">this video on node retrieval</a>, where I found out that $ references are inefficient. I then thought about this, and... yeah, that makes sense. $ is just a short-hand for <code>get_node()</code>, which means that, in a <code>_process()</code> context, I'm calling <code>get_node()</code> potentially 60 times a second – every time I use it. Considering this <i>massive</i> performance implication, I refactored a lot of code and created loads more <code>@export</code> references. They're easier to manage in case of moving or renaming nodes, anyway.</p>
|
||||
<p>Yesterday, I replaced a lot of $ node references with <code>@export</code> properties for performance reasons. I watched <a href="https://www.youtube.com/watch?v=fb68YXIBinc">this video on node retrieval</a>, where I found out that $ references are inefficient. I then thought about this, and... yeah, that makes sense. $ is just a short-hand for <code>get_node()</code>, which means that, in a <code>_process()</code> context, I'm calling <code>get_node()</code> potentially 60 times a second – every time I use it. Considering this <i>massive</i> performance implication, I refactored a lot of code and created loads more <code>@export</code> references. They're easier to manage in case of moving or renaming nodes, anyway.</p>
|
||||
|
||||
<h3 id="weapon-code">Weapon Code</h3>
|
||||
<h3 id="weapon-code">Weapon Code</h3>
|
||||
|
||||
<p>The weapons received some of the biggest changes. Previously, I had a bunch of different classes for a base weapon, semiauto, automatic, and thrower weapon (the last one being a semiauto weapon that fires in an arc), and they all kind of did similar things. I first used inheritance, then switched to a component-based design, where I still needed more boilerplate than I was comfortable with. The thrower in particular copied all the code from the other weapon types, just with changed logic for the projectile path.</p>
|
||||
<p>The weapons received some of the biggest changes. Previously, I had a bunch of different classes for a base weapon, semiauto, automatic, and thrower weapon (the last one being a semiauto weapon that fires in an arc), and they all kind of did similar things. I first used inheritance, then switched to a component-based design, where I still needed more boilerplate than I was comfortable with. The thrower in particular copied all the code from the other weapon types, just with changed logic for the projectile path.</p>
|
||||
|
||||
<p>It was a mess. It's all overhauled now.</p>
|
||||
<p>It was a mess. It's all overhauled now.</p>
|
||||
|
||||
<p>There's <code>weapon3.gd</code>, which is the base weapon class for all weapons, inheriting from <code>item.gd</code>. Then, there are <code>semiauto3.gd</code> and <code>automatic3.gd</code>, which implement only the functions to determine what happens when the player presses and releases the shoot button – one of them fires once, the other one repeatedly.</p>
|
||||
<p>There's <code>weapon3.gd</code>, which is the base weapon class for all weapons, inheriting from <code>item.gd</code>. Then, there are <code>semiauto3.gd</code> and <code>automatic3.gd</code>, which implement only the functions to determine what happens when the player presses and releases the shoot button – one of them fires once, the other one repeatedly.</p>
|
||||
|
||||
<p>Notice there's no <code>thrower3.gd</code>? It's unnecessary. The logic for the arc has moved into the projectile. Why would the weapon be responsible, I asked myself, considering that the throwers otherwise acted identically to the semiauto weapons. I also moved a lot more properties away from the weapons; damage and speed, among other things, have been moved to the projectile. AoE damage and radius, for example, have been moved into the explosion that's spawned by the projectile upon impact. I've generally moved properties to where they're needed instead of bunching them all up at the weapon and then sending them over via long and unnecessary functions. Like, for example, a function that spawned the projectile, which used to look like this: <code>start_moving(direction: Vector3, ramp_up_speed: float, damage: float, explosion_resource: PackedScene) -> void</code></p>
|
||||
<p>Notice there's no <code>thrower3.gd</code>? It's unnecessary. The logic for the arc has moved into the projectile. Why would the weapon be responsible, I asked myself, considering that the throwers otherwise acted identically to the semiauto weapons. I also moved a lot more properties away from the weapons; damage and speed, among other things, have been moved to the projectile. AoE damage and radius, for example, have been moved into the explosion that's spawned by the projectile upon impact. I've generally moved properties to where they're needed instead of bunching them all up at the weapon and then sending them over via long and unnecessary functions. Like, for example, a function that spawned the projectile, which used to look like this: <code>start_moving(direction: Vector3, ramp_up_speed: float, damage: float, explosion_resource: PackedScene) -> void</code></p>
|
||||
|
||||
<h2 id="enemies">My Enemies Follow Me Wherever I Go</h2>
|
||||
<h2 id="enemies">My Enemies Follow Me Wherever I Go</h2>
|
||||
|
||||
<p>The enemies have pathfinding now implemented! I used Godot's <code>NavigationRegion</code> to create a mesh the enemies can traverse. Since they all inherit from <code>StairsCharacter</code> – a class I once downloaded to deal with stair stepping for <code>CharacterController3D</code>s – they can traverse the world about as easily as the player. It works super well! I was able to piece it together quite quickly, after a friend of mine figured out how to implement navigation in another game we're working on together.</p>
|
||||
<p>The enemies have pathfinding now implemented! I used Godot's <code>NavigationRegion</code> to create a mesh the enemies can traverse. Since they all inherit from <code>StairsCharacter</code> – a class I once downloaded to deal with stair stepping for <code>CharacterController3D</code>s – they can traverse the world about as easily as the player. It works super well! I was able to piece it together quite quickly, after a friend of mine figured out how to implement navigation in another game we're working on together.</p>
|
||||
|
||||
<Video src="/projects/projectn5/devlog/20250316/enemy-stairs.mp4" />
|
||||
<Video src="/projects/projectn5/devlog/20250316/enemy-stairs.mp4" />
|
||||
|
||||
<h2 id="story">Story Changes</h2>
|
||||
<h2 id="story">Story Changes</h2>
|
||||
|
||||
<p>I have some minor ideas for where I want the story to head in.</p>
|
||||
<p>I have some minor ideas for where I want the story to head in.</p>
|
||||
|
||||
<h3 id="genre">Where the Game is Headed Gameplay-Wise</h3>
|
||||
<h3 id="genre">Where the Game is Headed Gameplay-Wise</h3>
|
||||
|
||||
<p>When I showed the Laura model to a friend recently, they noted how she doesn't look like she belongs in a shooter, but more of a puzzle-type game. I think that incorporating some elements of that sort could be quite cool, actually; solving problems to uncover the mystery of what happened to Laura's world.</p>
|
||||
<p>When I showed the Laura model to a friend recently, they noted how she doesn't look like she belongs in a shooter, but more of a puzzle-type game. I think that incorporating some elements of that sort could be quite cool, actually; solving problems to uncover the mystery of what happened to Laura's world.</p>
|
||||
|
||||
<p>That's the general idea.</p>
|
||||
<p>That's the general idea.</p>
|
||||
|
||||
<h3 id="story-weapons">How (Many) Weapons Will Play Into It</h3>
|
||||
<h3 id="story-weapons">How (Many) Weapons Will Play Into It</h3>
|
||||
|
||||
<p>Heading into this direction means that a large arsenal makes less sense. While I do still want to have combat elements, I've considered reducing the amount of weapons from 12 (which was even as high as 16 way earlier) to 8 or even just 4.</p>
|
||||
<p>Heading into this direction means that a large arsenal makes less sense. While I do still want to have combat elements, I've considered reducing the amount of weapons from 12 (which was even as high as 16 way earlier) to 8 or even just 4.</p>
|
||||
|
||||
<p>The amount of weapons in the game also impacts UI: having 8 weapons total would warrant a quick select, like the one currently implemented – though I'd probably make it look a bit more similar to Ratchet: Gladiator, where it is displayed in the upper left corner of the screen. 4 weapons total might instead be served through selection via the d-pad (or numbers 1-4 on the keyboard), though.</p>
|
||||
<p>The amount of weapons in the game also impacts UI: having 8 weapons total would warrant a quick select, like the one currently implemented – though I'd probably make it look a bit more similar to Ratchet: Gladiator, where it is displayed in the upper left corner of the screen. 4 weapons total might instead be served through selection via the d-pad (or numbers 1-4 on the keyboard), though.</p>
|
||||
|
||||
<h2 id="notebook">A Notebook for My Thoughts</h2>
|
||||
<h2 id="notebook">A Notebook for My Thoughts</h2>
|
||||
|
||||
<p>I bought a new notebook recently! While I had a notebook before – a <a href="https://www.thalia.de/shop/home/artikeldetails/A1071363499">green A5 notebook with dotted pages by Share</a> – it was filling up with notes from university, internships, and other miscellaneous things I didn't want to clutter my project notebook with.</p>
|
||||
<p>I bought a new notebook recently! While I had a notebook before – a <a href="https://www.thalia.de/shop/home/artikeldetails/A1071363499">green A5 notebook with dotted pages by Share</a> – it was filling up with notes from university, internships, and other miscellaneous things I didn't want to clutter my project notebook with.</p>
|
||||
|
||||
<p>I switched to a <a href="https://www.thalia.de/shop/home/artikeldetails/A1071895735">black B5 notebook, also with dotted pages, by Plan A</a>. This cost me a lot less than a Leuchtturm1917 B5 notebook (like 60% cheaper) and still totally serves my needs. I like the B5 format, it's just a fantastic size. It's bigger than A5, which allows for more expression, details, and overall just breathing space on the pages, but it's also not as big as A4, which would be unwieldy. B5 is a superb format for my sketch notebooks; can recommend.</p>
|
||||
<p>I switched to a <a href="https://www.thalia.de/shop/home/artikeldetails/A1071895735">black B5 notebook, also with dotted pages, by Plan A</a>. This cost me a lot less than a Leuchtturm1917 B5 notebook (like 60% cheaper) and still totally serves my needs. I like the B5 format, it's just a fantastic size. It's bigger than A5, which allows for more expression, details, and overall just breathing space on the pages, but it's also not as big as A4, which would be unwieldy. B5 is a superb format for my sketch notebooks; can recommend.</p>
|
||||
|
||||
<h2 id="bsky">Bluesky</h2>
|
||||
<h2 id="bsky">Bluesky</h2>
|
||||
|
||||
<p>I have a <a href="https://bsky.app/profile/denizk0461.bsky.social">Bluesky account</a> now!</p>
|
||||
<p>I have a <a href="https://bsky.app/profile/denizk0461.bsky.social">Bluesky account</a> now!</p>
|
||||
|
||||
<p>I've been eyeing the platform for a while now, but lately I've noticed that quite a few people I enjoy following have Bluesky presences. Plus there are other cool people there, as well as the Feed feature where I can, for example, see all Godot-related content. I've created an account with the idea of potentially posting some of my gamedev progress on there, though I have not yet shared anything. Still figuring out social media; while I grew up during the rise of social media (on mobile phones in particular), I've never really been into them quite as much as others have.</p>
|
||||
<p>I've been eyeing the platform for a while now, but lately I've noticed that quite a few people I enjoy following have Bluesky presences. Plus there are other cool people there, as well as the Feed feature where I can, for example, see all Godot-related content. I've created an account with the idea of potentially posting some of my gamedev progress on there, though I have not yet shared anything. Still figuring out social media; while I grew up during the rise of social media (on mobile phones in particular), I've never really been into them quite as much as others have.</p>
|
||||
|
||||
<p>Maybe this'll be different though, seen as I have a relatively specific goal here. We'll see!</p>
|
||||
<p>Maybe this'll be different though, seen as I have a relatively specific goal here. We'll see!</p>
|
||||
|
||||
<h2 id="addendum">Addendum</h2>
|
||||
<h2 id="addendum">Addendum</h2>
|
||||
|
||||
<p>Sorry for the walls of text! I've really just been working more on backend stuff than visually interesting things, mostly to clean up the project, but also because I feel that's my strength. I'm super good at programming expandable, relatively easy to maintain code, at least in comparison to my artistic skills. However, I'm <i>absolutely</i> working on story, visuals, more weapon, and of course Laura 2.0, so hopefully I'll have more to show for in the coming weeks and months!!</p>
|
||||
<p>Sorry for the walls of text! I've really just been working more on backend stuff than visually interesting things, mostly to clean up the project, but also because I feel that's my strength. I'm super good at programming expandable, relatively easy to maintain code, at least in comparison to my artistic skills. However, I'm <i>absolutely</i> working on story, visuals, more weapon, and of course Laura 2.0, so hopefully I'll have more to show for in the coming weeks and months!!</p>
|
||||
</Content>
|
||||
@@ -39,9 +39,9 @@ export const projects: Project[] = [
|
||||
banner: "/projects/projektike/banner.webp",
|
||||
icon: "",
|
||||
title: "Projektike",
|
||||
subtitle: "Wizard Game",
|
||||
subtitle: "PvP Game",
|
||||
paragraphs: [
|
||||
"Two friends of mine and I are working together on a multiplayer wizard game where you can throw magical and technological artifacts at one another.",
|
||||
"Two friends of mine and I are working together on a multiplayer game where you can throw magical artifacts at one another.",
|
||||
],
|
||||
links: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user