Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
baronvonzoomie - itch.io
[go: Go Back, main page]

Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

baronvonzoomie

7
Posts
1
Topics
3
Followers
A member registered Mar 21, 2026

Creator of

Recent community posts

Dev Diary #4

This one might be a bit dry and boring to non tech people, but I have learned a lot this sprint and is pretty excited about it. Blog #3 ended with the combat loop working for the first time — the player attacks, the scout chases, the scout attacks back, the player reacts. That was the threshold I needed to hit before this blog could exist. This sprint the goal shifted: the loop runs, so now it needs to feel like something is actually happening.

That turned out to mostly be a question of signal. When a hit lands, the player needs to feel it. When loot drops, it needs to be readable from across the screen. When a piece of gear has three affixes, they should mean something when you read them. A lot of the work this sprint — the shaders, the weapon design, the item system — was answering some version of that same question.

Shaders turned out to be the right tool for more of it than I expected.

Shader

As I was working on one of affix's visual effect, which is a circular shockwave expanding outwards, I started with a simple idea: draw a ring with 1 pixel thickness, then manipulate the scale based on time. This, however, did not work as I wanted. For some reason I think the thickness will also increase, but what happens is the size of the ring increased, which made much more sense than what I was expecting. So I went to do some research on this type of effect, and came across shaders.

A shader is a small program that runs directly on the GPU, and its job is to determine the final color of every pixel on screen. I had heard of shaders before but never written one. It sounded intimidating, so I did what any engineer would do: I found a resource — the Book of Shaders — and started from chapter 1.

The key insight that unlocked everything for me is that shaders do not know about the world. They do not know where your character is, they do not know the screen resolution, and they do not know what frame you are on. All they know is what you explicitly pass in, in engineering terms, they are essentially stateless. These passed-in values are called uniforms, and once I understood that — that a uniform is just a CPU-written value that every GPU thread can read — a lot of things started to make sense.

For the shockwave ring, the math turned out to be simpler than I expected. Calculate the distance from the current pixel to the center of the quad, then check if that distance falls within a band defined by an inner and outer radius. Expand that band over time and you have an expanding ring. smoothstep() handles the soft edges so it doesn't look like a hard cutoff.

There were a few gotchas that cost me some time. The first was that everything in the shader has to be in the same coordinate space. Shaders operate in UV space — 0 to 1 across the quad — so if you pass in a radius of 120 pixels it means nothing to the shader. Everything has to be normalized first. The second was premultiplied alpha. MonoGame's default blend mode expects you to multiply your RGB by alpha before returning from the shader. Without it, pixels that should be transparent were instead adding their full color on top of the background, which is why the ring first appeared as a solid yellow square.

It took a few sessions to get to a working result, but seeing the ring expand and thin out in game for the first time made it worth it. And unlike the circle.png approach, the shader gives full control over the shape, color, and timing entirely in code — no art asset needed.

The gif should demonstrate the idea, but since it's 240p and low framerate, it would not look as good as the one in the video.

Drop Indicator Shader

After the shockwave I felt more comfortable with the idea of writing shaders, so when I needed a visual for item drops I decided to lean into it rather than reach for a static sprite.

The design goal was readable at a glance: when an enemy dies and drops loot, the player needs to immediately understand that something is on the ground and roughly how valuable it is. The rarity tint — white for common, blue for magic, yellow for rare — handles the "how valuable" part from the C# side. The shader's job is to make the drop look alive and holographic rather than just a flat square sitting on the floor.

I landed on three layered effects: chromatic aberration, scanlines, and flicker. Chromatic aberration has to go first because it is the sampling step, it is how you get the pixels off the texture in the first place. Scanlines go second because they only darken horizontal bands and do not need to be distorted by the aberration. Flicker goes last because it dims the entire output, so everything built in the previous steps gets affected uniformly.

Chromatic aberration in a shader is simpler than the name suggests. Instead of sampling the texture once and taking all four channels, you sample it three times — once per color channel — each at a slightly different UV offset. Red shifts right, blue shifts left, green stays anchored at the center. The direction is not arbitrary: red light has a longer wavelength than blue, so when light bends through a lens the two channels separate on opposite sides. I did not expect physics to be relevant when writing a GPU program, but here we are.

