About FyberOptic (twitter: @FyberOptic)

Entries

 
Ludum Dare 31
 
MiniLD #52
 
Ludum Dare 29

FyberOptic's Trophies

The Longest Post In The World Trophy
Awarded by Tosic
on June 29, 2014

FyberOptic's Archive

Old Tricks for Old Dogs

Posted by (twitter: @FyberOptic)
Friday, December 5th, 2014 6:53 pm

I’d considered trying out a stable build of LWJGL 3, but I feel a cold starting to drag me down a bit, so I think I’ll just stick with what I’m comfortable with.  I threw the basic example code from the wiki for LWJGL 2.9.1 into a new project to set up the git repository, so I should be ready to rock.  At least, assuming I can pull any ideas out of my brainmeats this time, which didn’t work out so well last time, where I didn’t write a single line of code!  But LD29 before that was great, as was Mini-LD52.  So hopefully this one will get me back on the Ludum Dare track!

Second Go Around

Posted by (twitter: @FyberOptic)
Friday, August 22nd, 2014 4:39 pm

This will be my second official LD, though my third overall if you count Mini-LD 52.  Looking forward to it!

Like last time I decided to stick with Java, mostly because I just upgraded from Eclipse Kepler to Luna and want to see if there’s anything significantly different/better.  And like before, I’ll be using LWJGL for cross-platform OpenGL/OpenAL support.

I did my initial commit using the example code from the LWJGL wiki, just like last time, to make sure there wouldn’t be any kinks.

Let’s hope these storms don’t interfere too much, even though they’re predicted all weekend!

Idea Anew

Posted by (twitter: @FyberOptic)
Saturday, June 28th, 2014 1:14 pm

So my initial Mini-LD entry was to be a Minecraft-ish game for DOS, but as mentioned in my previous post, that didn’t really work out.  I didn’t have any idea where to go from there, but I still wanted to compete despite losing a few days.  I started trying to think of a side-scroller instead, since I at least already had some code for dealing with tiles.  I’d previously read all about John Carmack’s work to invent smooth scrolling on PCs with Commander Keen, including in the book Masters of Doom by David Kushner, a great read on the history of Id Software which I wholeheartedly recommend.  So I thought I’d see if I could come up with something that worked similarly.

The cube game I scrapped was designed to use all of video memory for scrolling, and I realized that I might need to make levels that are wider or taller than what’s possible in hardware scrolling alone.  The screen resolution was 320×200, but I’d set up for a virtual area of 640×400.  If you use 16×16 tiles, that’s a map width of just 40 tiles.  I also wouldn’t be able to do any kind of double-buffering, to avoid flicker when I started adding sprites.  So this is where the theory behind John Carmack’s work would come into play, as well as techniques I’d read about for doing scrolling on tile-based hardware like NES:  have a width of tiles that goes one or two larger than the display area, smoothly scroll these into view with the hardware, and as you get to the edge, shift the contents of the display over and draw new tiles along the edge, off-screen, allowing for seamless movement across a map much larger than video memory could ever hold.

On something like the NES, this is relatively easy.  It’s made for handling tiles.  They’re already in a separate section of memory (usually a separate ROM) devoted purely to the pixel processing unit, and all you have to do is fill another section of memory with an index of what tiles will be displayed where on the screen.  It handles doing the actual blitting itself, while the CPU is busy doing its own thing.  To scroll the screen, you shift only the array of tile indices over, and can adjust a register to set what pixel of the first tile to start drawing the screen at.  All of this makes for pretty smooth scrolling capability.

On the PC, however, this was a different story.  It wasn’t until EGA that the ability to do any kind of proper hardware scrolling even existed.  I was stuck with CGA for years when I was young, and I thought it was just the limited color and awkward memory arrangements that made game developers stop trying to support it.  But it was really lacking in multiple things that made games capable of running faster.  Other than scrolling, EGA offered features like extra video memory for things like double-buffering, basic arithmetic hardware for things like pixel masking, planar memory which let you clear and fill parts of the screen quickly, and hardware latches which allowed for things like quick blitting of graphics directly from one place in vram to another (the grandfather of hardware textures).  VGA had essentially the same graphics pipeline, which is why you saw so many games that supported both cards.

