So a couple late nights of coding and I have some progress.Â First off, I “fixed” the textures of the coins.Â I didn’t put my ugly mug on them but that can come later. For now I have this simple star pattern I took off the interwebs.
Coin collecting ... will it have a purpose in the game. Purchase powerups inbetween levels, perhaps?
I was able to check off a few items on the to do list as well. I was able to finish the Specials reworking to behave more like Widgets in the editor. Specials now are faded unless they can be placed, with some being able to be rotated, and can be larger than 1×1. To prove this is working I made a Prop (static object) of a large “mound” which takes up 2×2 grid squares. Right now it has the texture of stone but really it could be anything.
Unfortunately I didn’t tweak Widgets enough to make some grand unifying design where everything goes through the same code to place/store items on a level. There is now a bit of code duplication, with more to come for Enemies. I was stressing about doing this, because I hate duplicated code, but the way I store the Widgets vs Specials vs Enemies, there wasn’t a nice way to do it in a general sense anyway. I could have called the same functions but put in a big select…case statement everywhere for all three types. Or I could have a large “Entity” data type that stored all the data for any type of item on the map. These are not quite worth it, in my opinion. Especially when I’d be stepping on code that is a few years old. If the language was OOP there would probably be a clearer path, but I just didn’t see it with what I’m using. Maybe I’m getting old. Or lazy.
I must say, like a kid who rediscovers just how good sugary soda is, I find it quite tasty to get quick results with several copy/paste/adjust sessions. I can see why code duplication and minor tweaking is so tempting under a time crunch. I still don’t like it, but I’m willing to live with it.
So work continues at a snail’s pace.Â I have not fixed up the coins.Â I played with Classic view a bit but wasn’t happy with the result so we are back to the original Classic view for now.Â Not much has been done for fixing up the Specials in the editor yet.
Really what it is, is that I have some trepidation about making some large-scale changes to the Editor, and how it handles Special types.Â Specials can be a variety of items:Â railings, obstacles (static objects), gems/coins, powerups, moveable objects.Â All those things.Â I want to make the Special type act like the Widget type in the Editor.Â Namely, be able to be larger than 1×1 tile, rotatable, and ghosted/solid based on placement.Â No doubt it will improve the editor immensely and allow me to make larger obstacle types.Â It’s just consists of gutting a lot of existing code.
I’m also teetering on the edge of reworking the Widget logic in the editor to be more general so I can just use that, instead of copying the code and tweaking, which I hate to do.Â However, I feel that the language’s data structures and procedural methodology will make this tricky.Â So it may end up being a copy job, because Specials are just different enough from Widgets to make it difficult to join them up.
I have time off in the next few days, so perhaps some late nights will be possible and I can finish up Specials so I can then move onto Enemies in the Editor!
As promised, the Whirlygigs are slightly more “map aware” and will avoid picking a target spot which will cause them to fall off an edge. I tried using raycasting from the physics engine but I had a few issues with my use of it, so I’ve adopted a simple grid-based detection system by looking at the map data itself. Not as neat a solution, and it can miss some things (obstacles), but it works for now. I’m having trouble with Hypercam2 at the moment, so you’ll have to trust me that it works without a video. 🙂
There is room for improvement in enemy awareness, of course. Sometime in the future I will look into making the enemies know when they are heading for an edge and try to avoid it.
Something else added is a zone awareness, where if the player is X distance away from the enemy, it will wake up and become active.Â If the player gets further away the enemy will go back to “sleep” at certain times.Â The necessity of this intial sleep state is when a player puts enemies on a level, if they are across the level from the start position and the enemies can move around before the player gets to them, they will be all out of place and not where they should be.Â This could ruin a level’s difficulty or predictability.Â It’s an obvious thing to code for, but still took some time to implement.
I’m going to take a break from coding and spruce up the coin graphics and visual properties in the game. Then I will try to touch up the Classic View (camera) so it works better with no Z-fighting and uses a proper backdrop.Â After those minor touch-upsÂ it is on to the editor additions I have been planning since I finished gems and coins. This includes a small overhaul of how “specials” are handled. Right now they are all 1×1, but I think it would be much better if I could make them larger, and treat them like Widgets are treated. This is a pretty big change, as I will be breaking something I just got working a few months back, but it is worth it in the end!
Well slowly but surely, we’re getting a decent Enemy AI system. The Whirlygigs can now stop on a dime.
Check out the video
Next up, zoning and raycasting themselves to stay safe. Right now they go right off a cliff like a lemming. Wrong game for that!
I have been working more on the enemy system, getting it to where I want to be. Most recently I made it so the enemies are aware when they are falling (under the level) and they disappear when they reach a certain depth below. Eventually I will have them fade out, but right now they “blink” out.
I have been busy with other things so not much marble development, but I have been reading fun books when I can…
Some light reading...
I use Finite State Machines (FSM) for many things in this game. So naturally I have put it into the AI code I have been creating. FSMs are easy to understand and build upon, but sometimes easy to get carried away with if not planned properly. So I am trying to sketch out some flowcharts of the various states the enemies can be in, and how they relate to one another. I’ll include a diagram of what the FSM for an enemy is once I have it all mapped out. Right now we have a rudimentary Wait->Active->Finished->Wait cycle written for the Whirlygig. It works out well and each enemy takes care of its own state.
I have done something which I think is interesting with the AI system. I have two controlling variables that [a] dictate how often I update the AI per second (cycles) and [b] how many enemies update per cycle. This variable system will be fairly helpful in determining a good balance for smooth updating throughout the second. In other words, we don’t want to update the AI for each enemy 100 times a second but we may want to spread it out and update 100 enemies once over the course of a second. This can be done any number of ways, either 10 times per second for 10 enemies, 5 times per second for 20 enemies, or twice a second for 50 enemies. The 10*10 will be the smoothest overall. An “update” is where the enemy will make decisions whether it should change state or keep doing what it is doing.