Scanlines use a function I now think of as the shader workhorse: frac(). If you multiply uv.y by some number N and take the fractional part, you get a value that resets to zero N times across the height of the quad. That gives you N repeating bands, and within each band the value runs from 0 to 1. From there it is just a matter of picking a threshold — I used 0.8 — and darkening the top 20% of each band. The step() function handles the threshold.

The trickiest part of the scanline logic was getting the darkening formula right. My first instinct was step(0.8, scanPos) * 0.5, which gives you 0.5 in the dark band and 0.0 everywhere else. Multiplying the pixel color by 0.0 makes everything black, which is backwards. The fix I landed on was (step(scanPos, 0.8) + 1) * 0.5 — flipping the argument order so step returns 1 for most pixels and 0 for the dark band, then using the add-one-and-halve trick to convert that binary output into a 1.0 / 0.5 range. I like this formula because once you see the trick, it is obvious.

There was also a compiler bug I introduced without realizing it. I named my local variable frac, which is also the name of the built-in HLSL function I was calling on the same line. The compiler cannot resolve the call because the variable shadows the built-in. Renaming it to fraction fixed it, and it is the kind of thing that would take a long time to debug if you did not already know to look for it (and it did take me a long time lol)

Flicker was the most design-driven of the three. I wanted mostly-on with brief drops, not a smooth pulse — a glitch, not breathing. sin(elapsed * 12) gives a cycle fast enough to feel erratic, and step(0.8, sin(...)) ensures the image only dips when the sine value pushes past the high threshold, which happens briefly each cycle. Same step-as-threshold pattern as the scanlines, just applied to time instead of UV.

The shader is wired to the item drop system now. Each drop tracks its own elapsed time and manages its own draw pass with the shader applied. When I have the art asset in place, the effect should be immediately visible in playtesting — which is exactly what I want from a loot indicator. If a playtester walks past a drop without noticing it, the shader has failed its job.

After getting the chromatic aberration, scanlines, and flicker working, I wanted to push the holographic feel further by adding a horizontal stretch — a band of UV distortion that travels down the sprite, like a VHS tracking error scrolling through a bad signal. The pixels inside the band shift left or right by a smooth amount, with the center of the band distorting the most and the edges tapering off cleanly.

The math for this turned out to be the most involved of the three effects, and also the most satisfying to reason through. The distortion amount per pixel follows a bell curve: if you plot horizontal displacement on the Y axis against row position within the band on the X axis, you want a smooth peak in the middle and zero at both edges. The function that gives you that shape from a 0-to-1 input is sin(t * π) — it starts at zero, peaks at one halfway through, and returns to zero at the other end. That is the entire bell curve, one line.

Getting t requires knowing where in the band the current pixel sits. I track the band's position using frac(elapsed / cycleDuration) which gives a 0-to-1 value that resets each cycle — that is the band's Y position traveling down the sprite. The pixel's normalized position within the band is then (uv.y - bandPos) / maxShiftBand, which is 0 at the band's top edge and 1 at the bottom. Pixels outside the band have t outside [0, 1], and a pair of step() calls multiplied together masks those to zero.

The final displacement is sin(t * π) * band * maxShift, added to uv.x before any sampling. Since it goes first in the pipeline, the chromatic aberration, scanlines, and flicker all apply on top of the already-distorted image — which is exactly what you want, because it means the aberration fringing follows the stretched pixels rather than fighting against them.

One thing worth noting: I work in microservices professionally and almost never touch trigonometry in my day job. Going from step() thresholds to bell curves built from sin() is a different mode of thinking entirely — you are not writing logic, you are describing shapes. The shockwave taught me to think in distances. This shader taught me to think in curves. I expect that shift in perspective will keep paying off.

After all of this was working, I realized the shader was doing something I had not originally planned for: it was communicating rarity through signal behavior, not just color. A rare drop uses the sin(t * π) bell curve for its horizontal stretch — the distortion is periodic, predictable, rhythmic. It glitches in an expected way. A magic drop uses a different function altogether: 2 * sin(10.5x) * cos(3.2x), the product of two frequencies that share no common period. The wave never quite repeats. The pixels shift erratically, settle briefly, then jitter off in a different direction.

