Entry 11 and walking into walls
Jan 25, 2011
O.K., 3 days “left” and I’m spending most of the time digging through math code and complex collision/movement/path-finding logic. Then again 2 weeks was a completely arbitrary number and since I’m not quite abandoning this, I am safe to call this progress and continue past 2 weeks. Although, I do intend to make a working demo on day 14.
Optimization
Now, collision logic needs to be reworked. First of all, the collisions need to scale linearly and not exponentially, i.e. the game shouldn’t check every unit against every other unit. The way to do this is to keep a unit width x height array and only check units against other adjacent units. Of course, more than 1 unit may be at the same tile X,Y; therefore instead of just a unit array, this has to be a unit list array.
Secondly, as I mentioned couple days ago, a function is needed to pre-compute collisions at certain locations, mainly for mouse commands and editor. Currently, sending a unit very close to an object will have the unit continuously try an move there, but the object would push the unit back, resulting in an endless oscillating loop. On the other hand, stopping units from moving at all, will completely block unit movement if it is touching something even the slightest bit. So a unit may fail to move past a corner and would just get stuck. I am unsure at this point, how to fix this. (Fixed grid movement would have been so much easier.)
Even more to this, 50 units all chasing player and looking for path every frame ends up eating all CPU time, which means path-finding needs to be separately handled and unit A*’s need to be queued, which is another headache. Finally, units should also avoid A*-ing more than necessary, which is even more time-dependent logic to implement. I could easily spend a few days just making unit “AI” move/attack.
OK, so let’s sum up collision:
* Against props — unit size versus prop size
* Against units — unit-1 size versus unit-2 size
* Against tiles — unit size versus tile border
* Against walls — unit size versus tile border
Now, while I have first two implemented; I don’t have the latter ones. But, they will come later.
So, first problem is player character control — player must be able to click on any passable terrain and its unit must move there. The problem is that sometimes the unit may only stand so close to an object/prop before colliding. So the mouse click logic goes as follows — first attempt to send to exact mouse coordinate unless the player unit would collide in that location; otherwise send to the center of the tile. This is seen below:
Clicking next to a tree will send the unit to the middle of the adjacent tile; whilst clicking in an empty space will send the unit to that precise location. This guarantees the player won’t be able to send the unit to invalid locations and have it get stuck/oscillating in some corner. Furthermore, as game boost “free movement”, this won’t abstract command issuing, yet contain player’s actions.
Walls
Here’s what walls look like:
Here’s what I actually have to draw in the sprite sheet (and this excludes yet to be drawn 4 x T and X combinations):
One can imagine how much work needs to be done even for slight changes to wall style.
I may just have to put the walls back between the tiles and be done with just 2 sprites per wall. Art assets are much more time-expensive right now than collision-coding. Which is not to say that the collision isn’t a frikin’ nightmare. But since a little hack with path-finding and movement, I think I can prevent units from running into walls and such. Although wall collision logic is still dreadfully weird.
So let’s uncomment the wall code and use the walls between tiles after all:
There — much neater — and let’s not forget how easy it is to draw this:
Now, the collisions are not too complex, just may be a bit math intensive. Both walls and impassable tile borders (or map borders) can be handled by the same logic. First, units are pushed away from the borders at the normal vector. That is, while in the same tile as the border, units can’t get closer to the border than half their size. Secondly, tile corners on both sides of the border “act like” impassable objects — that is push away anything close.
While this is almost the same in terms of logic, it comes down to code optimization, units in adjacent tiles, and the way the math is done. Now, only unit path following “AI” needs to be taught to move through tile centers and not cut corners (or cut corners only around non-wall/tiles), as that will end badly around walls.
Phew
Lots of coding today, lots of math. Glad to see all that high school geometry didn’t go to waste. Anyway, for those that only come for pictures, here’s two new pedestals and a two-day old tree I drew:
—-
Entry 12 or sticks and scripts
Jan 27, 2011
“Less beer and YouTube videos, more coding” is a design methodology that I fail to follow. Yet, behold and amaze that I am able to get something done when I want to.
Ctrl+L
First of all, I made the World properly save and load the game state. It’s a bit of a mess, since everything in the name is in classes, so various prop/wall/unit/tile types need to be named, units commands need to be stored as indices, etc., etc. And no pictures!
Illuminafail
Light is O.K. when it is wide and close to ambient illumination — the borders are barely visible:
However, sharp changes are more or less immediately obvious:
Especially on uniform terrain:
I tried making custom sized shadow tiles and shadowing each tile with several overlaid tiles, but that takes forever to render (i.e. FPS drops to 20 or something). I tried making gradient overlay tiles, but that’s over 10 tiles for each neighbour lighter/darker combination. I suppose I know a way to make this “pretty”, but I really don’t want to get into pixel shaders right now.
So, yeah, I spent several hours without any progress.
Angry mob
I converted Player into Faction and removed bunch of redundant code. Each unit can now have an optional “angry” flag, which indicates if an otherwise friendly/neutral faction unit has been angered (attacked) by the player. So now holding Ctrl over unit send the payer character attacking it instead of talking. This angers the target and it attacks back.
I don’t need Player class as a “player” — i.e. someone controlling the units, since I am not doing multiplayer any time soon. And user Player unit reference is just a single variable.
MapCraft
I fixed and updated map editor to include walls and unit and add/remove/preview everything properly.
Of course I still need to be able to edit individual unit data/inventory/location/direction/commands etc. etc.
A little less conversation
Something like this would be cool:
Call this concept art.
One custom scripting language implementation later:
Just to stress this out a bit more — this single frame has a ton of logic behind it. There is a global script file, where each line is a specific command. Units can call the script by starting processing at a custom location/label within the script. The script will then run until an “end” command. In the case of dialogue, script manager retrieves the relevant text lines for both unit “part” of the conversation and player’s response. Talking to a unit triggers the game into a dialogue mode and draws the current script’s lines.
It theory the same logic can be applied to anything and any script action implemented — changing tiles, spawning mobs, reacting to switches, player movement, etc.
Currently, further player response isn’t implemented along with many other cosmetic features.
Yay
Here’s a little plant I made:
Here’s some broken pedestals and a new similar swamp plant.
Well, I’m done for today. Quite a few things improved and added.
—-
Entry 13 or pixel shaders and lighting
Jan 28, 2011
Oh wow, day 13. That means I only have tomorrow to finish this project until my imaginary deadline. Ah, silly deadline, I am not sacrificing quality for speed. Anyway, I better not start any complicated features today…
Shader, por favor
Crapload of tutorials, old XNA version code and over-complicated 3D samples later…
Of course, no one told me shaders work only with the complete texture and in XNA’s case, after all the sprites in current batch are drawn — so with the primary buffer. I guess I won’t be applying effect to individual sprites either, since that is super-slow:
So I finally applied pixel shader to the scene, so now it needs separating into render targets, so I only apply it to a certain “layer”, in this case lighting.
So here’s a shader on only tile layer (with sine wave on red channel to see that pixel coordinates work):
Now, lighting is a bit tricky. I want a nice, smooth and fast blur. It is definitely faster to upscale a texture than to blur it full size, as sampling processes a lot of pixels around itself. Besides, the quality remains almost identical.
The way I do light it is still pretty “cheap”. I don’t use 3D per se, so lights are just black tiles applied with translucency proportional to the amount of light. So technically I am darkening the terrain and not lighting it up.
So let’s split the tile into 4 pieces. Oh, guess what? My tile doesn’t split in 4 pieces precisely and mis-aligns and creates border artifacts, so I have to manually cut of 4 pieces and apply them depending on X and Y being odd or even.
So this is how they tile up (color-coded):
So now that I draw them translucent and upscale 2x, I get roughly this:
Which, with some blur value and sampling tweaking comes out as:
versus old light effect:
There must be a better way to do this though, but since my World lighting is on a per tile basis, I might as well do it this way. All I have to remember now is to draw everything really light.
Ta daa!
So, today can be summed up as “pixel shaders yay”. I can already dream up a gazillion ways to apply these. Lighting was probably the most rendering intensive one, so any additional effects (fire aura, glow, spells, full-screen distortions, even weather etc.) can all be done much easier and nicer.
—-
Entry 14 or borders, walls, and shadows
Jan 29, 2011
I have gotten used to doing the blog and the game. Although my personal schedule still sucks. I guess this project is beneficial to me in a few more ways than immediately obvious. Anyway, less philosophy-ing and more pictures.
Talk a little more
Let’s start with finishing the dialogue system, mainly ability to interpret user input. The answers are numbered (think Bioware games), so the player can use the number keys to select response.
The problem with this is that you cannot reflect on the past text, which is a nice feature (think ”TES: Morrowind”). So, here:
I will also need need it to properly scroll (or just discard lines). Future potential features firstly include character disposition/attitude — friendly, warm, neutral, cool, hostile — or similar. Then, different responses — neutral, hostile, friendly, condescending, which would make different characters react differently. Of course, this all gets written down into the script system, which adjusts character disposition variables and selects responses/answers based on current disposition.
Behind stuff
Currently tall, wide, opaque objects hide anything “behind” them. This isn’t a problem for static object — walls/props/terrain — the map will be designed in a way nothing important is hidden. On the other hand, mobile objects, namely units, will be obstructed:
This can be solved by splitting the texture into 2 pieces and setting a custom “split” flag, which forces it to render the upper part translucent should a unit be behind it:
Border smoothing
Generally in tile games tile border transitions are (were) done like this (think ”Warcraft 2”):
But again — like with walls — that dirt patch took 8 new tiles (and this excludes corner ones):
I could smooth them out even more, but even so, the isometric nature is obvious. Even though, it looks much more decent:
Here’s water:
These were done quite hastily, so little alignment/continuity/seem issues can be seen.
In the end, all “terrains” wouldn’t need transitions to all other terrains. Only several combinations are needed. But even so, this is really tedious work. What I really need is a tile artist…
Other alternative is to introduce another layer, say “borders” with custom sprites for various borders. However, the borders will remain looking square. Alternatively, a new layer for transitional tile sprites can be used, which would look like above examples, but with transparent background:
This can significantly reduce the number of transition sprites needed for similar tiles, such as different shades of dirt. Furthermore, two transitions can even be overlaid. The only downside is rendering frame rate, however — not counting A* issues — fps remains at 60 for now. Although the correct way to measure this is to measure delta time change between different/new methods, not an absolute value.
Wall-mE
Finally, let’s do a line-of-sight “ray-tracing” around walls. And several hours later, I give to you:
It’s not perfect, with occasional corner cutting and bleeding; but when blurred it looks pretty good:
Now the light/shadow wall effect is disproportionately nice compared to the really square world.
2 weeks, ey?
So, it’s been 2 weeks. Have I reached my extraordinary vague goal of “finish what I started”? I suppose, I haven’t technically ”finished” what I started, but I definitely have not abandoned it and kept myself motivated this long. And that’s something to say for me and my attention span. I guess my real goal was to get “something done” so that I could point to it and say “that!” And I believe I’ve done more in this time than most projects manage to do, having even learned a thing or two.
Now, I hadn’t actually planned anything out, except the broad scale features that either came naturally or were forced by implementation limitations. But, I do plan to plan in the future. Firstly, the codebase has grown quite complex, and any rash decisions can lead to nasty problems and rewrites — and if anything puts me off; it is rewriting code. Secondly, design decisions are getting more and more specific and building upon previous decisions, so any changes entail a lot of work — again much-undesired code rewrites. Finally, having a plan and a deadline keeps things organized and sets a goal, so at no time do I sit there thinking “sooo.. what next?”.
To sum up, I have “a framework for a 2D isometric cRPG with real-time combat.”
What now? Well, I’m going to continue both the blog/devdiary and work on the game. I may start browsing around for some Indie game sites to potentially submit a pre-alpha feature-complete demo when time comes (hopefully). It would be interesting to receive feedback on this, if a tad discouraging should it be criticized.
—-
Entry 15 and tile transition borders
Jan 30, 2011
One day past the “deadline” and going steady. This project is more fun that I had imagined it would be two weeks in. Then again, I am skimming over “boring” stuff and implementing “fun” stuff.
Border magic
Here is an example of tile borders:
Making a new tile type and new borders isn’t too hard:
But these are still whole sprites — both the grass and the dirt parts. And, I also need to select and apply them manually; so let’s make this automatic.
First, I will introduce a new tile border layer right above tile layer. Currently border tile uses the same logic/class as the main tiles, and it becomes an editing nightmare with 12 tiles for just 2 types — dirt and grass. Besides, it is still missing a few combinations. To automate tiling, I would have to keep track of which tile has which base type, then change the tiles around appropriately. Just messy.
So let’s get back to yesterday’s extended translucent grass border spritesheet:
(Note that I avoid flipping/mirroring tiles that ”could” be mirrored at render-time, as this would be very visually obvious.)
Now, applying the additional border layer pre-calculated at start-up/after changes, many combinations are automatically resolved, producing a quite nice looking result:
And, most importantly, I only need to edit grass/dirt tiles.
Although, I am still missing a bunch of tiles:
This can be solved by having more than border per tile:
The true number of border layers I need is 4 — the extreme case of all 4 corner patches.
Here’s triangle borders and corner borders together:
Additionally, more than one type of border can exist on the same tile. Actually, now that I think about this, there are a butt-load of possible combinations and I should really make an exhaustive list for these.
So, here’s every combination covered:
Basically, a combination is triggered by being surrounded by exactly the correct tiles. Also, that was pretty cool — taking a picture of the paper and all, I should do this more often. Except that ”does” involve using pen and paper.
Anyway, finishing the last few single borders (U and O):
So, here are all possible combinations visible (I think):
There are 17 different tile border sprites — 4 sides, 4 corners, 4 L shapes, 4 U shapes, and a dot. This combines into 46 different permutations (rotations included). There are — obviously — 17 cases with just a single border sprite; 20 cases with 2 border sprites; 8 cases with 3 border sprites; and 1 case with 4 — four corners.
Obviously, it was worth doing a little exercise in pedantry rather than drawing 46 sprites. And, the actual borders do not have to be of the same tile type either. One corner can be water, one can be dirt, another sand, etc. This is also potentially fully adjustable to respect walls. Indeed quite a powerful way to do borders. I cannot name any game of the top of my head that used such approach *shameless brag*.
Here’s water borders to show this doesn’t take too long:
Nice!
A feature a day, keeps procrastination away
Here’s a little scene to show how much the engine can do up to now:
—-
Entry 16 and never-ending borders
Jan 31, 2011
Tile borders is the first feature that I am working on for more than 2 days continuously. I guess such features are bound to come more and more as I try to get them just right. Then again, this is a base concept that would allow me add new tiles/transitions easily.
So… many… borders!
Here’s another shade of dirt:
Here’s dirt bordering water:
Here’s a cool spring-like creation:
Now that I have played with the map editor a bit, I just realized that I hadn’t covered all the possible combinations. I was working under the assumption that a border covering a certain side or corner cannot have another border on top of that:
Basically, in every yesterday’s combination the borders can be of any type. That is, they can be same, different, or mixed. However, overlaid borders (one atop the other) must also match up correctly. In this example, the central/base tile is water, but it has dirt-grass (not water-grass) corner border, since it also has a water-dirt triangle/U border. This makes sense visually, but was not immediately obvious on paper/in code.
So here’s the final 3 border combination including a double-overlay corner:
Similarly U borders can have dirt patches on either or both sides:
… or have a straight edge:
And, of course, single O puddle can have any combination of corner tiles…. or may be that is something I will ignore as an option for now. That’s 17 more combinations.
What I do actually want to make is a “T intersection/junction” borders:
The borders are currently defined so that the terrain may only transition between two layers on top/below each other (grass/water; grass/dirt; dirt/water). This means terrain a layer apart (grass/water with dirt in between) can never directly border without at least one unhandled border combination. The question is: how many combinations decent-looking combination can I make/handle without the borders looking bad?
So here’s a dirt-water edge plus overlapping grass corner:
I guess it looks O.K. and if you don’t know it’s there, you wouldn’t be picking on it too much. In the end, this let’s me create diverse terrain. So, here’s all 8 permutations:
Here’s the other 8 combinations — i.e. T junctions with lower level being perpendicular to the upper level.
And this combinations also aligns nicely:
So, here’s the final 8:
Here’s my silly bit of paper magic:
That’s enough for now. If I ever feel the need, I can add more combinations, but I this covers every two to four layer non-overlapping combination and a number of simple three layer overlapping combinations. The core principle here being that the map editor prefers bigger “pieces” of terrain over small patches and such.
Now only issue is units being unable to come closer to the water (impassable tiles), since there is additional 5-10 pixels that look visually accessible, even though the whole tile is classified as impassable. Bah, screw this for now, my future self can worry about this.
P.S. I am going away until next Tuesday, so there is little chance I will update the blog, since there is almost no chance I will be working on the game.
—-
Entry 17 or when will I stop making borders?
Feb 9, 2011
Well, turd on a stick, my main PC’s video card died. And this laptop can’t even handle my main monitor. Anyway, day 17 or real-life day 24 (26 if you count breaks).
Gee, at which point did I think not commenting a single line of code would not back-fire after I need to take a week’s or so break? So what better way to avoid coding than making “art” assets.
What, more borders?
Playing a bit with map editing, there are some more quite common corner combinations — angled coast with corner patches:
So here’s single corner patch combinations:
And double corner patches:
Hurray, 12 more combinations. I’m starting to think some dynamic way of generating these could have been better since I didn’t anticipate ”this” many permutations.
No swimming at the deep end
Half the readers of this blog suggested I make a “deep” water sprite. (P.S. 1 out of 2 is 50%) So, here’s deep water reusing existing “shallow” water borders:
Now let’s make a transition between shallow and deep water:
Giving us:
Here’s all 3 possible borders for a deep water tile:
Now, I made the transition smooth and taking up almost half a tile. But this means that other borders don’t necessarily align:
There is a gap between the dirt coast border (2) and the deep water transition border (1). Since deep water coast is the same as shallow water coast, the combinations of deep coast and water transition mis-align.
I cannot make deep coasts “deeper” and further into a tile, as that would misalign them with other coasts. I can only make deep water transition closer to the tile border. But that doesn’t look as nice, because the transitions are sharp:
Guess I’ll leave this for later.
Back or something
Hopefully I’ll get back into some proper development soon. For now, just fiddling around.
—-
Entry 18 or how video gaming hurts my video game
Feb 11, 2011
OK, not having had proper PC for 2 month took a toll on my gaming needs. So even this wonderful project is being slightly postponed.
Bit more borders
After some furious coding, I made fully dynamic border generation. The beauty of this approach is that it resolves almost anything:
I only need to specify the basic 17 cases and an additional check for corners in the main logic. Granted, some borders look weird and don’t align perfectly, but in the big picture this doesn’t matter. I think I spent (wasted) enough time on this already.
The way it’s done is basically parsing the same tile over several “layers”.
The higher layer is always drawn above lower levels. Technically, tiles do not have “height” or know anything about layers; only borders are ordered based on the “highest terrain” — water to dirt before dirt to grass, etc. This makes perfect sense visually, but in the code refers to building borders one layer at a time, at the same time marking which borders have been filled and by what type.
So, for example:
Every border of a dirt tile is marked as dirt border (left image). Placing a pool on the dirt (middle image) would produce an L triangle corner. Every border of the pool would initially be marked as water, but as the corner border is placed, these 3 sides (NW, N, NE) would be marked as dirt border for further processing.
Now, placing grass patch above the pool (right image) creates a grass-dirt coast. The actual tiles are grass and water. But the tile already knows that it has placed an L dirt coast, so the North corner is dirt. Thus, a correct (grass-dirt) corner border is placed.
Any other combination is just a variation of the same logic, potentially creating any possible tile combo for which borders are defined. (Though mixing many terrain types would most likely look bad.)
Now, the final thing about borders is not placing borders between wall-separated terrain:
The only problem is that some omitted borders can create weird looking abrupt transitions:
I guess this will have to be solved the same way other weird borders are — careful map editing avoiding these.
Tomorrow, may be?
I think I’ll stop making borders and terrain for now (at least big changes) and focus on other features. I’ve got a little carried away with this, even if this is a core concept that the player will spend looking at most the game.
—-
Entry 19 or hopefully vacation over
Feb 19, 2011
Whew! Been a while. Considering how much time passed, I’ve really done nothing.
A little variety couldn’t hurt
One thing I want to introduce is multiple variations of the same terrain type — i.e. same tile but several slightly visually different variant. For example, here is dirt with 3 possible tile types:
The actual difference is visible during rendering (left — no variation; right — 3 variants):
It may not be overly prominent, but when you focus on it, it becomes quite obvious. Darker or lighter spots and borders do stand out. Poorly drawn/designed/unlucky tiles will end up looking crappy tiling on their own. Older RTS games, like Dune and Warcraft did not have this and could end up looking too repetitive. This, again, comes to how good human eye is at pattern recognition. Ever since Starcraft and bigger GPU texture memory, multiple terrain variations became prominent and it really shows. Needless to say, I am not particularly worried about GPU memory for all my current sprites are <20 MB in size; most of which is taken up by transparent space.
What Warcraft ”did” have, however, is border variations. Obviously same looking borders are much easier to spot that tiny tile differences.
So here’s grass and new grass borders (since both grass and dirt tiles got changed):
I am now doing all these with a base color (brown/green/etc.) and applying a bunch of filters (noise/texture/drop shadow/etc.) so that I can make exact changes to all the applicable sprites. When I started out I had 1 tile and 1 sprite. But now that I have 17 different variations, it’s much easier to keep everything dynamic and adjustable. Plus — knowing me — I love to reinvent the wheel and redo stuff.
Actually, the transition is too messy; here:
That took 5 min to illustrate the point.
Final thing is to make several border variations, but that may just take too long to bother with for now.
When you talk too much
Another important thing is proper dialogue vertical trimming. That is, remove top lines from the dialogue screen if the bottom lines don’t fit:
This also makes sure that full responses/actions are removed, not just half-sentences.
Let’s get back on track
Here’s me being bored (some crystals I drew for a different fail attempt at making a game):
—-
Entry 20 or how I considered Xbox 360 in my plans
Feb 21, 2011
Entry 20 or more than a month in real time. I might need to redo this numbering system into real world days. It kind of makes no sense doing it in “code days” if I skip updates.
Ex boax three sixty
I want this game to be ”potentially” compatible with Xbox 360. Unfortunately this is a major decision that needs to be made at the start of the project.
So, let me illustrate how 360’s controls work…
NO:
YES:
I hope today has been informative for you.
Here’s the character moving based on Xbox controller’s left thumbstick’s position. A bit rudimentary and does not account for the angle, but — hey — it’s the thought that matters!
OK, the image is not very informative, but I really can’t be asked to make a YouTube video from this (until after I get something more done).
—-
« Previous entries (1-10) — Next entries (21-30) »