<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>

<svelte:head>
    <title>The Arena Update | denizk0461</title> 
</svelte:head>

<Content>
    <BannerTitle title="Project N5 Progress Update: 2024-03-24" subtitle="The Arena Update" banner="../../previews/2024/0324.webp" />

    <TableOfContents />

    <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>

    <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>

    <h2 id="product">The Finished Product</h2>

    <Video src="demonstration.mp4" />

    <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>

    <h3 id="enemy">The New Enemy, Suzanne Cylinder</h3>

    <img src="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>

    <Video src="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>

    <img src="lookingup.webp">
    <div class="image-subtitle-container">
        <span class="image-subtitle">send help</span>
    </div>

    <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>All that information looks a little like this:</p>

    <pre class="code-block">
    const arena_challenges = &lbrace;
        1099: &lbrace;
            "reward": 7382,
            "rounds": [
                &lbrace;
                    "type": "regular",
                    "spawner_count": 3,
                    "enemies": [
                        ENEMY_MONKEY,
                        ENEMY_MONKEY,
                        ENEMY_MONKEY,
                        ...
                    ],
                &rbrace;,
                ...
            ],
        &rbrace;,
    &rbrace;</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>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>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>

    <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>

    <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>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>
</Content>