I did not set out to encode rarity into the math. I picked the chaotic function because I wanted magic items to feel visually distinct from rare ones, and "more erratic" seemed right. But once I had both shaders running side by side, it was obvious they were saying something: a rare item has a stable signal. A magic item has a noisy one. The distortion behavior tells you something about quality before you have read the color tint or the tooltip — the same way a strong radio signal feels different from a weak one even when you cannot yet make out the words. That turned out to be exactly the kind of detail I want baked into the game's visual language.

    

Shotgun vs Pistol

One challenge for me as a new game dev is giving unique identity for weapons. In this scenario, I need to make sure the choice between each pistol type and shotgun type is meaningful. The difference between pistol and shotgun itself is easy, these are classic video game weapon types since the dawn of time and we don't need to debate further about their respective specialization in range and accuracy. The challenge here is if I have different pistol or shotgun base types, how do I design meaningful choices between them to adhere to different preferences?

The answer came from a constraint I had not thought much about: CircuitMind is direction-locked. The player faces left or right, and weapons fire in that direction. There is no vertical aim. This means accuracy alone cannot separate two pistols — both would fire along the same horizontal line, and the only difference would be a number. That felt like a non-choice.

So I started thinking about two separate questions. First, how reliably does a weapon fire along the ideal horizontal — the line directly in front of the player at weapon height? Second, how tightly clustered are the shots around that center? If you have a background in machine learning, you will recognize these as bias and variance. A high bias weapon consistently pulls toward the target line. A high precision weapon clusters shots tightly relative to each other. A shotgun is high bias, low precision: it always fires centered on the horizontal, but pellets fan out widely. A pistol is high precision, low bias: shots group tightly, but the center of that group has a small systematic drift from the horizontal.

What I like about this framing is that the range bands fall out naturally. The shotgun is reliable at close range because the wide spread covers anything in front of you regardless of exact positioning. The pistol rewards positioning — at medium range, the tight cluster hits consistently if you are at the right height relative to the enemy. At long range, there is an interesting interaction I did not expect when I started: because the pistol's drift is small and consistent rather than random, a jump attack repositions your weapon pivot and can realign the cluster with the enemy. Jumping becomes a combat skill for pistol users at distance, not just a traversal tool.

The projectile system is not built yet — these stats are defined in the data and flow through the pipeline, but the actual shooting logic comes when I build the ranged skill. Still, I have found it worth locking down the design before writing the code. When I know exactly why a weapon behaves a certain way, the implementation decisions are a lot less ambiguous. Here is my ugly attempt at drawing guns.

Affixes

This sprint I got 58 affixes wired into the game. You can now drop a piece of gear, read its affixes, and make a decision about whether it moves your build forward. That feedback loop — find item, evaluate, equip, feel the difference — is the core of the game, and it is finally running end to end.

The affix system in CircuitMind is built around a provider and processor model. Chips are providers: they supply flat values and tags, things like raw thermal damage or the Dash tag. Chassis pieces are processors: they carry affixes that amplify chips by tag. An Incendiary affix on a chest piece gives between 10% and 20% bonus effectiveness to every Thermal chip you have slotted. It does not care which specific chips they are — as long as the tag matches, the bonus applies. This keeps individual affixes simple to read while letting combinations grow in complexity naturally.

Some affixes trigger on combat events rather than sitting passively. Blood-Fuel Converter is a chip that heals 3% of your maximum HP on every kill. It does not sound like much in isolation, but in a room of fodder enemies it turns aggression into sustain. You are rewarded for staying in the fight rather than backing off. That felt right for the tone of the game.

The weapon affix I have been testing the most is Terminating, which executes enemies below 5% HP. Paired with Berserker's — which adds 1% bonus damage for every 1% of HP you are missing — the two affixes start pulling in the same direction in a way I did not explicitly plan. Berserker's rewards you for absorbing damage. Terminating rewards you for finishing fights before you absorb more. There is a tension between them that only resolves if you play aggressively enough to keep both active at once.

