A solution to sprite visibility in a raycasting engine with variable wall heights? I am writing a raycasting engine. At this point, I have added sprites, and I am using a z-buffer, with one stored length to a wall for the x coordinate of each ray. Below is an image of a sprite which is fully visible.

Z-buffering works fine when my vertical height is zero, as seen below.

However, when I change my vertical height and stand on top of a wall, as seen below, my sprite becomes only half-visible. I understand why this is true; the Z-buffer is only accounting for the first level of vertical height, and so it seems like the sprite should be partially obscured, even when it is not.  However, there also cases when most of a sprite is obscured except for the top. In that case, I could not simply have a z-buffer for each level of vertical height. Does anyone know of an algorithm that can determine the visible area of a billboard sprite in a raycasting environment?
Congratulations for having progressed so far.
Context, first analysis
Your explanation:

I am using a z-buffer, with one stored length to a wall for the x coordinate of each ray.

Means the z-buffer is currently one-dimension.
One dimension is enough in the first case (your first two images) but not in the second case. To see why, imagine that the red tomato sprite was closer to the player, such that the left half of it would be partially obscured by the first wall (bottom left). Since the top of that wall is projected to a diagonal line, it means that the property &quot;is pixel P of the sprite obscured?&quot; does not only depend on X but also on Y.
So, in the exact setup you have, a 1D Z-buffer is definitely not capable of performing the clipping you want.
Options
From that on, here are a few options:

switch to a 2D z-buffer (slower)
switch to painter's algorithm (slower)
switch to a 2D-based occlusion algorithm
study how Doom did it

Your geometry seems similar to Doom. It is probably a very good investment for you to study how the Doom rendering engine works. It clips sprites (called &quot;things&quot;) using a 1D criterion, then refines. One area has only one floor height and one ceiling height. This is very important and it looks like your geometry is similar.
Solution
The solution, to summarize, is to keep not only a 1D z-buffer, but actually a structure keeping for each sector (in doom parlance) the lines that make the limit and their parameters (like the a and b in y=ax+b).
Then, when you want to draw the sprite, clip X with 1D criterion but depending on the sector the sprite is in, and then limit the Y range of pixels drawn based on the y=ax+b of the sector just in front of it.
I don't know what data structure you currently have in your program. If this seems totally unreachable, then you need to rethink the data structure you keep while drawing.
If you haven't yet, you should read (sorry if you did already) https://doomwiki.org/wiki/Doom_rendering_engine#Rendering and the pages behind the links there, perhaps run their code in slow motion or see a video where someone shows/explains how it works.  This one lacks explanations but might help your intuition: https://www.youtube.com/watch?v=gfM6NpxmVGg .
Hope this helps.  Keep up the good work!