Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411522 Posts in 69377 Topics- by 58431 Members - Latest Member: Bohdan_Zoshchenko

April 28, 2024, 08:59:47 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsBarbearian - Fast-paced hack'n'slash action in a colorful hand-drawn world
Pages: 1 ... 6 7 [8] 9 10 ... 13
Print
Author Topic: Barbearian - Fast-paced hack'n'slash action in a colorful hand-drawn world  (Read 45696 times)
io3 creations
Level 10
*****



View Profile WWW
« Reply #140 on: October 25, 2017, 09:52:26 AM »

Hello there, a fantastic work here.

I'd like to ask some questions if you have time for them Smiley

Seamless beauty between ground and grass is amazing. How did you achieve that, are they rendered together ?
I mean it seems grass is effected by the terrain's shading (or diffuse lighting) and color.

And about grass , Are you baking them into one mesh to save some CPU overhead or are they individual sprites ?

Thanks!

Sure, I have time. Smiley The grass samples the same texture that the terrain uses to render itself to get the color, so they always match. (It contains the lights etc. too.) Also, I keep the grass on fairly single colored tiles only, as it will look awful if the grass starts spanning over large color changes rapidly, or like going on the sand / rock tiles etc. The grass itself is a bunch of individual wide sprites, as I need to sort them with all the other sprites to get the units etc. into the grass.

Is that clear enough? I could maybe write a more in-depth post about the lighting if there's any interest?
I'd be interested in an in-depth post because I'm not exactly clear what you mean.  I just skimmed a few pages and saw that you are using your custom 2d engine.  So, that means the grass sprite images have already been created and you are placing and updating the ones you want.  To get the nice smooth waving motion, the next sprites is used in the grass movement animation.  Or do you use some kind of skewing technique (e.g. texture uv or vertex moving in 3d) to move them because the trees seem like as if only a single sprite is used and then that sprite is manipulated.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #141 on: October 25, 2017, 09:16:17 PM »

I'd be interested in an in-depth post because I'm not exactly clear what you mean.  I just skimmed a few pages and saw that you are using your custom 2d engine.  So, that means the grass sprite images have already been created and you are placing and updating the ones you want.  To get the nice smooth waving motion, the next sprites is used in the grass movement animation.  Or do you use some kind of skewing technique (e.g. texture uv or vertex moving in 3d) to move them because the trees seem like as if only a single sprite is used and then that sprite is manipulated.

Sorry, I'm not 100% sure what you mean, but yeah the waving motion comes from moving the top vertices in the vertex shader. And the vertex shader gets it's "seed" from the world location in 2D (top down), so if there's two grass sprites right next to each other with their sides at the same spot, they will get the same wind offset too so there's no gaps even though they're separate sprites.

And sure, I'll try write to make a separate lenghtier post about the rendering pipeline when I have the time!
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #142 on: October 26, 2017, 10:49:42 PM »

Log Entry #43

Slow week, didn't get as much done as I would have liked. Finished the fire spider. Did about half of the levels to world 3 and tried to iterate the fire gameplay into shape. It's ok now, but I was kind of over optimistic about how much freshness it would bring to the levels and gameplay. Then I did this mummy ninja enemy, which I just finished. It's a new captain type that has got a few new gameplay tricks too.

Next week. I'll have to bring more elements to world 3 to make it more interesting. I have an idea for at least one enemy building and I should probably do a new tougher "normal" small enemy melee unit too. Then draw some more decoration elements that are specific to the world 3 deserty theme. Let's see how far I get. One thing is now clear though, that once I finish World 3 I need to spend time getting the game progression design in much better shape, as in how exactly the player gets new powers etc. and how the minion and enemy health/damage are balanced, now it's not working that well anymore as the game progresses into world 3.
Logged

NowSayPillow
Level 1
*


John Carmack Clone


View Profile WWW
« Reply #143 on: October 27, 2017, 03:37:30 AM »

Game looks hilarious, chaotic and adorable. Looking forward to trying it someday.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #144 on: October 28, 2017, 01:51:18 AM »

Rendering Overview