The interaction I find most interesting right now involves System Overrides, which are a separate category of affix that sit on chassis pieces and carry a permanent cost. Volatile Core reserves 20% of your maximum HP in exchange for a significant amplification to Potency-family affixes. You are running at 80% health for the entire run. That is the price.

What I did not anticipate when I equipped Volatile Core alongside Berserker's is that the reservation feeds the damage bonus. Volatile Core takes 20% of your HP away before the first fight, which means Berserker's is already active from the moment you spawn. You never have to get hit to prime it. The System Override is doing two things at once: paying for the Potency amplification, and silently activating a damage bonus as a side effect. That is exactly the kind of interaction the system is supposed to produce, and seeing it emerge from two components that were designed independently makes me feel like the underlying architecture is pointed in the right direction.

There are still around 130 affixes that exist in data but are not yet wired to game logic. Most of them depend on systems that are not built yet — projectile geometry, minion AI, cooldown tracking. They will get there. For now, 58 affixes that actually do something in combat is enough to start making real build decisions, and that was the threshold I needed to cross before moving on.

Again there is putting everything together in a video 



Shout-out to the extremely talented and skilled artist Olha Holonko. She is a professional 2D Game Artist & UI/UX Designer with almost a decade of experience, and I think she did a great job on the inventory UI design.

Thanks again for following along on this journey!

thanks for the interest! It means a lot to me. I only just recently started doing some community outreach (registering social media account, creating a private discord server and all that) so this part is also exciting new territory to me lol.

Pasting a copy of my dev log from my project here https://baronvonzoomie.itch.io/circuitmind/devlog/1528195/dev-diary-3-simple-com...

Dev Diary #3: Closing the Loop — The Combat Foundation

Introduction

This sprint we focused heavily on the core combat feel of the game. It is the foundation of everything combat related that we will implement later on, this include affix system, chassis system, socketing and skill. It is critical that we get this right so that we have a good base combat that player can rely on while they are looking for a good loot.

Binary Flash

The first thing I worked on was getting the player's attack to feel good. The skill is called **Binary Flash** — a two-hit melee combo, the Operative's primary damage tool.

The damage is split 40% on the first hit and 60% on the second. This was a deliberate choice from looking at reference games — a combo that rewards committing to the full sequence rather than hitting once and retreating. You get more out of it if you see it through.

Under the hood, each swing has an active window defined in the animation data itself. When the animator marks a frame as the attack frame, the engine reads it and fires the hit logic at that exact moment. This means the artist controls when the damage happens, not the programmer hardcoding frame numbers. If a swing feels too early or too late, you fix it in the animation file, not the code.



Contact Stasis

As an engineer newly turned game dev, it is a little difficult to convey the feel of a good combat to the player. We know the feeling of holding a sword, and we know the feeling of striking something with the sword, and that is because our senses directly connects with the instrument. As engineers, we don't reinvent the wheel, we look for references, and we look for the right problems to solve. In this case, the problem is, how do we convey the impact of a sword swing hitting something when holding a controller? Luckily this is a solved problem in the game industry, as there are many games such as Devil May Cry 5 and Breath of the Wild that have excellent combat and can serve as reference material. The common factor I found in those games is that when the hits land, the player and the enemy will freeze for few frames, and that is one of the magical ingredient in conveying the weight behind a hit.

In CircuitMind, both the player and the enemy pause for 0.12 seconds when Binary Flash connects. This value comes from our config file so it can be tuned without touching code. It's also limited to melee only — our Arc Blast ranged skill fires continuously, and applying this pause on every tick there would make it unplayable.

Knockback

The other piece of the hit response is knockback — the scout gets pushed back when it takes a hit. This sounds simple but had a tricky engineering problem behind it.

The scout's movement is controlled by a state machine that runs every frame. My first instinct was to add the knockback force directly to the enemy's velocity. But the state machine would overwrite that velocity on the very next frame — the enemy would visually not move at all.

