Advertisement

Do i make long/complex code logic or more art assets to simplify code?

Started by April 29, 2017 02:47 AM
21 comments, last by CelticSir 7 years, 6 months ago

From what i understand with your reply, i should do the "L" shape with two " I " pieces? Or did i misunderstand, and you were actually suggesting the opposite?


Yes.
You have a bunch of pieces. Since you aren't modeling the entire environment and instead are building it out of pieces, then use actual pieces.

The combinations for a wall aren't that complex. You've got the straight line, and you've got the corners. If you have a T junction that is two corners. You write about having curved corner walls, so really you've got this:

xfPzC4a.png

Four building blocks, all the curvy walls you want. You might sometimes need to have them back-to-back, but they should still work just fine for game purposes.

From what i understand with your reply, i should do the "L" shape with two " I " pieces? Or did i misunderstand, and you were actually suggesting the opposite?


Yes.
You have a bunch of pieces. Since you aren't modeling the entire environment and instead are building it out of pieces, then use actual pieces.

The combinations for a wall aren't that complex. You've got the straight line, and you've got the corners. If you have a T junction that is two corners. You write about having curved corner walls, so really you've got this:

xfPzC4a.png

Four building blocks, all the curvy walls you want. You might sometimes need to have them back-to-back, but they should still work just fine for game purposes.

Okay so my current approach is the right one it seems then, not sure what you mean by having them back to back?

Advertisement
Back to back would be when you have two curves opposite each other, on either side of the barrier.

The biggest drawback to this approach is the potentially high polygon count and draw call count. It is generally better to have modelers build the whole level paying attention to layout. If you must use segments like this, do all you can to keep them as rendered instances so they have minimal performance impact. A large number of parts will add to an expensive rendering cost if you aren't careful.

Back to back would be when you have two curves opposite each other, on either side of the barrier.

The biggest drawback to this approach is the potentially high polygon count and draw call count. It is generally better to have modelers build the whole level paying attention to layout. If you must use segments like this, do all you can to keep them as rendered instances so they have minimal performance impact. A large number of parts will add to an expensive rendering cost if you aren't careful.

It's a level editor so i am not sure i can see a way to avoid it. I guess i could try to merge the meshes into single meshes once in the level but thats another complication to worry about in future :P

Nobody saw the elephant in the room. He is using a code driven approach where a data driven approach would be a superior alternative. Even if I had a single wall piece I'd have added a world transform to the wall data itself and none of that if-else business.
However, I would indeed have more variety of pieces too as drawing larger meshes in one go is faster.

What do you mean by data driven approach ?

Advertisement
What do you mean by data driven approach ?

Instead of code, use data to express the decisions, as it is easier to change / extend / update / fix.

Are you referring to using tile bit masking ? Because if so i already have that but it doesn't really make the code any easier.

I am answering your general question "what do you mean by data driven approach?".

It literally means you store decisions, in whatever form, in data rather than in code, since data can be loaded at runtime, modified after shipping, modified by non-experts etc. I was not referring to anything specific.

However, if tile bit masking isn't working, tile bit masking is the wrong answer. You need to find another answer.

You seem quite stuck. Have you tried approaching it from the other end?

Assume you have to use simple code at runtime. No complicated long if/else code. Assume simple plain draw code, like "for (data d : drawdatas) { draw(d); }". Can't get simpler than that. One wall piece, one data. What data do you need then to make that work?

Likely it's not the ideal solution, but you seem to need a new way to approach the problem. Once you get going again, see if you can improve the approach. Tile bit masking was too far, my "one data, one piece" is perhaps not far enough. Perhaps the sweet spot is somewhere in the middle?

I am answering your general question "what do you mean by data driven approach?".

It literally means you store decisions, in whatever form, in data rather than in code, since data can be loaded at runtime, modified after shipping, modified by non-experts etc. I was not referring to anything specific.

However, if tile bit masking isn't working, tile bit masking is the wrong answer. You need to find another answer.

You seem quite stuck. Have you tried approaching it from the other end?

Assume you have to use simple code at runtime. No complicated long if/else code. Assume simple plain draw code, like "for (data d : drawdatas) { draw(d); }". Can't get simpler than that. One wall piece, one data. What data do you need then to make that work?

Likely it's not the ideal solution, but you seem to need a new way to approach the problem. Once you get going again, see if you can improve the approach. Tile bit masking was too far, my "one data, one piece" is perhaps not far enough. Perhaps the sweet spot is somewhere in the middle?

I don't follow how draw(d) would be stored in the tile to know what game objects to draw?

For example my code is currently like this which feels similar to your draw(d) idea:



if (tile.Mask == 22 || tile.Mask == 18 || tile.Mask == 55 || tile.Mask == 23 || tile.Mask == 54 || tile.Mask == 19)
{
    // bottom left corner
    WallManager.NewWall(WallType.Corner, tile.GameObject.transform, Vector3.zero);
}
else if (tile.Mask == 112 || tile.Mask == 80 || tile.Mask == 116 || tile.Mask == 240 || tile.Mask == 244 || tile.Mask == 84)
{
    // top left corner
    WallManager.NewWall(WallType.Corner, tile.GameObject.transform, new Vector3(0, 90, 0));
}
else if (tile.Mask == 200 || tile.Mask == 72 || tile.Mask == 201 || tile.Mask == 232 || tile.Mask == 233 || tile.Mask == 73)
{
    //top right corner
    WallManager.NewWall(WallType.Corner, tile.GameObject.transform, new Vector3(0, 180, 0));
}
else if (...
   // straight pieces & columns to check & combinations of corners/straight pieces and colums per tile
   // else if ... 100+ lines and counting.

I'm not even half way and its getting quite long and feels inelegant for implementing given the amount of checks and combinations involved. I can't seem to find blogs or information on other approaches for simplifying this code.

This topic is closed to new replies.

Advertisement