The focus of the rendering has been to make it all run well on older iOS devices (minimum target PowerVR SGX543, an old OpenGL ES 2 chip). I was originally meant to release this game about a year back already, so the target is already quite obsolete. If I would start things now, I would naturally do many things differently (and target higher perf devices anyway), but such is life! Smiley

I'm not a rendering expert and this is not meant as any kind of ideal way to do things, this is just the way things ended up as I made it up as I went. This is also a high level overview, if there's something interesting here and you want me to go into more detail on something, just let me know!

The .gifs are a poorly compressed, the smearing etc. and low color fidelity is not something that's really there...

Layers

Off screen render targets

First I render all off screen render targets, all of these are top down view of the level.

1. Level tilemap color

The multiple tile layers of the entire level from Tiled are cached into one offscreen target. This is only updated when needed, like when first coming into view or when tiles are changed dynamically during gameplay (like adding some damaged terrain on top or something like that).



2. Ambient shadows

One channel target (low resolution on some devices) where I render ambient shadow sprites for all entities that have
one and are in view.



3. Point light shadow maps

All point lights that have shadows enabled render a 1D shadow map of their occluders into one horizontal line in the point light shadow map texture.



4. Combined level color and lighting

This is where I combine all the previous stuff for the final level mesh texture. Only in view parts, roughly culled, are rendered again.

First the tilemap color is rendered with the level mesh (combining some ambient/diffuse lighting into it). Then ambient shadows are rendered on top. Then point lights, which are additive sprites with shader doing shadowing based on the shadow maps, are added. Lastly "ground splat sprites" on top, used for some indicators like player front direction arrow or some impact warning effects.



5. Water depth map

Very low resolution target where I render a top down view of the level depth (used for coarse depth checks in water rendering)



Background

Now we start to render to the actual screen. First render the background "plasma" and stars. I also don't fill the whole background, but generate a shape that fits the area that the level doesn't overlap, but just enough so I get nice alpha blending on the borders. A bit heavy shader where I also cut features based on if the mobile GPU is powerful enough. Gif shows the individual triangles of the background mesh toggling on and off in the final frame.



Level to screen

Then it's time to render the the level mesh to screen. This is a runtime generated mesh that is textured with the combined level texture render target we prepared before. The parts that will be fully below opaque water are not rendered.



Water

Generated mesh for water with a specific water shader. The shader does the effect with a few scrolling noise textures, foam for the shores based on the water depth map and coloring with some light params etc. and the level bottom color.



Level borders

Separately generated mesh for the level "drop borders". Two textures, one for the basic ground color and another for a bit of grass on the top, which again samples the level color map to match the lighting to the level.

Then there's also a separate mesh and shader for the parts where there's water on the level border.



Sprites

This is by far the largest task on the CPU side. All in-view particles, Spine meshes, sprites and grass sprites are gathered and sorted back to front. Then I generate one large mesh to render them all with one draw call. All these use the same texture (combined 4k sprite map).

There's a few bits of extra GPU processing on top of basic sprites to faciliate doing all these on one call so the vertex ends up a bit fat. The vertex has 2D pos (screen space), diffuse UV, color, ground UV, ground color multiplier and wind factor.

The sprites/spine meshes/particles themselves are generally lit on the CPU side by finding closest point lights and calculating the color from that.



The ground UV and ground color multiplier are used to color things based on the ground lighting. This is what gives the grass its color. The grass texture is white and I multiply it with whatever is sampled from the combined ground render target so the color always matches nicely. Some particle effects also use this, for example some near-ground dust uses a bit of it to give it a color that blends more with the ground.



The wind factor tells how much to "wave" the vertex based some ad hoc sin/cos "wind" values. For example grass gets large values so it waves much in the wind, trees get a bit so they too wave in the wind and buildings and units get 0. I also use the ground UV as "seed" for the wind so it's positionally stable. The .gif shows me trying some exaggerated wind parameters to highlight the sprites that use it.



Effects

Special effects are just rendered on top with no sorting, things like trails, lightnings, flares, the swipe effects from player axe etc. Some of these would benefit with from sorting, but generally they are so large and complicated in 3D space that they would either still look wrong or be too complicated to sort with not much benefit. I try to also keep them fast so there's no time to look if there's something very "wrong".