But even with all of this, computer graphics hardware of the time still wasn’t designed for video games.  There was no hardware for blitting tiles to the screen quickly like on game consoles.   And there was no hardware for drawing sprites on top of the background.  This was compounded by the fact that video memory was awkward to work with in most video modes, both from dealing with switching between the multiple planes of video memory, to pixels being packed into bytes various ways in the lower color modes.  The more work involved with drawing pixels made games like side-scrollers that much harder to deal with, because you had to draw all of the tiles on the screen yourself, draw in the new rows/columns as the screen was scrolled, and you had to draw the sprites on top, replacing the background tiles as they moved, while maintaining a respectable framerate.

Eventually though while writing the code for a side-scroller I shifted gears and decided it should just be more in the style of Gauntlet instead.   The tile engine would still work the same in the end, but it would save me from having to deal with things like jumping/falling and more complex level design.  But I still didn’t know what I was going to make!

I had to write a couple of custom utilities as I went along.  The first was to convert 8-bit paletted PNGs into C headers.  This included the palette as well, so that I could use what ever colors were necessary for the art while editing them, and let the program automatically set that palette to that when the game started.  But I took it a step further and used the util to break the image down into 16×16 tiles while I was at it, arranging them one after the other in a big vertical column, reducing the calculations and code necessary to draw them.  The other tool was to convert maps I created in Tiled into C headers as well.  Both of these were so I could add these commands into the makefile and just do a ‘make’ on the project to quickly test out any graphical or map changes.

Dr. Maze tile set

The tile engine itself still took a lot of optimizing.  By the time I added in test sprites that bounced around the map, I was crippling my framerate due to all the drawing of tiles to erase the sprites from the previous frame.  Initially I was capturing the actual pixels behind the sprites and redrawing that on the next frame.   I ended up converting various code loops into assembly, from tile drawing to screen scrolling, scratching for every CPU cycle I could get.  I also replaced the “pixel patching” technique I was using and switched to just fast-blitting the (up to) four tiles under each sprite, since I could blit those back from vram, where as capturing and replacing the exact pixels couldn’t take advantage of the latches.  At some point I also split the framerate in half, from the 70hz refresh rate of the resolution to 35fps, using the first frame to handle scrolling the screen, and the second frame to handle erasing and drawing the sprites, then flipping the final screen into view.

One of the test sprites was the animation you can see in the image above of what looks like a skeleton, even though it was really supposed to be zeroes and ones for more of a computery idea I’d had for the sidescroller initially.

It wasn’t until the Friday evening before the last weekend that some ideas started coming together.  That’s when I decided I could save even more time by having the maps generate procedurally.  I looked on Wikipedia for information on things like generating mazes.  I started trying to think up some cheesy 80s/90s video game plot with a mad scientist whose name somehow spelled out “maze” (Morton A. Zeman in this case).  That started to sound like a fun idea to me.

The mazes were a three-step process.  First is just to generate it in memory.  I chose a maze of 10×10, since I could make passageways take up 6 rows/columns each (counting the walls), and this would all fit within a 64×64 tile grid.  Next is to draw it out across a map with tiles.  And third is to go back over the map and draw in the wall shadows where appropriate, based on the immediate surroundings.  Later on I added in the code to randomly place the floppy disks in the maze, too.

With the maze working, I focused on some simple sprites and animations, and added in code for really basic AI to bounce the robots around, with the occasional randomness thrown in.  It was shaping up into a game already.

I wanted to have some way for the main character to shoot, or for the robots to shoot at you, but unfortunately I didn’t feel that I could pull it off very well.  I would have needed animation frames for walking up and down, and I’m no artist.  I went with the easier route of just making the robots “catch” you and drag you back to the start, which kinda fits with the whole concept of a crazy doctor obsessed with mazes.  I also added in the floppy disks bit, which was not only a fun way of finding the evil doctor’s plans, but also an homage to games like Commander Keen.