The fix was to add a dedicated knockback method to our motor system. When a hit lands, the motor locks out the AI's movement control for the duration of the stagger. The AI literally cannot override its own stagger while the timer is running. Ground friction then decelerates it naturally so it doesn't slide indefinitely. The force and duration both come from `skills.json`, so dialing it in is just editing a number.

The Scout: The Other Side of the Fight

Building a combat system in isolation is one thing. But for it to feel like a real fight, the enemy also has to threaten the player — not just absorb damage.

The Scout is our first ranged enemy. It doesn't wake up when the player enters the room — it patrols, dormant. When you get close enough, it enters an alert state, then broadcasts a signal to nearby scouts. Those wake up too. Your first engagement can escalate into a multi-enemy situation very quickly if you're not paying attention.

I found this pattern in a lot of games I admire — enemies that communicate, that don't just react individually. It makes the world feel like it's actually coordinating against you rather than waiting in line.

Once in range, the scout fires a projectile. The muzzle flash and bullet both spawn from the gun itself — there's an anchor point on the attack animation that tells the engine exactly where the barrel is on that frame. Small detail, but it reads much more clearly than spawning everything from the enemy's center.

When the projectile hits the player, it drains poise. If poise drops to zero, the player's hurt animation triggers. That closes the loop — the player is now the one reacting instead of the enemy.

Audio

Two sound effects anchor the combat feel this sprint.

The sword swoosh fires on each swing's active frame — the same frame that triggers the hit logic. I originally had it playing when the skill executes, which meant the sound played before the blade even moved. Tying it to the active frame made it feel immediate and physical.

The hit sound fires when damage lands. To avoid the same sound repeating identically every hit, we apply a small random pitch shift each time. The range is narrow enough that it doesn't sound strange, but wide enough that repeated hits feel like separate events rather than a loop.

Both sit inside the vertical audio layering system from Dev Diary #2. When combat starts, the action layer comes to full volume and the calmer layers pull back.

The Full Loop



What's Next

With the combat foundation in place, the next two things on the list are the Inventory UI and Skill Ranks.

The loot system already generates items when enemies die — but there's no screen to put them in yet. That showcase is saved for when the inventory UI is ready, because seeing an item land in a slot is the actual payoff, not just the drop.

Binary Flash also currently runs at Rank 1. Rank 2 unlocks attack-to-dash and dash-to-attack canceling, which opens up a much richer combat expression. That's waiting on the rank system to be built first.

Thanks for following along.

— BaronVonZoomie

hey there, my discord is same as my user name here, baronvonzoomie

(1 edit)

posting a copy of the dev blog here to keep this thread updated. Follow the project here! https://baronvonzoomie.itch.io/circuitmind


Dev Diary #2: Kinetic Logic & Harmonic Flow

Hello again! BaronVonZoomie here. In my first update, I talked about the high-level vision for CircuitMind —the world of El Velo, the "Chassis & Chips" itemization, and the shift from stamina to Neural Flow.

This week, I am sharing the development process on player movement and dynamic bgm layering, the harmonic flow.

Kinetic Logic, the Math of "Feel"

1. The Geometry of Gating: 31 vs. 32

In a Metroidvania, movement is key to player's enjoyment of the game. To implement proper "Slide Gates" without a dedicated "crouch" button cluttering the controls, I had to change our collision bounds around.

The Stand: Our protagonist's standing height is 40px. The Gate: Our world is built on a 32px grid. The Dash: When you trigger a dash, I dynamically shrink the collider to 31px.

That 1-pixel difference means you physically cannot walk through a 1-tile gap, but the moment you dash, the math clears. It’s a "low-profile" mode that turns the environment into a series of locks and keys.

2. Tunnel Safety & Forced Continuity (The "Auto-Glide")

One of the first logical hurdles I hit was the "Stuck in a Tunnel" problem. If your dash timer ends while you are still inside a 32px gap, the physics engine normally tries to revert to your standing height, which would cause you to clip into the ceiling or get stuck in a state-loop.

I implemented an industry-standard solution which is Forced Continuity. Before exiting the dash state, the engine calls a `CheckClearance(40f)` utility. If there’s a solid tile above your head, the engine refuse to let you stand up. Instead, you will "auto-glide" at dash speed until you hit open air. 

 3. The "Laser Line" Dash

