[{"content":"Check out Pick Some Axe on: Steam, itch.io\nMy Role: Gameplay / UI Programmer Made in Unity | Team Size: 13 Refactored existing UI systems to make them more maintainable, and created new UI systems with a focus on sustainability Designed new gameplay features for combat, puzzle-solving, and exploration Created developer tools with specific functions requested by other programmers and designers to optimize the testing process of new features Code Snippets BreakableBarrel.cs using System; using UnityEngine; using FMODUnity; [Serializable] public struct BarrelDrop { public GameObject item; public float percentChance; } public class BreakableBarrel : MonoBehaviour { [SerializeField] GameObject barrelBreakVFX; [SerializeField] BarrelDrop[] drops; [SerializeField] EventReference BreakSound; void Awake() { BreakSound = RuntimeManager.PathToEventReference(\u0026#34;event:/SFX/Interactions/Barrel Break\u0026#34;); } void OnTriggerEnter(Collider other) { // break when player hits this with pickaxe if(other.CompareTag(\u0026#34;PickaxeHitbox\u0026#34;)) { Break(); } } private void OnCollisionEnter(Collision collision) { // break when enemy is knocked back into this if (collision.collider.CompareTag(\u0026#34;Enemy\u0026#34;)) { EnemyScript enemy = collision.collider.GetComponent\u0026lt;EnemyScript\u0026gt;(); // only break if enemy is actually in knockback if (enemy != null \u0026amp;\u0026amp; enemy.stunned) { Break(); } } // break when player belly bashes this BellyDash bellyDash = collision.gameObject.GetComponent\u0026lt;BellyDash\u0026gt;(); if (bellyDash != null \u0026amp;\u0026amp; bellyDash.IsDashing) { Break(); } } public void Break() { DropItem(); if(barrelBreakVFX) { Instantiate(barrelBreakVFX, transform.position, Quaternion.identity); } RuntimeManager.PlayOneShot(BreakSound, transform.position); // set persistence key so the barrel stays destroyed between play sessions PersistenceKey key = GetComponent\u0026lt;PersistenceKey\u0026gt;(); if (null != key) { key.SetDestroyed(true); } Destroy(gameObject); } public void DropItem() { float rand = UnityEngine.Random.Range(0f, 100f); float accumulation = 0f; // loop through each item until the RNG number is within that item\u0026#39;s \u0026#34;window\u0026#34; // accumulation creates windows by stacking each chance on top of each other // without having to define the ranges manually for(int i = 0; i \u0026lt; drops.Length; i++) { accumulation += drops[i].percentChance; if(rand \u0026lt;= accumulation) { if(null != drops[i].item) { Instantiate(drops[i].item, transform.position, Quaternion.identity); } i = drops.Length; } } } } GembitsUI.cs using TMPro; using UnityEngine; using UnityEngine.UI; public class GembitsUI : MonoBehaviour { [SerializeField] float visibleTime = 3.0f; [SerializeField] float fadeOutTime = 1.0f; float visibleTimer = 0f; bool fadingOut = false; bool forceVisible = false; Image gembitsImage; TMP_Text gembitsText; void Awake() { gembitsImage = GetComponentInChildren\u0026lt;Image\u0026gt;(); gembitsText = GetComponentInChildren\u0026lt;TMP_Text\u0026gt;(); } void Start() { PlayerState.ListenToGembits(GembitsChanged); GembitsChanged(PlayerState.GetGembits()); ShopHandler[] shops = FindObjectsOfType\u0026lt;ShopHandler\u0026gt;(); foreach(ShopHandler shop in shops) { shop.ListenToInShop(InShop); } } void OnDestroy() { PlayerState.ListenToGembits(GembitsChanged, false); ShopHandler[] shops = FindObjectsOfType\u0026lt;ShopHandler\u0026gt;(); foreach(ShopHandler shop in shops) { shop.ListenToInShop(InShop, false); } } void Update() { visibleTimer += Time.deltaTime; if(!forceVisible \u0026amp;\u0026amp; !fadingOut \u0026amp;\u0026amp; visibleTimer \u0026gt;= visibleTime) { fadingOut = true; gembitsImage.CrossFadeAlpha(0f, fadeOutTime, false); gembitsText.CrossFadeAlpha(0f, fadeOutTime, false); } } void ResetFadeOut() { visibleTimer = 0f; fadingOut = false; gembitsImage.CrossFadeAlpha(1f, 0f, true); gembitsText.CrossFadeAlpha(1f, 0f, true); } void GembitsChanged(int amount) { gembitsText.text = amount.ToString(\u0026#34;D6\u0026#34;); ResetFadeOut(); } void InShop(bool inShop) { forceVisible = inShop; ResetFadeOut(); } } LastSafePosition.cs using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(ThirdPersonController))] public class LastSafePosition : MonoBehaviour { [SerializeField, Tooltip(\u0026#34;Layers that count as safe ground.\u0026#34;)] LayerMask groundLayers; [SerializeField] float raycastLength = 1.5f; // Minimum height for each level of safe positions [SerializeField] List\u0026lt;Transform\u0026gt; respawnFloors; float[] respawnFloorsY; Vector3[] safePositions; Vector3 overrideSafePosition = Vector3.positiveInfinity; // used during final climb bool safePosFound; readonly Vector3[] raycasts = { new(-1, -1, -1), new(0, -1, -1), new(1, -1, -1), new(-1, -1, 0), new(0, -1, 0), new(1, -1, 0), new(-1, -1, 1), new(0, -1, 1), new(1, -1, 1) }; void Awake() { BubbleSortRespawnFloors(); respawnFloorsY = new float[respawnFloors.Count]; safePositions = new Vector3[respawnFloors.Count]; for(int i = 0; i \u0026lt; respawnFloors.Count; i++) { respawnFloorsY[i] = respawnFloors[i].position.y; safePositions[i] = Vector3.positiveInfinity; Destroy(respawnFloors[i].gameObject); } respawnFloors.Clear(); } void Start() { Vector3 returnPos = PlayerState.GetReturnPos(); if(!Equals(Vector3.positiveInfinity, returnPos) \u0026amp;\u0026amp; SceneState.GetScene() == PlayerState.GetReturnLevel()) { GetComponent\u0026lt;ThirdPersonController\u0026gt;().Teleport(returnPos); } } void OnDestroy() { // try to set the return level ScenePSA prevScene = SceneState.GetPrevScene(); bool success = PlayerState.SetReturnLevel(prevScene); if(ScenePSA.MAIN_MENU == prevScene) { return; } // special case: this is a purposeful failure else if(!success) { Debug.LogError(\u0026#34;Failed to set return level to: \u0026#34; + SceneState.GetPrevScene()); return; } // if that works, save last safe position as return position (if one exists) Vector3 returnPos; for(int i = 0; i \u0026lt; GetFloors(); i++) { returnPos = Get(transform.position.y, i); if(!Equals(Vector3.positiveInfinity, returnPos)) { i = GetFloors(); PlayerState.SetReturnPos(returnPos); } } PlayerState.Save(); // weird place to call this but it should be fine } void FixedUpdate() { safePosFound = true; // cast out a bunch of raycasts to determine what the ground is like around the player // if any of them return no ground collision, the position is not a valid respawn position for(int i = 0; i \u0026lt; 9; i++) { if(!Physics.Raycast(transform.position, raycasts[i], out _, raycastLength, groundLayers)) { safePosFound = false; i = raycasts.Length; } } if(!safePosFound) { return; } // save safe position within highest possible floor for(int i = 0; i \u0026lt; safePositions.Length; i++) { if(transform.position.y \u0026gt; respawnFloorsY[i]) { safePositions[i] = transform.position; //i = safePositions.Length; } } } // https://www.geeksforgeeks.org/dsa/bubble-sort-algorithm/ void BubbleSortRespawnFloors() { int n = respawnFloors.Count; if(0 == n) { return; } bool swapped; for(int i = 0; i \u0026lt; n-1; i++) { swapped = false; for(int j = 0; j \u0026lt; n-i-1; j++) { // sort greatest to least if(respawnFloors[j].position.y \u0026lt; respawnFloors[j+1].position.y) { (respawnFloors[j+1], respawnFloors[j]) = (respawnFloors[j], respawnFloors[j+1]); swapped = true; } } if(!swapped) { i = n; } } } public Vector3 Get(float currentY, int backUp = 0) { // Safe position override has priority, used by final climb if(!Equals(Vector3.positiveInfinity, overrideSafePosition)) { Vector3 temp = overrideSafePosition; overrideSafePosition = Vector3.positiveInfinity; // override decays after one respawn return temp; } // otherwise, determine which last safe position to use for(int i = 0; i \u0026lt; respawnFloorsY.Length; i++) { if(currentY \u0026gt;= respawnFloorsY[i]) { if(backUp \u0026gt; i) { backUp = i; } return safePositions[i-backUp]; } } Debug.LogWarning(\u0026#34;Couldn\u0026#39;t find a floor to respawn on!\u0026#34;); return Vector3.positiveInfinity; } public int GetFloors() { return respawnFloorsY.Length; } public void SetOverrideSafePosition(Vector3 pos) { overrideSafePosition = pos; } } ","permalink":"https://topmost-hat.github.io/portfolio/projects/pick-some-axe/","summary":"Pick Some Axe","title":""},{"content":"Check out Nest Quest on: itch.io\nMy Role: Gameplay Programmer Made in Unreal Engine 5 | Team Size: 11 Developed foundational gameplay mechanics such as movement and collectables using Blueprint Implemented UI and HUD elements using assets created by artists Applied Agile Scrum development practices to define and organize tasks, identify and mitigate risks, and ensure constant communication with the rest of the development team ","permalink":"https://topmost-hat.github.io/portfolio/projects/nest-quest/","summary":"Nest Quest","title":""},{"content":"About Me Pictured: Me enjoying my summer job as a zipline guide, c. 2024.\nHello, I\u0026rsquo;m Atticus. I\u0026rsquo;m a game programmer specializing in gameplay, systems, and UI.\nI graduated from Champlain College in May of 2026 with a B.S. in Game Programming and a minor in Mathematics. I really enjoy working with others to turn great ideas into well-structured systems, and combining those systems to create engaging gameplay experiences.\nSome of my favorite games include Deltarune, Hollow Knight, Inscryption, Super Mario Galaxy, and Team Fortress 2. When I\u0026rsquo;m not playing games, I also enjoy biking and reading manga.\n","permalink":"https://topmost-hat.github.io/portfolio/aboutme/","summary":"\u003ch1 id=\"about-me\"\u003eAbout Me\u003c/h1\u003e\n\u003cp\u003e\u003cimg alt=\"(image not found)\" loading=\"lazy\" src=\"/portfolio/aboutme/akc_zip.jpg\"\u003e\n\u003cem\u003ePictured: Me enjoying my summer job as a zipline guide, c. 2024.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eHello, I\u0026rsquo;m Atticus. I\u0026rsquo;m a game programmer specializing in gameplay, systems, and UI.\u003c/p\u003e\n\u003cp\u003eI graduated from Champlain College in May of 2026 with a B.S. in Game Programming and a minor in Mathematics. I really enjoy working with others to turn great ideas into well-structured systems, and combining those systems to create engaging gameplay experiences.\u003c/p\u003e","title":""},{"content":"\nDownload as PDF ","permalink":"https://topmost-hat.github.io/portfolio/resume/","summary":"\u003cp\u003e\u003cimg alt=\"Atticus Clark\u0026rsquo;s Resume\" loading=\"lazy\" src=\"/portfolio/resume/atticus-clark-resume.png\"\u003e\u003c/p\u003e\n\n\u003ca class=\"hugo-shortcodes-download\" href=\"./atticus-clark-resume.pdf\" download=\"AtticusClarkResume.pdf\"\u003eDownload as PDF\u003c/a\u003e","title":"Resume"}]