Somewhere in all of this is when I had to change the camera-follow code.  Initially I was scrolling the screen automatically when you moved, which could get out of sync around the edges (since scrolling positions were reset when the last/first tile was at the edge of the screen), requiring some special conditionals to account for when to start scrolling again in those cases.  But it just didn’t work very well, and I kept finding myself not exactly in the center of the screen after a bit.  And after I added in the ability for the robots to change your position, I knew it needed to be changed.  So I switched over to a system where the camera actively tries to follow the player instead, dynamically adjusting its speed until it “locks” on to the player again.  This worked a lot better, both at the start of the maze as well as when you get captured.  But it didn’t solve an annoying quirk of how your character starts moving a step before scrolling starts.  I couldn’t ever find a way around this, since scrolling occurs first, then sprite movements, so sprite movements would always be seen before changes in scrolling would.  Oh well though.  I had to keep moving.

Next I knew I needed to focus on sound.   Before the Mini-LD started, I started trying to read up on Sound Blaster.  But I knew I wasn’t going to have time for that, so I stepped back to just the PC speaker.  I was afraid I’d be limited to just awful tones, or complicated interrupt timing or something.  But it turns out that it wasn’t nearly as hard as I thought to make proper sound effects with it.  I basically just created an array of frequency values, and changed the output to the next one at the following frame.  I added in a couple of specific values which could trigger a delay or cut off the speaker immediately to help achieve some of the sounds I wanted.  But overall, I was surprised at how quickly that part went, and was satisfied with how it sounded.  The most time-consuming part was testing the sound effects themselves, which is why I eventually had to add them as debug keys.

I wasn’t going to bother with a title screen, much as with LD29.  But I realized I had time, and it would seem a lot more complete if I went to the effort this time.  That came pretty easily as well, since I was able to just draw words using the maze blocks in Tiled and make a few custom tiles for writing my name.  Then I added some simple “any key” kind of functionality into my keyboard handler.

Well, then I decided I wanted to be able to fade the screen out when you go to the next level, which meant writing in a bunch of palette code.  Performance isn’t great when you’re modifying 256 values per loop iteration, so I had to stick to playing the stairstep sound effect before I started the fade rather than during it as I wanted.  I made the title screen fade out as well.  Then I decided it was a good idea to show an interstitial screen between levels to show you which one you’re on as well, to give some semblance of progress.  Luckily I’d already added in a font and code to draw it when trying to figure out how to put text on a title screen (and never ended up using it for that).  I also decided to change the color of the mazes each level to help give the impression of progress as well.  This all kind of meshed together, but that was loosely the order I guess!

And at the last minute I added in the marker beacon, which it seems multiple people have confused for a mine instead!  I can’t blame them, actually, looking back.  But I wanted people to have some way to mark their path to avoid some frustration.  I also used the beacon as an opportunity to play with palette animation, since that’s how its little light blinks.  Though that’s probably the very part that confuses people about its purpose.

Other than the engine, the majority of the game really happened on that last weekend.  I hadn’t really had any sense of urgency or excitement until I got that wave of ideas and found myself rushing to get the game together, just in case a hard deadline got set.  It felt like a proper Ludum Dare at that point, and that’s when I found it to be the most fun.

In the end, there’s not a lot of actual gameplay, I admit.  But overall I’m satisfied with what I managed to make.  I still learned new things, and got a new appreciation for a lot of other games made and techniques used back then.

This post is unintentionally huge, so kudos if you actually read it all!

Little Hardware, Big Challenge

Posted by (twitter: @FyberOptic)
Tuesday, June 24th, 2014 11:33 am

This Mini-LD hasn’t turned up as many entries so far as I expected, but given the challenge that it can be to program anything for some of these old platforms, I guess I can’t be too surprised.  It actually makes me wonder how many people thought they were going to participate, and then just gave up along the way.  I even hit one of those points myself.

My game started out as something different altogether.  I had no idea what I was going to make before it started, I’d only practiced blitting some tiles on the screen and trying to get a feel for the VGA hardware.  After the competition started, though, I got it into my head that I was going to do a Minecraft-ish style of game, since I make mods for the real Minecraft, and have even experimented with my own voxel engine.  I could quickly envision what I had in mind, so I whipped up some simple graphics, and after a day or two I managed to have code together that could render tile-based cubes drawn in an oblique perspective.

 

Scrapped Mini-LD52 attempt

 

That mouse cursor you see could in fact click blocks and remove them from the grid, and the arrow keys panned all around.  But, there were a couple of problems.

The first is the issue of depth.  You can already see in that picture, particularly around the bottom left, how when you delete blocks from the front-most rows that they tend to bleed right into the rows farther behind.  I tried to combat this by giving blocks a defined edge, but this actually didn’t help; it just made the perceived depth bleed together two rows apart instead of one.