Additive flare/bloom sprites for lights are rendered on top here too. I also had an occlusion test for flares at some point too, but the effect was so unnoticeable and useless that I removed all the code for that in the end (after discovering that it had been broken for a month and I hadn't noticed).



UI

Then we just render all the UI sprites on top. Fonts are basic bitmaps fonts, generated with Glyph Designer. And then the frame is done.



I think that's it! Might have missed something, but nothing obvious. I'm always happy to answer questions, if there's any!
« Last Edit: October 28, 2017, 02:38:36 AM by gimblll » Logged

ddengster
Level 0
**


View Profile WWW
« Reply #145 on: October 28, 2017, 05:10:08 AM »

Nice stuff you've got there:)
Could you explain a little on point 3, the point light AO?
Logged

dotsquid
Level 0
**



View Profile
« Reply #146 on: October 28, 2017, 11:35:03 AM »

Nice tech done from scratch!
I didn't get how grass and trees are animated. If all sprites are packed in a single mesh, aren't the grass and trees animated in vertex shader? Or does it mean that you are using some heavy uber-shader for all types of sprites?
Logged
gimblll
Level 2
**



View Profile WWW
« Reply #147 on: October 29, 2017, 04:51:01 AM »

Nice stuff you've got there:)
Could you explain a little on point 3, the point light AO?

Thanks! So ok, yes. They're not AO (if you mean ambient occlusion), but proper shadows. It's the same basic idea that if you do a shadow map in 3D, you render it to a 2D texture. In 2D you get a 1D output. So first, for each point light, I gather all the occluders (line segments) within the point light radius. Then render those into one shadow map horizontal line so that from left to right, the U coordinate correspond to the angle, and the value ends up the closest depth. And the V coordinate in shadow map is the light index. Then in the light rendering shader, I check per pixel if that point should be visible or not (and then some smoothing on top). Does that make any sense? Getting into the actual details would require it's own tutorial post I guess.

Nice tech done from scratch!
I didn't get how grass and trees are animated. If all sprites are packed in a single mesh, aren't the grass and trees animated in vertex shader? Or does it mean that you are using some heavy uber-shader for all types of sprites?

Thanks! Yes, grass and trees get their vertices manipulated for wind in the vertex shader. The CPU writes the "how much multiplier [0-1]" wind parameter per vertex. So the vertex "uber" shader calculates wind to everything (few lines of sin/cos), but everything but grass and vegetation top vertices gets the wind multiplied to zero, so they stay still. It's a bit of a waste for sure, but vertex shader power is abundant in 2D games anyway, so there's no problem doing extra stuff there.
Logged

ddengster
Level 0
**


View Profile WWW
« Reply #148 on: October 29, 2017, 06:14:10 AM »

Nice stuff you've got there:)
Could you explain a little on point 3, the point light AO?

Thanks! So ok, yes. They're not AO (if you mean ambient occlusion), but proper shadows. It's the same basic idea that if you do a shadow map in 3D, you render it to a 2D texture. In 2D you get a 1D output. So first, for each point light, I gather all the occluders (line segments) within the point light radius. Then render those into one shadow map horizontal line so that from left to right, the U coordinate correspond to the angle, and the value ends up the closest depth. And the V coordinate in shadow map is the light index. Then in the light rendering shader, I check per pixel if that point should be visible or not (and then some smoothing on top). Does that make any sense? Getting into the actual details would require it's own tutorial post I guess.

Nice tech done from scratch!
I didn't get how grass and trees are animated. If all sprites are packed in a single mesh, aren't the grass and trees animated in vertex shader? Or does it mean that you are using some heavy uber-shader for all types of sprites?

Thanks! Yes, grass and trees get their vertices manipulated for wind in the vertex shader. The CPU writes the "how much multiplier [0-1]" wind parameter per vertex. So the vertex "uber" shader calculates wind to everything (few lines of sin/cos), but everything but grass and vegetation top vertices gets the wind multiplied to zero, so they stay still. It's a bit of a waste for sure, but vertex shader power is abundant in 2D games anyway, so there's no problem doing extra stuff there.

Thanks, think I get it! Hmm, so you're doing something like this? That's really cool. And I'm guessing each U coordinate has a range of 360 divided by rendertarget width.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #149 on: October 29, 2017, 11:47:22 PM »

Thanks, think I get it! Hmm, so you're doing something like this? That's really cool. And I'm guessing each U coordinate has a range of 360 divided by rendertarget width.

Kind of yeah. I don't need any of the visibility information for anything other than just visuals, so I don't have to deal with any of that raycasting nonsense and can just use the GPU. Smiley And yes, U is like that.
Logged

io3 creations
Level 10
*****



View Profile WWW
« Reply #150 on: October 31, 2017, 12:51:39 PM »

I'd be interested in an in-depth post because I'm not exactly clear what you mean.  I just skimmed a few pages and saw that you are using your custom 2d engine.  So, that means the grass sprite images have already been created and you are placing and updating the ones you want.  To get the nice smooth waving motion, the next sprites is used in the grass movement animation.  Or do you use some kind of skewing technique (e.g. texture uv or vertex moving in 3d) to move them because the trees seem like as if only a single sprite is used and then that sprite is manipulated.

Sorry, I'm not 100% sure what you mean, but yeah the waving motion comes from moving the top vertices in the vertex shader. And the vertex shader gets it's "seed" from the world location in 2D (top down), so if there's two grass sprites right next to each other with their sides at the same spot, they will get the same wind offset too so there's no gaps even though they're separate sprites.

And sure, I'll try write to make a separate lenghtier post about the rendering pipeline when I have the time!
Yes, that answered my question.  I was wondering if you were using the "traditional" bitmap based approach for images (e.g. a character running has all pre-rendered movement poses/frames in a spritesheet) or a vertex based approach.

Thank you also for the detailed explanation.  That was one of my guesses regarding the wind effect. Your ad hoc sin/cos "wind" effect looks really good.  Also, there were a few things that others asked about that I didn't even "see", but the examples have shown light to them (e.g. how the light affects grass and objects). Smiley


Special effects are just rendered on top with no sorting, things like trails, lightnings, flares, the swipe effects from player axe etc. Some of these would benefit with from sorting, but generally they are so large and complicated in 3D space that they would either still look wrong or be too complicated to sort with not much benefit. I try to also keep them fast so there's no time to look if there's something very "wrong".
Something potentially "wrong" comes to mind is when you swing the axe the you are behind a tall tree but the swipe effect is visible "in front of" the tree.  To me that would seem "wrong".  Especially, if the character is near the top of the tree because then the character should be farther in space.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #151 on: November 01, 2017, 11:59:29 PM »

Something potentially "wrong" comes to mind is when you swing the axe the you are behind a tall tree but the swipe effect is visible "in front of" the tree.  To me that would seem "wrong".  Especially, if the character is near the top of the tree because then the character should be farther in space.

That's true. It's not really noticeable in that you rarely do that behind a tree AND keep on eye on that. The game is very action focused, so you rarely notice those little things unless you go looking for them. Your focus is usually on other things. In a way it's actually better that you see the axe swing effect all the time so you know what's happening even if partially obscured by a tree. I would always prioritize readability of gameplay over correctness anyway.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #152 on: November 03, 2017, 04:44:47 AM »

Log Entry #44

Another slow week, I seem to be in a bit of a slump again. Argh. Need to climb out. This week I did two new enemy towers, one is just a fast shooting one and another one is a kind of magnetic thing that pulls things and then zaps them. It's ok, but needs tuning. At least it's something different.

I need to figure out a few more interesting towers at some point. The problem is that there's not too much insentive to go destroy the towers usually. It's often a better strategy to just pull the enemies away from the tower area or just kill the enemies fast and run away. I'm not sure if that's a bad thing, but there should be more strategy to it. I can counter this a bit by placing some things that need destroying before level ends into their shooting range, but that's not super useful and you can then "use" the towers themselves to shoot the things with their splash damage. I was thinking of maybe doing some tower that would lock onto you for forever if you activate it, but that doesn't feel too good either. I could also give some better rewards for tower kills, but that's kind of counter to what I want. The magnetic tower seems to cause some chaotic situations, so maybe I should look into doing some other physics things like that too... maybe.

Then I spent some time drawing some new walls and props, nothing special really. New metal wall type too which goes to World 4. Then I did some World 3 levels, very unpolished ones. I need to get back to these later when the player progression systems are in better shape. But the good thing is that gameplay of World 3 is I guess mostly finished (might need to do 1 more enemy, not sure), just need polish.

Next week. I'll have to take some time to plan what's next and how I'll pull all together. I'm in pretty good state now though that I pretty much know the basic shape of the game from beginning to end, but I just need to update my plans and designs etc.. Then I'll probably do a few more weapons/upgrades and such to put more meat into the progression. I'll probably work on the world hub too.
Logged

io3 creations
Level 10
*****



View Profile WWW
« Reply #153 on: November 03, 2017, 12:52:24 PM »

Yes, I agree that I tend to notice/look for those kinds of issues due to making games where z-soring is important. To me it'd similar to seeing an arm or leg appear in front of the tree. Grin

Of course, I don't expect everything to be realistic but another aspect might be more subjective and is based on my preferences/expectations.  For example, if there's an explosion with a large spherical volume, then I wouldn't mind part of that visible in front of the tree.  But the axe swing seems to be more like a plane.

Similarly, on the right side of the image below, there's a torch partially covered by the tree.  In that case, the glow in front in the tree looks good because you'd see something similar in the real world.  However, if that torch is fully behind the tree, the thick leaves would provide a dense cover and seeing the glow would not seem "right".
https://i.imgur.com/ZaIr0eB.gif

Visually speaking, it seems like that the axe swing sprites are large enough to be visible as none of the trees seem to cover them completely.

Also, audio sfx (axe swing hits something or misses) would also give a cue as to what is happening.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #154 on: November 03, 2017, 10:51:45 PM »

Of course, I don't expect everything to be realistic but another aspect might be more subjective and is based on my preferences/expectations.  For example, if there's an explosion with a large spherical volume, then I wouldn't mind part of that visible in front of the tree.  But the axe swing seems to be more like a plane.

Similarly, on the right side of the image below, there's a torch partially covered by the tree.  In that case, the glow in front in the tree looks good because you'd see something similar in the real world.  However, if that torch is fully behind the tree, the thick leaves would provide a dense cover and seeing the glow would not seem "right".

About the tree vs. glow. Yes, the glow will come through the tree if fully obstructed, which is wrong. Like I wrote, I had a full occlusion test written and working for that, but in the end I decided that it wasn't worth it (additional code complexity + GPU waste on mobile). So I just deleted it. I notice the artifacts now and then when they pop up, but it's not something that I lose sleep over. Everything is a compromise. Smiley

Here's my #screenshotsaturday post from this week. I think the axe swing effect works well here even if on top. If sorted, it would sink into everything and you wouldn't be able to see so well what you're hitting at as the bear sprite itself is only a flat 2D thing that gives no visual info. And as the axe swing damage arc is 3D (I want to visualize what it hits/damages, not what the axe sprite is doing), it would be an "interesting" problem of how would you even sort that. Anyway, no worries, I've got audio etc. there too. I think it's fine, even if "wrong". Smiley It's not something any of the testers have had issues with either I think.

Logged

io3 creations
Level 10
*****



View Profile WWW
« Reply #155 on: November 04, 2017, 09:30:45 AM »

Given the chaos of the scene, I don't think many playtesters' attention was on the axe swing.  Cheesy

If you were to look at actual distance, the current axe swing visuals are "close enough", close to about the axe's length.  But in case of a tree or tall building, the distance at the top of the tree would be 3-4 times as much.  That's why those would seem off to me if the axe swing still appears in front.
Logged

gimblll
Level 2
**



View Profile WWW
« Reply #156 on: November 09, 2017, 10:53:48 PM »

Log Entry #45

So at the start of this week I drew up plans on how to reach alpha / feature complete state. It'll still take many months, but at least I know where I'm going and what is the content/features that will get in and what gets cut. It finally feels like I might actually finish this game some day! That is of course until I start to have "ideas" again... already had a few cool ideas... nnngghhh... aaaanyway...

I started with hero's secondary weapons, I'm going to finish them all now. 7/9 done. One simple and one quite complicated left to do. Also a lot of audio missing, might leave that later, dunno. I suspect I'll spend maybe half of next week with that stuff. Then I'll finish the random "gift" drops (3/6 done so far) and I guess that's it for next week.

I don't want to spoil the new weapons, so here's one old weapon I showed ways back, but I drew a proper weapon sprite and upgraded the effects etc. to near final form.

Logged

gimblll
Level 2
**



View Profile WWW
« Reply #157 on: November 17, 2017, 06:08:52 AM »

Log Entry #46

All hero secondary weapons are done. There's nine total now, I think that'll do. They still need audio and probably some tuning once I progress further with other level stuff etc., but that's for later.

Then I spent a day on doing some code maintainance to break up some annoying compilation dependencies that had built up along the way. Now it's much more pleasant to add stuff again.

Also just now finished the random gift/powerup drops, there's 5 now. One really fun new one and one that's "ok". I don't want to spoil gameplay on these now though, so let's leave it at that. Decided to not do one also. I was thinking of an axe weapon power enhancer, but I felt it wasn't needed in the end. The other powerups compliment the gameplay much better (and you'll be able to purchase axe upgrades too).