Originally, gravity was always pulling on the player, causing dashes that go off edges to "dip" slightly once in air. This also have the side effect of player unable to dash across gaps and lead to bad player experiences. I’ve moved to a Zero-G Dash model, which means during the dash frames, gravity is zeroed out and vertical velocity is locked. This means if you dash mid-air, you stay on that horizontal plane exactly, allowing for pixel-perfect gap crossing and "air-threading" through hazards.

4. Conservation of Momentum (The Dash-Jump)

Originally, we had a tiny, frame-perfect window right before and after a dash ended where a jump would preserve your momentum. But if you missed that window by even a millisecond, the engine would force you into a static jump windup, effectively "eating" your input and killing your velocity, which is another bad player experience.

It felt like a penalty for being human. To fix this, I updated the state machine to explicitly detect this "Dash-Jump" transition (just like in Megaman X series). Now, we bypass the normal jump windup animation entirely and inherit the full horizontal velocity. The result is a massive, high-speed kinetic arc that rewards you for timing your inputs without the frustration of lost momentum.

5. Platform Threading

Dropping through one-way platforms is a friction point in many games where the player can feel "sticky." To solve this, "Down + Jump" now triggers two specific logical shifts:

1.  A 150f downward nudge is applied instantly to the velocity.

2.  The physics engine enters a 0.2s platform-ignore window.

That initial nudge is the "secret sauce." It ensures the collider is physically overlapping the platform boundary on the very next frame, letting gravity take over without the player "stuttering" on the top pixel of the tile.

Data-Driven Tuning: The combat.json Suite

Finally, I’ve moved all these variables—Jump Force, Dash Speed, Apex Gravity—into a dedicated combat.json configuration. As an engineer, I hate hardcoding magic numbers. Now, I can tweak the "gravity of the world" or the "snap of a dash" in real-time while the game is running, allowing for immediate feedback and iterative polish. In addition, I am also entertaining the idea of providing this file to the player in the final v1.0 release, so that players can tune the game to their own preferences.

---

Harmonic Flow: The Code Behind "Combat as Jazz"

 We are moving away from static background tracks toward a systemic model I call "Harmonic Flow." The goal is simple but ambitious: to transform every combat encounter into a procedural jazz-fusion performance where the player acts as the conductor.

1. The Stem Stack

Our current architecture uses Vertical Layering—a stack of perfectly synchronized audio files (stems) running in parallel.

To prevent "music thrashing," we implemented a Tension Linger system. When you lose aggro, the music doesn't abruptly cut; it "lingers" for 4 seconds, allowing the "Cool Noir" atmosphere to melt back into the city hum naturally.

2. The Lick System: SFX as Performance

In El Velo, sound effects aren't just feedback—they are musical "licks." We are building a library where every action follows our "Chrome & Brass" palette (Flesh vs. Tech).

For example, Dashing triggers a "chk-chk" guitar scratch, and landing a critical hit fires a sharp Brass Stab, and by tuning every impact to the Scale of the BGM, we ensure that your attacks never clash with the music. Instead, they feel like improvised solos layered over the arrangement.

3. The Vision: Enemy as Instrument

Our ultimate goal for the vertical slice is the "Enemy as Instrument" logic. We want to tie specific instrument samples to different enemy archetypes:

- Hitting a Security Guard contributes an Upright Bass pluck.

- Destroying a Drone triggers a Trumpet blast.

- Engaging a Heavy Mech brings in the Baritone Sax and low piano bottom-end.

Through Sidechain Compression, the system is designed to "duck" the background music the moment you land a hit, creating the acoustic space for your "solo" to cut through the corporate noise. You aren't just fighting the city; you are performing its downfall.

---

The Showcase Level: Putting it All Together

To wrap up this update, I’ve recorded a video of our new Showcase Gauntlet. This level was designed specifically showcase the finer details of a character's movement in a 2D game, such as coyote time, corner correction and frame canceling etc.

CircuitMind - Character movement showcase, initial iteration