The other problem was performance.  Each cube is four tiles.  The order that the tiles are drawn is also very important.  You have to draw the grid from back to front, bottom to top.  You can skip drawing tiles for blocks which have blocks around them, which does help performance.  But the issue is what to do when you change the structure.  If you delete just one block, then the entire thing has to be redrawn.  I tried to think of ways to avoid this, like making special tiles to represent blocks beside one another with already-connected surfaces drawn on them, so that I could potentially only draw onto the screen the parts that were changed (maybe).  But if I was to have multiple kinds of blocks, then I was going to need combination tiles of every possible combination.  And even if I had tiles like that, it wouldn’t necessarily help at all if I were deleting blocks from deeper inside the structure.

In other words, deleting a block caused a noticeable hiccup until the grid drew back in, and I’m not really smart or patient enough to solve it!

Eventually I decided it just wasn’t practical.  And it was more of just a gimmick than an actual game, since I could have never had sprites moving through the terrain without more problems of dealing with depth and redrawing, so I scrapped it.  Which sucked, because suddenly I had no ideas.

On a side note, that mouse cursor is completely software-based.  When running in unchained VGA mode 13h, the standard mouse cursor is all messed up, still expecting a non-planar video memory arrangement.  So I’m having to capture what’s behind the cursor, draw it, then on the next frame, draw back the captured area to erase the cursor, capture the area of where the cursor moved to, then draw the cursor on the screen again.  So much work and processing just for something simple that we take for granted today!

And in case you’re wondering what I mean when I say “unchained” VGA, it basically means you’re tweaking registers in the card, turning VGA mode 13h (320x200x256) from a nice mode where video memory is one byte per pixel and linear into a more difficult to program mode where each byte is every fourth pixel, forcing you to switch between planes of video memory to write to the ones in between.   But this allows you to access all of the card’s video memory for things like panning, scrolling, double-buffering, etc, as well as doing some tricks like fast blitting from the vram using the card’s latches.

I was going to write about how I did my final game, too, but perhaps I should save that for another post at this point!

 

Updated Gems of the Deep

Posted by (twitter: @FyberOptic)
Monday, May 12th, 2014 5:48 pm

I liked where Gems of the Deep was going, and decided to keep working on it after the competition.  I made a lot of progress since then, but I feel like I ran out of steam on actual gameplay ideas, so I figured I’d just post the current version for people to play around with in case I don’t take it any further.

Windows

Mac/Linux/etc

Still requires Java to run.  Controls are mostly the same, too.

You never know when inspiration can hit, and I still would like to flesh this one out more since I really enjoyed making and playing it, but we’ll see what happens, I guess!  In the meantime, at least people can enjoy what there is of it.

Gems of the Deep Post-Mortem

Posted by (twitter: @FyberOptic)
Thursday, May 1st, 2014 9:52 am

I already wrote a “the day after” kind of post regarding Gems of the Deep, but I noticed that people were writing proper post-mortems about their games, and I thought that sounded like a good idea to address specific things.   So let’s sum it up!