Next week, I'm not sure. I'll probably concentrate on the shop system and the upgrades you buy from shops. I might finish a few final features on the player character too. Let's see.
Logged

borinouch
Level 0
*


View Profile
« Reply #158 on: November 17, 2017, 08:49:11 PM »

Your game looks amazing, love the style of the art and the gameplay looks like it'll be really fun. I have your devlog permanently in my list of tabs so I can check it on when I need to get motivated. Can't wait to play it, but I'm on a Mac also so I guess it might be a while before I get a chance.

Also if you don't mind answering, I was wondering your custom game engine, specifically the task scheduling. What kind of techniques did you use such as are you using lock-free structures and/or are you using any available library or is it all custom written? Do you have any suggestions or recommendations on where to look for someone thinking about trying to create their own task scheduling for their game engine. Thanks!

Logged
gimblll
Level 2
**



View Profile WWW
« Reply #159 on: November 18, 2017, 12:51:50 AM »

Your game looks amazing, love the style of the art and the gameplay looks like it'll be really fun. I have your devlog permanently in my list of tabs so I can check it on when I need to get motivated. Can't wait to play it, but I'm on a Mac also so I guess it might be a while before I get a chance.

Also if you don't mind answering, I was wondering your custom game engine, specifically the task scheduling. What kind of techniques did you use such as are you using lock-free structures and/or are you using any available library or is it all custom written? Do you have any suggestions or recommendations on where to look for someone thinking about trying to create their own task scheduling for their game engine. Thanks!