This video will show case dynamic BGM layering. At first the base layer will play, then we move into enemy sight range, and that would trigger the tension layer. We then move out of the detection range and the base layer will play again and tension layer will fade out. Finally, we stay within enemy range long enough to trigger the chase, and also triggering the action layer.

CircuitMind - Dynamic audio layer showcase

---

Roadmap & Next Steps

With the movement physics and audio foundation locked in, my next focus is build up the foundation for a robust inventory system, where player can swap out gears and the cybernetic chips on their equipment.  

Thanks for joining me on this journey.

— BaronVonZoomie

Thanks! I will definite keep you in the back of my mind! There are a lot of art assets need to be created. My discord is BaronVonZoomie


Introduction: Who am I?

Hello everyone! I'm BaronVonZoomie. After a decade-long career as a senior software engineer, I finally decided to take the leap into my true passion: game development.

I grew up on a steady diet of Heroes of Might and Magic 3 and Diablo—games that didn't just give you a hero, but a math-heavy world to optimize. That lifelong love for the deep dive of Metroidvanias and the addictive "one more run" loop of looter ARPGs is exactly why I’m building CircuitMind.

What is CircuitMind?

At its simplest, CircuitMind is a high-octane action-RPG set in a sprawling cyberpunk dystopia. It’s my attempt to fuse the atmospheric, handcrafted exploration of a Metroidvania with the deep, loot-driven progression of a Diablo-style game.

But beyond the genre labels, I’m building this because I wanted a game that empowers the player to "engineer" their own character. In CircuitMind, you aren't just picking a class; you’re programming a machine.

Welcome to El Velo

The story of CircuitMind takes place in El Velo, a sprawling, futuristic city built on stark contrasts. It’s a place where rain-slicked, neon-drenched lower sectors crawl with desperate mercenaries, while gleaming corporate spires pierce the toxic clouds above.

In El Velo, the figurehead government is long gone. The real power lies with the omnipresent Conglomerates. Following a catastrophic event known as The Great Disconnect, these corporations seized control of all R&D and private security, turning technology into a tool for surveillance and suppression.

You step into this world as a nobody mercenary who has been framed for the murder of a high-ranking corporate official. You aren't just fighting to survive; you're following a trail of digital breadcrumbs to prove your innocence in a city that wants you deleted.

Beyond the Chrome: The Endgame

I didn't want the journey in El Velo to end just because you reached the final biome. I’m designing two distinct ways to push your build—and your mind—to the limit.

1. The Endless Ascent

For those who want to test their "Hardware," we have the Endless Ascent. It’s a procedurally generated gauntlet that forces you to adapt to new combinations of enemies and hazards. It’s the ultimate playground for your Memory Allocations and Overload skills.

2. The Conglomerate Conspiracy

This is the part I’m most excited about. CircuitMind isn't just about combat; it's about uncovering the truth. In the Conglomerate Conspiracy, you'll engage in a deep, deductive endgame where you must piece together digital evidence to solve the murder you were framed for. Think of it as a "Cyber-Detective" mode, where your ability to find clues is just as important as your ability to swing a sword.

The "Chassis & Chips" Philosophy*

One of the first things I wanted to fix was how mindless itemization can feel in some ARPGs. In most games, you just jam the highest-level gem into a hole and forget about it.

I’m building something different: a Socket Puzzle. Gear is split into two parts: the Chassis (your physical equipment) and the Chips (the "brain" of your build). By using conditional affixes, we’re making every decision meaningful. You might find a chip that grants an extra Dash Charge, but only if it's installed in "Vector" brand gear. Or maybe a chip gives +5 Reflex, but only if it’s sandwiched between two "Synapse" modules. Your inventory becomes a place for tactical engineering, not just random clicking.

Breaking the Mold: Neural Flow vs. Stamina

As I spent the last few weeks tuning the physics and "game feel," I hit a wall with traditional resource management. Originally, I had a stamina bar, but it felt clunky. In a fast-paced cyberpunk world, your character shouldn't get "tired" from swinging a sword or dodging.

So, I performed some "logic surgery" and moved to Neural Flow. We’ve removed the stamina bar entirely. Instead, your character uses a Charge-based Dash system. Each move has a rhythm, an internal cooldown that scales with your stats. This lets you focus on the combat jazz—dashing, striking, and recovering in a seamless loop—without constantly glancing at a blue bar.