What Went Right

  • Dynamic cave generation.  This was the very first thing I started doing after the initial rendering of a tile grid worked.   I didn’t want to be designing levels, and it seemed like a waste to not use some of this procedural terrain experience I’ve gotten recently (even if that was for 3D).  The tile grid wasn’t even initially as big, but it had to grow to accommodate the cave generation until I was satisfied with how easily it might be traversed by the player.
  • The jetpack.  This came along pretty early in the game, even before jumping.  Tuning the gravity and thrust was one of the priorities, which I eventually thought felt pretty smooth.  But I still felt like it was kind of unnecessary to constantly be flying, especially since it meant constantly hearing thrust.  Jumping was added on Sunday, immediately after which I moved the jetpack onto the W key.  I didn’t like it; I felt like I was fumbling the controls a lot.  So while out for a break I thought of just implementing a double-jump technique to activate the jetpack instead, and that ended up working out great.
  • Parallax scrolling.  It was never planned, it was just an idea to fill the empty void of the background.  I liked the look, so I kept it, tweaking it along the way.  Initially it was using the exact same render as the main map, so when you destroyed terrain in the foreground it was affecting the background too and looking a bit odd.  So I ended up doing a separate pre-render of the world, then using that one for rendering the parallax layers.   Probably would be even better if I flipped it, since at the starting area you can really tell that it’s the same cave.  But it’s fine once you start moving deeper.  It was apparently a hit with people reviewing the game!
  • The artwork/graphics.  And I’m not an artist!  Sometimes I luck out though by pushing pixels around, which happened with things like the main character and the bat.  Other stuff though, like the background tiles, went through several iterations (some still in the texture atlas) before lucking out on something which wasn’t bland, and which I could use as a base to easily tile random tile types together with.  Rounded corners had already been implemented before that, which made this all even more time-consuming because I had to keep remaking those, too, for each iteration of tiles.
  • Destructible environment.  This was another thing that wasn’t initially planned.  Shooting wasn’t even added until Sunday, and I added breaking blocks as a way to make the gun have a purpose in case I didn’t get enemies added in time.  A happy accident was when I realized that shooting gems made you collect them, because I had based the bullet on the main entity class.  The entity class itself had actually ended up primarily being the player class as time had gone by.  The player could of course collect gems by touching them, so bullets suddenly had the same behavior.   I left it, because I thought it was fun to collect them that way.
  • It’s fun.  Somehow I made something that I personally enjoy loading up and playing every so often, even after the contest.  I surprised even myself with that one.

 

What Went Not-So-Great 

  • Rounded edges.  Overall, this was a plus, avoiding sharp blocky corners and giving it a slightly more polished look.  But it had quirks due to the hacky way part of it was implemented, which while this saved a ton of time, it bugged me and made me worry that people would think it looked sloppy.  The combination of shortcuts manifested itself most noticeably when there was a narrow row of diagonal blocks.  I’ve fixed most of this in a post-LD version, though, using some multi-texturing techniques to apply the rounded edges instead.
  • There was no web app.  I mentioned this in the other post, but I kept getting Java security permission problems, and wasted a lot of time trying to sort this out.  I eventually decided that if my default Java permissions are going to give me this much trouble then I’m not going to bother aggravating other people with it too.  I cut my losses after wasting almost two hours signing and packing JARs.
  • There’s no music.  I wanted something to help set the mood, but at the same time I realized that if it had been bad or annoying/repetitive music (which could very likely have been the case, coming from me) then it might have actually worsened the overall experience.  I did try a few  music-related web things for a bit, but I never got anything I was happy with.  The other big part of it was that I honestly wasn’t even sure of the legality of using music from some of them.  Eventually I felt like I wasted enough time on it and went back to code.  Next time though I’ll be better prepared on that front; I’ll find a tool ahead of time.
  • There’s no proper crosshair.  There’s a flashlight beam, which I felt turned out really well (despite spending too much time on it), but that doesn’t really help you aim.  I also didn’t grab the mouse cursor due to the lack of any kind of crosshair/aimer system, which means it’s also possible to accidentally click outside the window, which is annoying.

 

What Went Wrong

  • There’s not enough gameplay.  Getting gems and shooting bats is fun, but it needed an end goal.  Even just a “you win” type of thing for getting all the gems (there’s exactly a hundred of them randomly placed) would have been better than nothing.  There just wasn’t time, unfortunately.
  • You can’t die.  I didn’t start working on bats until about an hour remaining, then health at the half-hour mark, which meant I not only had to make the code for it but also draw the heart (and I reiterate, I’m not an artist).  I wanted there to be some knockback from the bats, and some flicker during your moment of invincibility.  I wanted you to take damage if you hit your head too hard or fell too far.  I wanted to have earthquakes and have rocks fall.  Even something like stalactites/stalagmites would have made it a bit more hazardous.  Health didn’t seem incredibly important early on, but in the end it turned out to be one of the most important things which didn’t get finished, so practically anything that revolved around the concept didn’t either.
  • The wasted time.  Between all of the time spent sorting out the collision detection, dealing with the applet stuff,  redoing the map tile graphics several times, trying to come up with some music, etc, I could have probably accomplished many of the things the game needed.  I suppose most of that was just part of the development process, but the applet part at least could have been avoided if I’d worked it out before the contest.  But I didn’t even know I was going to enter until practically the same day, so there wasn’t much I could have done anyway, I suppose.

 