Hi, and thank you, glad you find this of some use! And the reverse is also true, I get motivated whenever anyone posts things like that. Smiley Mac port wouldn't be too difficult, but my Mac is 2011 MacBook Pro model that's just barely holding it together (no SSD, slow as hell), so it would be too difficult for me to do a port with that. Otherwise I would gladly do it. I'll do it if I can some day afford a new Mac.

So my task system is a custom system, and is based on fibers. It's based on something we used while I was at Housemarque, just reimplemented for myself. Also similar to what's presented here by Naughty Dog. There's a bunch of open source implementations of that apparently too, maybe worth a look. Mine's just a lot more limited as I just wanted something simple. For example I can't create tasks from other tasks while they are running etc., all my tasks are pre-constructed. Mainly just because I wanted to keep it as simple as I could and what I would need for this game. My lowest target are 2-core iOS devices so I don't need anything to scale that much anyway. It's worked well so far. Also, I don't really have lock free algorithms in it (outside of the task manager), tasks tend to work by themselves a lot. The only one is an allocator that I can use to allocate space for output from a vector (so just one atomic int that tells the current size). Then I have an atomic spin lock in a few places. It's all very low-tech really. Smiley
Logged

Pages: 1 ... 6 7 [8] 9 10 ... 13
Print
Jump to:  

Theme orange-lt created by panic