Thursday, July 25, 2013

Continuing with pyglet

After a lot of web searching and lying trying to beat the concepts into my head, I've finally gotten the basic tile engine working AND at a good enough performance.  Only thing is, now the HUD isn't appearing.  GAH!

EDIT: But wait!  I fixed it.  Maybe I can finally move on to non-mind-draining work, at last.

Monday, July 22, 2013

pyglet discovery

The current scheme is, a primitive shape (a triangle list) for each tile on screen.

My first attempt deleted the previous primitive and created a new one each frame.  Very poor performance.

Second attempt kept the tiles in place, but changed the vertices.  If the new tile has a different number of vertices from the first though, a resize operation has to be done.

It turns out that resize() is very expensive.  If I don't do it, and just make sure all the tiles have the same number of vertices, screen updates are much faster.

I'll have to design tiles around this, but the speed difference is encouraging.  I'm still looking into ways to improve performance.

Sunday, July 21, 2013

What I was doing wrong

So, it seems in OpenGL there are modes the system can be in, with names like GL_PROJECTION and GL_MODELVIEW.  And each one is a "stack" of matrix transforms, through which the various objects you then create are converted on its way, each frame, into being displayed.

If you change the camera, you really want it to be in GL_PROJECTION mode.  What is more, if you don't call gl_LoadIdentity() before you actually change the camera, then it seems your camera's position is modified relative to its previous position instead of from the arbitrary origin of the coordinate system.

It seems like a simple mistake to make, and to fix, but my Google searches were not an appropriately-shaped key to unlock that knowledge.  Most of the tutorials I had seen had covered using OpenGL for 2D, but not for scrolling around, at least not in the way I was wanting to use it.  Because I didn't perform this necessary step I was getting strange behavior, like the camera skittering off when I tried to move it.

I had been partly misled by a tutorial that said you could set the projection system to gl_Ortho once, at setup, and leave it alone.  The thing is, the code ended setting the mode to MODELVIEW.  If you then change the camera after that, well, you get weird behavior.  Instead, I needed to change back to PROJECTION, reload the Identity matrix, and move the camera from there -- changing it back to MODELVIEW afterward.

Wheee.

Friday, July 19, 2013

Still working on OpenGL/pyglet

I had jerry-rigged tutorial code in place that *almost* did what I wanted.  But it was more fragile than I expected, and when I changed it to do the rest, it broke.

I've been having the disconcerting experience where, when in my web searching I find out something I've been doing wrong, I go in and fix it, and it causes a blank screen, or my coordinate space not being what I expected it to be.  So I go back in and do more searching, find out a little bit more about how OpenGL handles the matrix math to convert vertices into screen coordinates, fix what was wrong, but break something else along the way.

I hope the NSA enjoys seeing my Google search records as being every possible combination of "pyglet", "OpenGL", "orthographic", "glLoadIdentity", "pixel", "GL_PROJECTION", and "gluLookAt".

Wednesday, May 29, 2013

pyglet

After a lot of frustrating hacking, made not less so by the fact that Pygame and Pyglet have completely different display paradigms, I've managed to get Pyglet displaying rects from the game's simulation code.  I just wanted to make a post to celebrate that quiet victory.

Friday, May 17, 2013

Progress!

What has been going on lately?  This--

Because there was do much cruft in the code from early bad assumptions and later-added misfeatures, I started it over. That turns out to have been the right choice-- progress had been rapid again, the new cellular engine is *much* faster, and my second take at a random world builder produces much more interesting output.

I've been trying to merge a previous tile engine I had gotten working in pyglet with this, which has been going slower, mostly because piglet doors things so differently from Pygame.  Anyway, more soon....

Friday, March 29, 2013

Design realignments

I've been thinking hard about the future of the project and the best way to go from here.

1. I'm more and more convinced a platformer, or at least not the style the engine currently runs, is not the way to go.  The thing is that the cellular engine can change the world, from turn to turn, in ways that it's not simple for a real-time platforming engine to overcome, at least not one developed by a single guy.