Overall it was an incredibly positive experience, one which I plan to participate in again.  Peoples’ reactions have been really enjoyable to read, and making something you’re proud of in such a short amount of time is pretty motivating.  And perhaps best of all, I learned a few things in the process!

To wrap this up, I thought I’d include one of the early screenshots:

ld29_1

The Next Day

Posted by (twitter: @FyberOptic)
Monday, April 28th, 2014 10:10 am

I thought I’d make a post to mention a few things now that it’s all over.

This was my first Ludum Dare.  I’ve known about the competition for quite a long time now, even played some of the games in the past.  But I honestly never saw myself competing in it.  I didn’t think I could ever produce anything worth showing in just two days.  I get stuck on things sometimes (like collision detection), and then the little glitches bother me enough that I just stay focused on that one aspect until it’s completely sorted out, or lose all my sanity trying.  I don’t know if that’s being a perfectionist or just being stubborn, but either way, I never thought I’d compete in Ludum Dare because of such things.  I never even intended on competing this time, but at the last minute I thought it might actually be fun.  I’ve been staring at one particular project a lot lately, complex and 3D, and I figured it would be a nice break to do something simple.  And it’s good experience, if nothing else.

I ran into two snags along the way which held me up.  One was, surprise surprise, collision detection.  I’m using the box method, and when that’s not perfectly implemented then you run into a lot of issues of clipping through walls.  Depending on the problem, sometimes that presents itself as if no collision detection was there at all, or alternatively, getting ripped through the wall and spit out somewhere else across the map.  There would be times where I thought I’d fixed everything, but then a little annoying bug would show itself, and I kept going back to that same code.  Eventually I perfected it though, and I was pretty happy with that.  But I lost time nonetheless.

The other timesink was trying to make the game run as a Java applet.  I probably spent almost two hours on that before finally deciding to cut my losses.  I kept getting Java permission problems, regardless of self-signing the JARs.  I figured if this is how it’s going to act with just the default Java permission settings then it’s going to be just as bad for everyone else trying to use it.  I don’t know if it was something on my end or something with LWJGL (I saw reference to an issue similar to mine on a forum which was said would be fixed in a later version, so I dunno), but unfortunately I wasn’t able to have a web version.

The artwork took me a bit of time, and it changed along the way, but I would say that that was more just part of the regular development rather than being a problem.  I’m not an artist, but sometimes I manage to come up with something that I like.  I have to admit, I’m pleased with how it came out overall.

Other than the two frustrating issues of collision and applets, I actually had a lot of fun.  Having a time limit really pushes you to come up with code that just works for that specific purpose instead of thinking too far ahead and trying to make it more robust.   I guess that comes from the mindset of not wanting to rewrite code when you realize you need to add something in later.  But in this case that was fairly irrelevant.

I worked right up near the time limit, only quitting about ten minutes till so that I could package it up and upload it.  Since this was my first Ludum Dare, I wanted to be done and submitted by the actual deadline.  I realized there was an hour-long submission window, but I figured better safe than sorry.  The website got hit pretty hard too, so I’m glad I got mine in when I did.

As for the game itself, they always say that the sign of a good one is one that you enjoy playing yourself.   I honestly do enjoy floating around and shooting things.  I definitely think that it’s something I want to develop a bit further.  I wanted to add things like earthquakes, maybe rocks falling, taking damage when you fall or hit your head too hard (the HP system was added at the very last minute, so I barely got bats hurting you implemented!), more enemies (like spiders), a thrust bar (which you have to either replenish, or it regenerates, I’d have to try it), a title screen and game over condition, etc etc.  I wish I could have made a more complete game to submit for the contest, but I’m still pretty pleased with what I managed to accomplish.

I can say with confidence that I’ll be participating again.  It was a great experience, and as a master procrastinator, I can say that anything that motivates you to make something is worth involving yourself in!

 

Base Code Commit

Posted by (twitter: @FyberOptic)
Friday, April 25th, 2014 4:20 pm

I’ve never done one of these before, but I thought I’d give it a shot this time around, even if I end up getting distracted along the way and don’t finish!

Just dumping in the base tutorial code, found on the LWJGL wiki, and getting a repository all set up.

https://github.com/FyberOptic/ludumdare29

 

[cache: storing page]