Category Archive: Programming
Subcategories: Bits & Bots Rant
Lost track of time, there. Whoops.
So, what’s new with Project SYPHA? Couple of things, over the last version I posted in 2014 (!). It has sound, collision, multiple rooms, rudimentary combat, and more – it’s nearly playable, at least to the point that I’ve finally posted the code in a proper repo. You can find it in two separate repos on GitLab, ‘sypha-engine’ for the engine itself, and ‘mod-noname’ for the game data (scripts, assets, and configs). Not sure how I’m going to end up licensing it – probably very permissive on the engine side (MIT, ZLIB, whatever), and maybe GPL on the data end of things.
Prerequisites for running the demo are a Git client and Love2D v0.10 or better; you can find instructions for cloning the repos here. If anyone wants to help out with art, scripting, mapping, or whatever, sign up for a (free) GitLab account and shoot me an email. Check out the commit logs on GitLab to see what I’ve been up to lately with it, and I’ll have more to see soon!
Stumbled across this on the Love2D forums: love-android-sdl2. It’s a native port of Love2D for Android, which allows you to drop a Love2D project onto Android without too much difficulty. As a test run, I’ve been porting Bits & Bots to Love2D – it’s already nearly complete, and I’ve worked in some major improvements over the old version (like finally implementing the buffered background layers). Once I’ve got the Love2D version fully running and tested, I’ll post the .love file around here somewhere.
Another random sighting of the MV-Plat sprites, this time showcasing the capabilities of the upcoming Tethical RPG engine. Check it out!
I’ve been liking the Android experience since I got the new phone, and Chrome in particular has been pretty good to work with, but.. there are a few quirks to it that I find a bit infuriating. One isn’t major, but it’s a tad inconsistent, and just annoys me to no end: when you hold your finger on a link and select ‘Open in New Tab’, it does just that – it opens a new tab for the link. But then, it HIDES THAT TAB, shuffling it to the background and returning you to the previous tab. I wouldn’t find it so irksome, except that in literally every other situation, the new tab gets focus. Did the link itself specify a new tab? No problem, open it up and switch to that. Did the page open an unrequested popup of a writhing nymph doing unspeakable things to herself (complete with audio)? OF COURSE the browser should automatically switch to that, especially if you’re at work or your inlaws’ house. But if the USER goes out of their way to hold their finger on the link for two seconds and select an option to open the link in a new tab, well, that’s probably not anything they actually wanted to view. Let’s just shove that to the background, and let the user jump through a few hoops to get to it. Again, it’s not that it’s hard to switch tabs, it’s just annoying as hell that the only time Chrome doesn’t give the new tab focus is when it’s blindingly obvious that I wanted it to.
Beyond that minor quibble, there’s the train wreck that is Font Boosting. What it is meant to do is adjust font size of individual html elements, to avoid situations where the user needs to scroll left and right to read the entire text – long, fine strings of text are boosted to a size that is legible when zoomed out so the whole element is in view. In practice, though, what it actually does is make any site with dynamic content a complete mess, with some chunks of text tiny and others huge. Most sites I browse, I actually have to zoom repeatedly in and out to read everything – it makes reading, say, Reddit MUCH more difficult than it has to be.
It doesn’t have to be this bad, though. For years (as far back as 2012, from what I’ve seen), the majority of Chrome’s userbase* has been asking – PLEADING – for an option to disable this horrible, horrible mess of a UI ‘improvement’, and by and large the response has either been suggestions to add a certain workaround to a site’s CSS (which is useless to users, since it can only be done by each sites’ web admins), or to suck it up and live with it because it’s ‘better’ (we’re all just too stupid to see why). All they need is one simple dumb toggle in the Settings menu, and everyone would be happy – if they can give us an option to mangle the UserAgent to avoid awful mobile sites, you’d think this wouldn’t be that big a deal.
*If you think I’m exaggerating, just Google it. For every snippet of praise (mostly from their press releases), you’ll find at least two bug reports, three ranty blogposts, and five ‘WTF is this’ forum posts about Font Boosting.
**Edit: Okay, so Z2 put the ‘New Tab’ thing in perspective. Seems it’s a holdover from desktop browsers, where Ctrl+Click does the same thing; the logic behind it is that the typical user does that to background something to be read next, after they’re done with the page they’re on. I guess that makes sense, but it still seems rather counterintuitive to me, when every other method of opening a link foregrounds the resulting page.
Got three weapon prototypes up and working: Knife (light/pierce), Sword (medium/slash), and Hammer (heavy/bash). Still playing with the timing and properties of each, but it’s a good start. Now to decide where to go next: combat, map/environment mechanics, or further fleshing out the GameObject class (which, realistically, should probably be first).
For combat, I’ve been doing some thinking on what equations to use. Attack is easy – (weapon base + strength) * modifiers – but defense threw me for a bit more of a loop. How much should armor affect damage taken? I don’t like the thought of a linear design (ATK – DEF = DMG) – a low-level character is overwhelmed too easily (especially if DEF > ATK), and if ATK and DEF scale at a similar rate, then you’re stuck doing a constant amount of damage no matter what level you’re at. I’ve decided instead to use exponential decay, something like:
DMG = ATK * e ^ (d * -DEF / ATK)
..where ATK and DEF are self-explanatory, e is Euler’s Constant, and d is a configurable rate of decay. This method tends to skew things toward the underdog – if ATK is much higher than DEF, then small increases in DEF will show a large payoff in the amount of damage mitigated, and if DEF is higher than ATK, the character will still do a small but decent amount of damage. A few examples:
- d = .9, ATK = 80, DEF = 20: 64 dmg
- d = .9, ATK = 80, DEF = 30: 57 dmg
- d = .9, ATK = 40, DEF = 70: 8 dmg
- d = .9, ATK = 50, DEF = 50: 20 dmg
Playing with different values of d will change the effectiveness of armor – the
lower higher d is, the more heavily DEF is weighted. My hope is to have a combat system where magic users don’t get unconditionally bulldozed, and the player doesn’t get stuck in too many situations where they constantly do 1 or zero damage.
A while back, I mentioned that Bits & Bots performs pretty poorly: at the title screen, with just two parallax scrolling backgrounds and nothing much else going on, it was using a HUGE amount of CPU time. I had tracked it down to my brute-force background rendering, and I finally got around to implementing the background buffering that I used for my NDS project (one of the few things I did right).
Basically, the background library creates a canvas twice the dimensions of the viewport and renders a chunk of the map to it; as the camera scrolls around this area, a viewport-sized chunk of the canvas is rendered to the active window. When the camera breaks the boundaries of the canvas, the background library renders another chunk of map, centered on the camera. Instead of looking up and rendering every visible tile each frame, it does one simple operation most frames, and only actually renders the background from raw tiles when it’s absolutely needed. Between that and the efficiency of Love2D for everything else, I’m down to only 3% of one core, which I’m pretty happy with.
As an added bonus, thanks to the direction of Ghoulsblade and Co. and the excellent documentation on the Lua Wiki, I built in Tiled map support at the same time. It’s an elegant suite with a lot of cool features, and a hell of a lot easier than trying to constantly fix LIV every time Firefox breaks it.
I fired up Bits & Bots the other day with ‘top’ running in a console, and holy crap, it uses a LOT more CPU than should be necessary. Ran some random tests on it, and found that CPU usage drops significantly on the title screen when I hold Space or S to hide the scrolling background layers.
So, looks like my background rendering is pretty craptastic. It’s written in a pretty brute-force manner: render every tile, every frame, which is stunningly inefficient when you think about it. 40×30 tiles per layer, times up to 4 layers, is potentially 4800 operations per frame (and that’s JUST for the backgrounds). Factor in text operations, which are written the same way (render every character separately, every frame), and you’ve got huge overhead for what should be a relatively simple scene.
How do we fix this? The best way I’ve seen so far is to use OpenGL Framebuffers to render a chunk of background to a texture, then blit the texture all at once rather than each tile piecemeal. To reduce how often it composes the background chunk, I would likely crib off the old DS version of the engine and load a section of background 2×2 screens in size, centered on the camera; the camera could then pan up to 1/2 a screen in any direction before it leaves the loaded area, at which point the engine would render another 2×2 screens centered on the camera.
This is probably the best way to attack the text rendering as well, though it’d need to be slightly altered – you’d need to be able to update the rendered string, and if the new value’s rendered size exceeds the size of the allocated texture, you’d need to release and reallocate it. Shouldn’t be too hard – I already have all the math worked out for the backgrounds in the DS code, since you could ONLY load a 4-screen chunk into the BKG VRAM at once.
Biggest drawback? Large textures – I’d need to allocate a 1024×512 texture per background layer. That’s not large by modern standards, but it’s larger than my current self-imposed 64×64 limit per texture. Time to ditch some old habits, I guess.
..Really, I should be working on pixelart for the next project, but if dicking around with rendering is what it takes to get me motivated again, so be it.
**Edit: Also, WIP pixel art:
Genre: Platformer or Dungeon Crawler
Main Mechanic: The main character has two main types of attacks, Lethal (sword) and Nonlethal (punch/kick/grapple). Enemies are either Cursed (humanoid-type monsters) or regular (animal-type monsters, etc). Lethal attacks do much more damage early on, and if a Cursed enemy is finished with >50% Lethal damage, they die permanently and do not respawn. Otherwise, they are stunned until the player leaves the area. Regular enemies always respawn. Some Cursed enemies are Boss-level encounters, which must be fought repeatedly if beaten through Nonlethal means.
The Twist: A third type of attack, Soul, is earned 1/3 to 1/2 way through the game. These attacks do not do damage, but instead have a chance of ‘cleansing’ a Cursed enemy and turning them back into a normal human; this chance increases as the enemy’s HP approaches zero. Cleansed enemies do not respawn, and may help the player in subtle ways (either through plot devices, loot, or new abilities).
The Hook: The quality of the ending (and the difficulty of the final boss) depends on how many enemies are cleansed; more cleansings == harder boss and better ending. A player who opts for Lethal attacks early on will have an easier time since the tougher Cursed enemies don’t respawn, but ultimately will end up with less Cursed enemies to cleanse once the Soul attack is attained, and even afterward the player may choose the easy path of killing everything and getting the ‘bad’ ending.
The Story (WIP): A warrior is dispatched to an abandoned village to investigate, and on the way there is accosted by a host of twisted creatures. He fights his way to the village, where a wandering monk stops him from killing one of the creatures. The monk explains that the Cursed are actually the innocent villagers, who must be saved at all costs.
The warrior continues on to a nearby mountain, where he finds an old wizard. The wizard explains that he is responsible for the curse, having accidentally unleashed the evil force from an ancient chalice/crystal/whatever. The warrior is granted the Soul attack type, allowing him to cleanse the villagers and send the evil energy back to the chalice.
With the Soul ability, the warrior travels to several McGuffin locations and (cleanses/kills) villagers. He encounters the monk several times, and learns that the monk is suspicious of the old wizard and thinks he, too, may be cursed. They return to the mountain and use the Soul ability on the wizard himself, revealing him to be a demon in disguise; the demon’s power had been sealed away long ago in the chalice, and when he finally freed it, it spread across the countryside and infected the villagers. The demon fights the warrior, drawing dark energy from the chalice; the more villagers were cleansed, the more power/forms he has. The warrior defeats the demon and seals it inside the chalice.
The ending can be Best (all villagers cleansed, you’re a freakin hero!!), Good (most villagers cleansed, and the demon has been sealed away), Bad (the demon is defeated, but at what cost?), and Worst (no villagers saved, and the warrior claims the chalice as his own).
Dear web developers,
Yes, you have an alternate site layout for mobile devices. Awesome. You win the internet, forever. But do the world a favor, and allow users to set a version preference (preferably in a cookie somewhere).
Seriously, who thought it was a good idea to restrict mobile users unconditionally to a stripped-down, buggy mirror of their site? “Oh, but the regular site isn’t sized properly for a mobile device.” Yeah, most mobile devices manufactured in the last decade have a ‘zoom’ gesture. I shouldn’t be locked into your unnavigable mess of reduced content just because Bob’s still working with a Blackberry his grandkids gave him in 2004. At least give the option of disabling it.
And for those devs who don’t know how to pull off mobile redirects properly (I’ve seen various sites where the redirect is to the main page, rather than just a mobile version of the link you clicked on), just quit. Your work is bad, and you should feel bad.
Now that Bits & Bots is out the door, I’d like to take a bit of time off to relax – just not too much time. I’ve enjoyed the momentum I’ve finally found over the past half a year after several years of messing around with the engine, and I don’t want to lose that. So, what’s next?
I kicked around the idea of a sequel/remake of Dragonrider (my old MS-DOS shoot-em-up), but.. I already made it once, and I’d like to strike out in a different direction this time. One idea I’ve had is for a Zelda-esque dungeon crawler; you’d only be able to carry two weapons/items, one piece of armor, and one piece of equipment at a time, and everything breaks as you use it. Say you have a sword and a shield, and you need to carry a key down a hallway full of archers: do you keep the shield to block arrows, or do you keep the sword to kill the monster at the far end?
Aside from that, I’d like to have the items break after a set amount of time or damage, to keep the player constantly using whatever is at hand to keep going. In games with lots of different equipment to choose from, I usually end up finding one combination and abusing it for a long time, while my inventory gets cluttered with all sorts of neat things I have no real use for. It might be fun to remedy this with short-lived items, forcing the player to branch out and use different equipment as they come across it.
Of course, a Zelda-like would need each action ‘rendered’ in three different directions (up, down, and horizontal), so it might be less work graphically to instead try for a simple platformer. I might just spend a few weeks doing random sprite art, and see what grabs me.