Solution: Go with something more tile-based.  Not abandoning the real-time aspects, but instead of worrying about subpixel-level movement accuracy, instead have the player move from cell to cell.  That doesn't mean it would look exactly like a roguelike, we can have intra-cell animations, but under the hood movement will be discrete, one block at a time.  And by not trying to be an action game, the framerate consistency problems, searching for a solution to which having been the secondary cause of the development delays (the primary one being having to keep myself fed and clothed -- I live well beneath the poverty line) are no longer a problem.

2. The high-degree of substance property randomization isn't as interesting as I thought it would be, and the code is a snarl in any case and difficult to maintain.

Solution: Ditch the lot of that and simulate, for the most part, a number of preset, interesting substance types, that each might have zero or one special properties.  There are too many substances that it's just plain out useful to have around for gameplay purposes: water for swimming, sand for piling up, oil for burning, and so forth.  There are reasons World Of Sand games always tend to simulate those basics.

3. The game world generator doesn't produce interesting spaces to explore.  Oddly, the nearly completely random world builder that I had in the earlier versions made much more interesting terrain than the current maze builder algorithm.  This is actually a case where more randomness is more fun than less.

4. The game world is so large that we can't simulate the whole thing easily, which makes large-scale structures (such as flowing rivers) difficult or impossible to do accurately.

Solution: Try simulating a smaller world.  Also, I've come to realize that 8 levels of fluid in each cell is almost certainly too many.  We could get away with 4 or even 2 levels, and the result would be far less calculation.

5. There is still work to be done towards optimizing the cellular engine.

Solution: There are four possible approaches to the engine, which I've tried to different degrees over time:
A. The one that I've been using the most lately uses a "spiral" scheduling system; cells are calculated going in a square-cornered spiral around the current view focus (either the player or the cursor).  Advantage: if we want to calculate fewer or more cells due to real-time requirements, we can just stop whenever we want.  Disadvanges: iteration overhead, if we're not trying to be an action game, unnecessary, and iterates over every (well, every other) in its region regardless of need.
B. The obvious alternative is a rectangular region around the focus.  Advantage: the sim
plest scheduling system, so the least overhead.  Disadvantage: Iterates over every cell in region regardless of need.  If there's nothing in a cell it moves on fairly quickly, but it's still a matter of concern.
C. Use a list of "dirty" cells, compiled as the previous frame is worked on, and only calculate those spaces.  Advantages: We can calculate much more of the world each turn within the same period of time.  Disadvantages: More complex, and thus more fragile.  This is one of the reasons I moved away from this approach before since the increase in complexity wasn't matched by the performance gains.  With a smaller world, however, we might be able to use this approach to simulate the whole world... making the large-scale structures I really want to implement possible.  I think this is the most promising avenue.  Since we're using random world building, instead of one gigantic world we could instead explore a series of smaller worlds.
D. Use the weird column-based "sort" I've been working on and wrote about in the past few posts.  I think it might be viable eventually... but it is a weird thing, it's good for moving fluids vertically quickly, but we still have to iterate through those cells anyway to handle side-to-side fluid movement.  And it's so weird that I think it'll also be even more fragile, that is, vulnerable to being broken by other engine changes, than the dirty cell list system.  So I'm not using this technique for this project, it might be an interesting experiment some other time but now isn't the time for that.

Tonight I went into the code and switched it from the spiral turn scheduler to a rectangular field one.  I also tried running the game with a smaller world, and it seems to work okay if I make sector sizes smaller.  If I make fewer sectors I get an error, but so it goes.  It'll get fixed, and so will the next one, and the one after than.  Until it's done.

It's nice to think it'll be done.  You've all been waiting all this time.  I've been laboring under this weight, this sword of Damocles, for two years now.  I don't ask for pity or for forgiveness -- I'm not sure I deserve either.  I just say, I have not forgotten it over all this time.  I have never considered abandoning the project, for even a second, and I'm not going to abandon it now.  When I make a promise to do something, I get it done, even if it takes a while.  If you thought to yourself "sure, we've heard that before," I wouldn't blame you in the least.  I'm still trying to think of this in constructive ways, though.

Well, that's where we are.  Next up: getting the smaller world size to work, derandomizing the substance properties, and designing a better world generator.