Character Progression: Memory Allocation

In El Velo, power isn't granted through traditional experience points. Instead, you earn Credits—the lifeblood of the city’s economy.

I’ve always been a fan of the high-stakes economy in *Dark Souls*, where your currency and your growth are one and the same. To me, this is a well-established and incredibly effective system—there’s no need to fix what isn't broken. So, I’m bringing that same tension to CircuitMind. You use your hard-earned cash to purchase Memory Slot Expansions (up to a hard cap of 70). Just like any high-end tech, the more memory you add to your system, the more expensive the next expansion becomes. This creates a permanent, strategic tension: Do you buy a powerful new weapon, or do you invest in a Memory Slot to allocate toward your Hardware (Stats) or install new Software (Skills)?

The real "Ah-Ha!" moment is our Overload system. If you allocate enough memory into a base stat (like 30 Reflex), your skills will literally break through their normal limits, unlocking hidden behaviors like explosive decoys or CD resets. It’s all about reaching those high-level thresholds to see what your build is truly capable of.

The Foundation: Tiled & Pixel-Perfection

On the technical side, I’ve spent the last week ensuring the world of El Velo is as solid as its mechanics. We’ve moved to a high-performance, tile-based system using the Tiled Map Editor.

This isn't just about drawing levels visually; it’s about precision. We’ve implemented pixel-perfect physics and two-pass axis resolution. When you land on a platform in CircuitMind, you land exactly on the top pixel of that art. No flickering, no "sinking" into the floor. It’s that tight, *Castlevania*-style movement that makes a Metroidvania feel right.

 Visual Identity: From Greybox to Neon

As an engineer, my first priority was always the "feel"—getting the gravity, the two-pass collision, and the hitboxes right. But a world like El Velo deserves to look as sharp as it plays.

My journey started with what I like to call Programmer Art—functional greyboxes that served their purpose during the first weeks of coding. To move beyond the blocks, I worked closely with talented artists to establish our visual soul. They created an initial moodboard to capture the rainy, high-contrast atmosphere I was aiming for, and through a process of feedback and refinement, we’ve arrived at a vision that perfectly matches the dark, neon-drenched world of El Velo.



This is the initial programmer art. It's really rough around the edges, however these place holders allow me to quickly build up the custom physic engine and test the collision, hit boxes and affixes implementation.

---------------------------------------------------------------------------------------------------------

@knight.1e (Instagram) and killakhi (Discord) did a fantastic job aligning the moodboard to my vision, providing a strong foundation for future art asset creation.





--------------------------------------------------------------------------------------------------------- 

The real turning point for the player character was collaborating with the talented @knight.1e. Seeing our protagonist evolve from a simple sketch into a professional, atmospheric design has been incredible. We’ve finalized the Main Character Design, capturing that framed mercenary silhouette perfectly




--------------------------------------------------------------------------------------------------------- 

We are now in the process of translating that design into gameplay. Here is our first look at the Idle Sprite, alongside the Fodder Enemy idle animation spearheaded by killakhi.



Future Plans & Roadmap

The goal for the immediate future is completing a highly polished vertical slice—a definitive proof of concept that showcases the Neural Flow combat and the Socket Puzzle itemization in action.

Current Wins: Pixel-perfect physics, Tiled level integration, and our functional loot/chip engine.

Next Milestone: Launching a Kickstarter campaign to help bring the full project to life, including our planned cap of 70 Memory Slots, the implementation of dual classes (Operative & Netrunner), and sprawling biomes.

I'll be diving deeper into the specific Overload skills for the Operative and Netrunner in the next update, and I'll share more about our unique Combat as Jazz dynamic audio system. Thanks for joining me on this journey!

Call to Action

If this sounds like your kind of game, feel free to reach out to me on Discord (BarronVonZoomie). I’d love to hear your thoughts on the Memory Allocation progression!

Shoutout to @knight.1e and killakhi for their incredible work bringing our hero and enemies to life.

— BaronVonZoomie