Tumgik
zephagame · 5 months
Text
My game I made in 48 hours came 2nd in Ludum Dare 54!
Ludum Dare 54 is a massive worldwide game development event, and my game, Less is Moore, came 2nd out of over 500 submissions in the most competitive bracket! I made a video about it! I'm a very small creator, so if you'd watch it, that would be great! ❤️❤️❤️
youtube
3 notes · View notes
zephagame · 7 months
Text
How do games load so many textures? - Sparse Bindless Texture Arrays
Hey, long time no see!! ❤️ I've been working on a video about how video games store and use so many textures, and it's finally done! I think it's really good, and I would love it if people would take a look at it. This is like, my first real video on YouTube so I don't think it'll get much organic attention — so if you're willing to give it a watch it would be super appreciated. I promise it's interesting!
youtube
71 notes · View notes
zephagame · 8 months
Note
the Funky Grass (but a bit toned down) would be a great effect for a nightmare sequence or status condition XD gets hit by a curse and the land starts writhing
I absolutely love this idea! It's very reminiscent of Minecraft's Acid Shaders, if you remember them. In my game there are a lot of scenarios in which it would make sense to briefly fuck with the player's vision for effect. I'm definitely going to do this :)
1 note · View note
zephagame · 8 months
Text
The bugs one encounters while developing a voxel game
I've been digging through my old Twitter posts recently, trying to get everything of "value" off of the platform, and I found a bunch of posts with glitched / broken images of my game in it, and I thought, hell, why not? Here's a little gallery of the neatest bugs that I bothered to take pictures of.
Tumblr media
This funky grass happened when I was working on leaf swaying particles. I accidentally applied it to the grass blocks instead of the tall grass, and I had the intensity multiplied by a factor of 10.
Tumblr media
This was... meant to be a wireframe model, to show you what you're pointing at. I don't even know what happened to it here!
Tumblr media
Shaders breaking can sometimes lead to really satisfying results... I believe I accidentally routed texture coordinates directly to the fragment shader output somehow, resulting is this very dreamlike effect.
Tumblr media Tumblr media Tumblr media
Back when I was still storing partial chunks -- chunks containing only structure data that spanned a chunk boundary while generating -- in the regular chunk array, it was possible for the game to mistakenly believe these chunks were complete and render them. These chunks were default-filled with id 0, the invalid block, which only meant to appear when a block from a mod that has been removed is loaded. They were a slightly scary sight, looming over the horizon.
Tumblr media Tumblr media Tumblr media
A while back, when I was working on the GUI system of the game, I added an API to programatically crop and resize textures, which caused a lot of problems and memory corruptions. I'm not a very careful programmer :)
Despite how annoying debugging can be, it can be fun seeing the chaos that bugs can throw at you. I just wish I got more stuff like this and less Segmentation Fault (Core Dumped).
Do check out our Discord server if you want to see more nonsense, or if you'd like to involve yourself with the project. I'd love to say hi!
52 notes · View notes
zephagame · 8 months
Text
Light Propagation Visualization
Hey all! Sorry for the silence for the last few weeks. I'm visiting family right now so I have less time than I'd like to work on this project.
I'm working on a longer form Devlog + accompanying article on Light propagation in Zepha, my Voxel Game Engine, and I thought I'd post a tiny preview here!
This visualization demonstrates the difference between Minecraft's sub-par light propagation algorithm, my own algorithm designed for Zepha, and the theoretical "ideal" spherical propagation algorithm. Hopefully you can see that the Zepha algorithm produces a much more accurate result when compared to the ideal.
The Devlogs I'm working on will go into detail about how this algorithm works (so that you can integrate it into your own projects!), how to make it performant, and how it interacts with colored lighting. I'm hoping I'll have it out in a couple of weeks.
This video is already stacking up to be weeks of work, so I'm really hoping that a lot of people are able to get value from it. If you're interested, please join our Discord or follow this blog to keep up with things! I'll be posting on all of my socials when the video is out.
Thank you so much! ❤️
36 notes · View notes
zephagame · 8 months
Text
The bugs one encounters while developing a voxel game
I've been digging through my old Twitter posts recently, trying to get everything of "value" off of the platform, and I found a bunch of posts with glitched / broken images of my game in it, and I thought, hell, why not? Here's a little gallery of the neatest bugs that I bothered to take pictures of.
Tumblr media
This funky grass happened when I was working on leaf swaying particles. I accidentally applied it to the grass blocks instead of the tall grass, and I had the intensity multiplied by a factor of 10.
Tumblr media
This was... meant to be a wireframe model, to show you what you're pointing at. I don't even know what happened to it here!
Tumblr media
Shaders breaking can sometimes lead to really satisfying results... I believe I accidentally routed texture coordinates directly to the fragment shader output somehow, resulting is this very dreamlike effect.
Tumblr media Tumblr media Tumblr media
Back when I was still storing partial chunks -- chunks containing only structure data that spanned a chunk boundary while generating -- in the regular chunk array, it was possible for the game to mistakenly believe these chunks were complete and render them. These chunks were default-filled with id 0, the invalid block, which only meant to appear when a block from a mod that has been removed is loaded. They were a slightly scary sight, looming over the horizon.
Tumblr media Tumblr media Tumblr media
A while back, when I was working on the GUI system of the game, I added an API to programatically crop and resize textures, which caused a lot of problems and memory corruptions. I'm not a very careful programmer :)
Despite how annoying debugging can be, it can be fun seeing the chaos that bugs can throw at you. I just wish I got more stuff like this and less Segmentation Fault (Core Dumped).
Do check out our Discord server if you want to see more nonsense, or if you'd like to involve yourself with the project. I'd love to say hi!
52 notes · View notes
zephagame · 8 months
Text
Tumblr media
In Zepha, you're not limited to 1x1 blocks. Modders can easily design multiblock structures, custom models, and other cool things to really liven up the game world. This is a model for a basic Crafting Table I created a while back, with the idea of making the eponymous station a bit more prominent in your builds.
Nowadays, I'm not even planning on having a crafting table! Crazy, I know, but I'd like to make a departure from the traditional grid crafting system of Minecraft in my game. Hand crafting will be done by selecting two items in your inventory while holding a special key, which will convert them into their product, if they have a recipe using the two of them, and more complex crafting will all be done with specialized machinery, no 3x3 grids in sight. I'm hoping that this system will provide more uniqueness to the crafting system, as I feel that 10 years of Minecraft has made the crafting grid just a little bit stale.
Do you like the Minecraft 3x3 crafting system, or are you also feeling burnt out from it?
We have a Discord Server ✨
29 notes · View notes
zephagame · 8 months
Text
Check out these waving lilacs in my voxel engine, Zepha!
In the engine, all game content (blocks, entities, etc) is defined by sandboxed mods. The block model system allows you to specify random model offsets, textures, rotations, and apply shader-features like spinning and wind-swaying. These flowers were scripted using this API!
We have a Discord Server ✨
14 notes · View notes
zephagame · 8 months
Text
In Zepha, colored lighting allows you to create pretty ominous scenes. The lighting algorithm has been a focus of mine for the last several weeks, and I have a much more detailed write-up for it here:
We have a Discord Server ✨
13 notes · View notes
zephagame · 8 months
Text
I made this really smooth transition for breaking blocks a while ago! I really like little interactions like this in video games, and I'm excited to cram as many as I can into Zepha. I haven't yet decided what I'll do if a block doesn't drop itself, or drops an item. I could probably have the block shrink down to nothing, and have the actual item drop grow out of its position, so that it kinda just transitions between the two entities.
What are your favorite small interactions like this in video games? Let me know what things you think I should do to make this game feel extra smooth™
21 notes · View notes
zephagame · 8 months
Text
Incredible writeup! I really appreciate someone dissecting this topic, as it's been something I've struggled with for a while :) I'll definitely be using this knowledge in my own projects.
Framerate (In)dependance and Simulation Stability
In this article we’ll go into:
Framerate dependence/independence
How it relates to simulation (particularly physics) in games
And methods to achieve framerate independence and overall simulation stability
Framerate dependence means a game’s simulation plays out differently depending on the games framerate.
We’ll start with a simple update loop to illustrate framerate dependence:
// framerate dependent updateLoop() { pos += 10; draw(); }
A game with this update loop is framerate dependent. If the game runs at 100fps, after one second, the pos is changed 1000, if it runs at 1fps, the pos is changed 10. Different framerate, different simulation.
We can fix this problem by calculating and using the time between frames (dt) to compute our update.
// framerate independent updateLoop() { dt = CalcDt() pos += 10 * dt; draw(); }
This game is framerate independent. If the game runs at 100fps, dt is 10ms and in one second the player moves 1000. If the game runs at 1 fps, dt is 1000ms and in one second the player moves 1000.
// framerate dependent updateLoop() { dt = CalcDt() accel = 2 vel += accel * dt; pos += vel * dt; draw(); }
But if we do something more complicated in our simulation, like in this example where we have something constantly accelerating, we reintroduce frame rate dependence.
Framerate 100fps: dt = 10 (100times) pos change after 1 sec ~= 1,000,000
Framerate 1fps: dt = 1000 (1time) pos change after 1 sec = 2,000,000 (assuming vel starts at 0)
// framerate independent updateLoop() { dt = CalcDt() accel = 2; pos += 2 * pos - prevPos + accel * dt * dt; prevPos = pos draw(); }
This is Verlet integration, and it has the nice property that when acceleration is constant, this is framerate independent. Many games work well with this integration method because the majority of game logic can be expressed as simple states of acceleration - player is falling => accel = -G, player is pressing fwd on the stick => accel = vecFwd, and clamp velocity at MAX_SPEED. In all but the few state transitions is the player at constant acceleration.
// framerate dependent updateLoop() { dt = CalcDt() accel = k * pos; // a spring force pos += 2 * pos - prevPos + accel * dt * dt; prevPos = pos draw(); }
But if we have more complicated physics models, like this spring example where acceleration is based on a continuous variable like position, we become framerate dependent again.
By using more advanced integration methods we can lessen or error. In the same way a regular polygon with 40 sides is closer to a circle than a polygon with 10 sides, a game that does 40 smaller steps is closer than a game that does 10 larger ones.
// 'less' framerate dependent updateLoop() { bigDt = CalcDt() dt = bigDt/4; for(int = 0; i < 4; ++i) { accel = k * (pos - restPos); vec += accel * dt; pos += pos * dt; } draw(); }
This method simply does 4 smaller Euler time steps. This is more accurate than a single long step, but we have a systematic problem - it’s kinda ‘laggy’. If something is acceleration, we’ll always be a little slower than we should. If something is decelerating, we won’t stop quite fast enough. So why not do 8 steps? Sure, why not, though each time you increase the number of steps you are spending performance to calculate those steps. Sometimes it’s worth it, sometimes you can’t afford it.
Turns out there are some techniques to get 'extra’ value out of each or our substeps if we do our math wisely.
// even more 'less' framerate dependent updateLoop() { dt = CalcDt() dpos[0] = f(t, pos); dpos[1] = f(t+dt/2, pos + .5 * dt * dpos[0]); dpos[2] = f(t+dt/2, pos + .5 * dt * dpos[1]); dpos[3] = f(t+dt, pos + dt * dpos[2]); pos += dt/6 * (dpos[0] + 2*dpos[1] + 2*dpos[2] + dpos[3]); draw(); }
This is Runga-Kutta 4. Note, it’s pretty close to the our previous method. The main improvement is by making better guesses, and doing better at averaging them together we can avoid much of the systematic error of Euler integration. The main challenge is we need to phrase the equation of motion for our system in terms of velocity = f(time, position). Often this is much more challenging. Moreover, while 'less’ frame dependent than our previous incarnation, it’s not that much less, so often the complexity is not worth the trouble.
// framerate independent, timestep dependent updateLoop() { dt = CalcDt() game.dtAccumulator += dt; while(dtAccumulator < timestep) { dtAccumulator -= timestep accel = k * (pos - restPos); vel += accel * timestep; pos += vel * timestep; } draw(); }
This is a fixed timestep method. This eliminates variance of the simulation based on time completely, for any equation of motion you can come up with.
IMPORTANT NOTE: This does not mean the physics won’t blow up. It means it won’t act any differently based on your frame rate. It can still act differently based on your choice of timestep. And it will be 'incorrect’ relative to an analytic solution for all but the simplest equations of motion. 'Extreme’ conditions can still lead to unstable behavior.
// framerate independent, 'less' timestep dependent updateLoop() { dt = CalcDt() game.dtAccumulator += dt; while(dtAccumulator < timestep) { dtAccumulator -= timestep dpos[0] = f(t, pos); dpos[1] = f(t+timestep/2, pos + .5 * timestep * dpos[0]); dpos[2] = f(t+timestep/2, pos + .5 * timestep * dpos[1]); dpos[3] = f(t+timestep, pos + timestep * dpos[2]); pos += timestep/6 * (dpos[0] + 2*dpos[1] + 2*dpos[2] + dpos[3]); } draw(); }
Here we merge our fixed timestep and advanced integration techniques together, to try and get the best of everything. Now we have frame rate independence and 'less’ timestep dependence. But we’re still not perfect.
High end physics research is often concerned with improving on this dilemma, maybe for a specific subset of physics (like cloth, fluids or whatever), maybe for specific simulation states (high velocity, equilibrium), or maybe for alternate computation models (vectorized, gpu).
Some other techniques to achieve more stability beyond the scope of this article:
Simplifying your equations of motion
Analytically solving all or parts of your equations of motion.
Implicit integration techniques
Hopefully this has helped illustrate some of the issues in game simulation with regard to framerate dependence, fixed timesteps and different integration techniques. As you’ve probably realized, there’s no single answer. All sorts of games (from hobby to AAA) use all sorts of the combinations of the techniques above, and others. What techniques you should use for your game unfortunately comes down to 'it depends on your game’
Thanks for reading, and if you have any comments or corrections let me know @greysphere!
10 notes · View notes
zephagame · 9 months
Text
Working on a video script that goes over the lighting algorithm I showed here in detail! I'm hoping I can make something cool for people to watch :)
7 notes · View notes
zephagame · 9 months
Text
Introducing Zepha
Hi, I'm Auri and I'm reinventing the wheel making a voxel game / engine. Recently I've managed to scrape together a really cool RGB voxel lighting algorithm so I'm going to make a post about it!
Tumblr media Tumblr media
One thing that was really important to me when designing my game's lighting was that I wanted the static lighting to fit in with more fancy graphical effects. That means that Minecraft's lackluster diamond-shaped lighting wasn't going to cut it. I wanted spherical light and I wanted colors!
Tumblr media Tumblr media
To accomplish this, I split the lighting into 6 channels. RGB for block light, and RGB for sky light. (technically there's 9 channels but that's too complicated to get into right now). I also store the direction that light comes from so that I can build a pseudo-sphere of light around the source.
Tumblr media Tumblr media
To make things performant, I had to delve deep into micro-optimizations like Word Level Parallelism, which is a technique to do the same operation on multiple numbers packed into a single integer. The algorithm supports a huge dynamic range for colors and brightnesses, and operates in real time.
Tumblr media Tumblr media
Any color can be used, and bright lights even overexpose. Lights can span chunks in radius!
If you're interested in the project, and want to see more, please join my Discord! I do weekly livestreams and I post updates often! Thanks for your interest ❤️❤️❤️
aurail.us/discord.html
107 notes · View notes
zephagame · 9 months
Text
I know you're joking, but I actually did go through that midlife crisis a year and a half ago about this. It was incredibly tempting to shift the whole project to rust when I was in the worst of my implementation struggles. But I decided unfortunately it wasn't worth it, the codebase has around 70,000 LOC and that number is increasing all the time, rewriting it would be a 2 year detour at least.
I think it worked out though, things are progressing rapidly and I've learned a lot of tricks for hyper-optimizing C++ code. I'm going to be writing a more in-depth post soon about the lighting system and how it works, as I use a lot of techniques I didn't even know existed, like Word Level Parallelism. I have an overview of it here, if you're interested:
127 notes · View notes
zephagame · 9 months
Text
Thank you!! If you're interested in how the lighting algorithm works, I have a longer post about it here:
127 notes · View notes
zephagame · 9 months
Text
127 notes · View notes
zephagame · 9 months
Text
1,000 Rabbits
6 notes · View notes