dorchadas: (JCDenton)
Insert that quote about how "I'm a content creator--I create problems for myself."

If you know anything about JSON, you might think "refactor JSON? What are you talking about?" If you don't, JSON is a way of storing data that makes it easy for both machines and humans to read. It's all done as key-value pairs, so you have like
"name": "Item",
"Description": "This is an item.",
"black": true
and so on and so on, with as many fields as necessary.

The reason for the refactor is that Cataclysm: Dark Days Ahead has a JSON-based scripting language incorporated into it. A lot of games use Lua for modding, a programming language where one of its main feature is that it's designed to be embedded in other codebases (such as that of a video game), and indeed some other forks of Cataclysm use Lua as well. CDDA does not, for several reasons, but as far as I know the most relevant is that it's open source, multiple builds come out every day, and the Lua integration would need constant work and constant tweaks to keep working with all the changes. A full game that releases discrete patches can make sure all the Lua binds are working before releasing the patch, thus avoiding constant mod disruption.

Anyway, CDDA has a scripting language called "Effect on Condition" that's all built out of the dialogue system, which allows certain dialogue choices to only appear sometimes depending on what Conditions are set--what other quests you've done, how long since the start of the game, if you have certain items, etc.--and cause an Effect, like setting NPC opinions, giving you quest rewards, and so on. That was all expanded out to scripts that run under certain Conditions and cause certain Effects. Nowadays a lot of the game is reliant on this system for more complicated effects, since it's easily expandable and testable without re-compiling the game, which lowers the barrier for contribution. One update allowed crafting recipes to run a script on completion, and I used this to make training psychic powers for my Mind Over Matter mod into crafting recipes. At the time, I did not have the skill to come up with a generic framework, so every single recipe (something like 200) had individual handling for training whatever power it is attached to.

Well, this week I pulled the trigger and rewrote every one of those 200 scripts so they all called on a set of ten total scripts, nine for each of the psionic paths (telekinesis, telepathy, etc), and then a final one that handles which power you're using and appropriately trains it. That means if I ever want to make changes in the future, I only to do it at most ten times, and more probably only one time, rather than having to mirror the change 200 times and hope that I never mess it up. It only took like six hours to go through thousands of lines of JSON and make all the changes, but now it's all done and easy to make further changes. I'm already thinking of how to make learning powers a bit more complicated--currently it's a straight Skill + 1d10 vs a difficulty roll, and when that was repeated 200 times I was loathe to change it. But now that I would only have to change it once...

The eternal battle between "add new things" vs. "do boring work of making old thing better" and this time the second one won.

Fun with bugs

2024-Jan-02, Tuesday 14:46
dorchadas: (Kirby sweatdrop)
Going to do my New Year's post tomorrow, but first another Cataclysm story.

So if you know anything about video games, you know the way the player perceives them and the way they work under the hood rarely have anything to do with each other. FPS devs making the apparent last 10% of the player's health actually 40% of the total health bar, or making the last bullet in a magazine do 5x the damage of the rest, so that the player is more likely to end a fight on low health and out of ammo in their gun and feel the best feeling in a game, that you had to pull out all the stops against overwhelming odds and just barely won. Fallout 3 not having any system for vehicles so the metro trains were actually NPCs with giant tram-shaped hats that you climbed inside and then the NPC would run along under the tracks, that kind of thing.

In Cataclysm, you can scan in books to an e-reader or a smartphone, as a reflection of how good modern cameras are, and then keep your entire book collection with you. This is very convenient but a recent bug exposed how it actually worked. There was a change in the way gun magazines worked, and fixing that bug meant that people were picking up their smartphone, turning on the flashlight, and suddenly having a hundred books materialize out of thin air and fall into their lap.

This is because how book scanning works behind the scenes is that smartphones, laptops, etc., all have a giant invisible Tardis pocket that makes a physical copy of the book and holds it, so the PC is still using the code for reading a physical book, they're just carrying it invisibly with them. And the change to gun magazines meant that pocket was changing and the game was doing what it's supposed to do when a pocket changes somehow--kick out the entire contents so it doesn't get lost. Thus, sudden magic library!

I'm not sure if this is better or worse than how monsters with ranged attacks actually have an invisible NPC holding a gun do the actual firing or not.
dorchadas: (Chrono Trigger Campfire Scene)
So I had a problem I was trying to solve. I'm working on electrokinetics for my Cataclysm: Dark Days Ahead mod and the top-level power is supposed to manipulate a corpse's nervous system to raise it back up to fight for you briefly before it expires again. However, by default, the raised corpse is hostile. Which approach would you take, given that:
  1. Look up the spell effect in C++ and follow it through to the function in monster.cpp that turns items back into monsters. See if you can pass through a check for a spell flag that will cause the raised corpse to be friendly or, failing that, duplicate the methods so you can have a revive_but_friendly one that causes revived monsters to ally with the player, then make sure that monsters who revive naturally don't become friendly...

  2. Remember that there's a "Charm Monster" spell effect, and just chain that after the revive so from the player's perspective it looks like the monster comes back friendly.

Lesson--don't overthink things, and if it seems like it works from the player's perspective, that's what matters.

Code "style"

2023-Oct-24, Tuesday 14:38
dorchadas: (JCDenton)
So I did more programming for my Cataclysm mod and I wrote the following statement:
if( in_species( species_PSI_NULL ) ) {
return false;
} else if( has_flag( mon_flag_HAS_MIND ) ) {
return true;
} else if( in_species( species_ZOMBIE ) ) {
return false;
} else if( has_flag( mon_flag_HUMAN ) ) {
return true;
}
else {
return false;
}

Simple, right? It makes the clear decision hierarchy obvious to the reader. If not A, then B. If not A or B, then C, and so on.

Well, no. It turns out the heads of the project have very particular ways they like things to be done, and they don't want any nested statement where different branches return the same thing--so no having two branches return true or two branches return false. This is set as a warning in the tests, but they deliberately elevated it to an error.

Alright, so I need to change it. And I thought, and I thought, and I said, you want a simplified statement? Alright, I'll give you a simplified statement!

return ( ( !in_species( species_PSI_NULL ) && has_flag( mon_flag_HAS_MIND ) ) ||
( !in_species( species_PSI_NULL ) && !in_species( species_ZOMBIE ) && has_flag( mon_flag_HUMAN ) ) )


Malicious compliance is a go.

(I did leave a comment explaining the logic, before you ask).
dorchadas: (Maedhros A King Is He (No Text))
We went to baby Shabbat in the park Shabbat morning, at the same park I've gone to Torah study in the past. They also had a Torah study there but I skipped it this time to help wrangle Laila. She needed a bit of wrangling--when the rabbi started reading a storybook (Chicken Man), she walked right up in front of Rabbi Lizzi and stared at the book and ignored the rabbi's polite requests to move away so other people and see. I felt better though when the rabbi's daughter, age 4, did exactly the same thing. Emoji embarrassed rub head Adira was old enough to complain about not being able to see anything, though, so after that the rabbi moved backward and everything was solved. Laila even listened to the story!

Working more on that mod for Cataclysm and it's reminding me of all of those Game Developers Reveal the Nonsense They Had to Use to Make Games Work articles that come out. To pick one example, CDDA makes it difficult to determine who the other party is outside of dialogue, where the other party is the person you're talking to, because the internal scripting language developed out of the dialogue system and wasn't originally designed to handle all the uses it's being put to. However, it's always obvious who the PC is. So when I made a monster that drained the PC's stamina and health (in that order), I rather than actually doing it as a drain I set it up in code so that the monster checks the PC's stamina and health levels and then has the PC secretly use a "drain stamina/health" power on themselves. This is necessary because there's no way to set attack priority or otherwise influence monsters' AI.

I just made a telekinetic power to let people lift cars to change the tires and the way it works in the game is by summoning a jack made of telekinetic force that you hold in your inventory and can use when you work on a car. It's not the DC Metro is actually a hat but I feel like it's on the same pathway.

I'm most of the way through Hollow Knight. I last beat Hornet in Kingdom's Edge, one of the blocker fights for a lot of people. It took me as many tries as all previous bosses put together I think, and while I looked up strategies and found a cheese one--equip charms for fast attack, thorns, faster healing, and just spam attack until you win--I'm stubborn enough that I refused to do it. I used magic and dodged her attacks and learned her patterns and eventually I did win. It's just like all that advice about never giving up.

This weekend we're going out to the suburbs for fireworks! The award-winning Batavia Fourth of July fireworks didn't happen this year because cellular network outages meant the coordinating computers couldn't actually coordinate, so everyone went to the field and spread out their blankets and then nothing happened. The town couldn't have that, so they rescheduled it for the first weekend in August. I'm not sure if it's going to be the same program and super Emoji Sad Eagle Flag AMERICA Emoji Sad Eagle Flag themed, which I don't have an ideological problem with but which would be a little weird in August, or if they're going to come up with a new program. They've had a month to do so. I guess we'll see.

While randomly scrolling through Facebook I saw an ad for a candlelit Legend of Zelda music concert put on by Fever. While I've been to multiple Symphony of the Goddesses concerts, those are all full orchestra. This is a chamber orchestra so it will be a genuinely new experience for me. I asked [instagram.com profile] sashagee about it, and though she has never in her life played a Legend of Zelda game she was excited about it, so we're going to turn it into a date night! It's in Logan Square, where I don't know what the good restaurants are but I know there are good restaurants. I'll write about that after it happens.

It's all just math

2023-Mar-28, Tuesday 09:42
dorchadas: (Office Space)
Thank you for your good wishes for [instagram.com profile] sashagee's health! She's doing a little better, though still not back to where she was a couple weeks ago. She's scheduled for some more tests soon so hopefully that will get her back on track.

Working more on my Cataclysm mod and someone just added the ability to use arithmetic expressions in spell fields, unlike the previous limit of integers only. Right now, since psionics should be a little unpredictable, the powers are designed so that the damage is totally random within defined bounds, and leveling up the power decreases the randomness. Because of the way the syntax works, however, I couldn't previously increase the possible max damage at higher levels without allowing that amount of damage as a random possibility at lower levels--but now I can! And then I thought, oh, I should also scale damage based on Intelligence too, so I needed to come up with a mathematical formula for that. After a while of trying to figure out how to get +1 Intelligence to mean +5% damage normalized around 10, I gave up and went with adding 5 to Intelligence, dividing by 15, and then using that as the multiplier. That gives +6% damage at 11 Intelligence, +13% at 12, +20% at 13, +27% at 14...

...and I just figured out that answer while writing this post. Add 10 and then divide by 20. Emoji Picard facepalm That would give me exactly the values I was looking for.

Anyway, it didn't matter in the end because I wrote up the formula like so:
"max_damage": { "arithmetic": [ { "arithmetic":
[ { "u_val": "spell_level", "spell": "pyrokinetic_eruption" },
"*", { "const": 3 } ] }, "+", { "const": 97 }, "/"
{ "const": 15" }, "*", { "arithmetic": [
{ "u_val": "intelligence" }, "+",
{ "const": 5 } ] } ] }
...and then the game told me "too many args," because each arithmetic operation can only take two arguments and you can only nest them two deep, so it's flatly impossible to do what I want. Oh well. Maybe in the future someone will add a way that it can work.

At work they're refining the database we currently use to try to make it something that's remotely functional at scale. They have actually done a lot of refinements from the initially basically unusable state and now it is actually possible for me to accomplish some work in a day--[instagram.com profile] sashagee was initially like "White collar jobs are a scam! You're not working at all! You just play games and occasionally look at your screen!" until we switched back to the old database and she realized that I did actually have work to do when the tools didn't prevent me from doing it--but while the minutes' long wait between every action has actually been fixed, having to click through seven or eight screens to do anything still exists. I'm trying out the new refinements and it does seem to work a bit better, in that there's a work queue on the same screen as the one where the work takes place which is actually a massive improvement! I currently can't test record management because the list of test profiles does not include anything that I can manipulate...but it does show the same record multiple times in a row. Well, I'm sure eventually it will all get fixed.

Eventually, eventually, eventually.
dorchadas: (Maedhros A King Is He (No Text))
We spent most of this weekend at the grandparents' houses, at my parents' house on Shabbat and then at [instagram.com profile] sashagee's parents' house on Saturday night and Sunday. [instagram.com profile] sashagee went out with my parents around noon on Friday, and I stayed behind to finish the workday, vacuumed, did the laundry, wiped down the counters, emptied the dishwasher, and otherwise did all the pre-Shabbat cleaning, then I got on the train, went downtown, and took the express Metra out to the suburbs and arrived just in time for dinner. Pot roast. Delicious!

We didn't go anywhere or do anything particularly special while we were there except hang out with the grandparents and give them Laila time, but Laila had a lovely time! She was so excited that she had a hard time taking her naps but then didn't want to go to sleep because she would have missed out on the excitement. That meant that she spent a bunch of the visit tired, and when we finally got home on Sunday she fell asleep for an hour and then woke up and cried for two hours because she absolutely did not want to be alone. When I went into sing to her, she clung to me like I was a sinking ship and cried when I tried to hold her prone in my arms instead of letting her hug my neck. She finally consented to be put down in the crib but demanded I keep a hand on her head, and if I tried to move it away she reached up to grab it back Emoji Kawaii heart After fifteen minutes of singing בשם השם to her she calmed down...or so I thought, because she started crying basically as soon as I closed the door. [instagram.com profile] sashagee went in there after a bit and that did the trick--Laila fell into an exhausted sleep around midnight and [instagram.com profile] sashagee wasn't long after her. On Monday she had a much better time.

I'm nearly done with my psychic powers mod for Cataclysm: Dark Days Ahead and currently having to deal with more bugs. The ones that I can't solve myself are:
  • I'm trying to make a teleporter power that warps space so that enemies' movements draw them toward a central point, but the function to move monsters is bugged. My current idea is to make a fake 'enemy' that will pull everything nearby toward it, but that's reliant on being able to make a summoned monster that other monsters will ignore.

  • Telepathic powers work on zombies because there's a whitelist for which targets spells can affect, but no blacklist. That means when I set HUMAN as a possible target for telepathic attack, formerly-human zombies--who are tagged both HUMAN and ZOMBIE--are eligible. This is unfixable without me personally adding a blacklist function to the game.
On the other hand, I was playing last night and discovered a feral psychic in the wild, so I know that my attempt to add them to monster spawn list worked! It was a pyrokinetic who proceeded to throw fire everywhere and set the hospital I was trying to loot on fire, so that was exciting! I'm also in the boring numbers-adjusting part of the game. "Oh, I think [Ψ]Fountain of Flames does ten percent more damage than I want, and [Ψ]Stutterstep lasts too long" blah blah blah. The boring-but-necessary part of game design.

Yesterday, I went out to lunch with [facebook.com profile] aaronhparker, who's taking a trip to Japan in April and wanted some suggestions of where to go. Unfortunately, his group's itinerary isn't set in stone beyond being in Japan yet, so I really could only provide the most general advice. I told him that if he had to go three places, he should go to Tōkyō, Kyōto, and (of course) Hiroshima, especially talking up Miyajima. I mentioned Kiyomizu-dera and Arashiyama in Kyōto, too, and when he talked about hiking I told him about Matsumoto. We only met for a bit over lunch because we both had meetings to go back to and I feel like I didn't provide much actionable advice, but I did suggest that we meet up again when he has a better idea of exactly where he'll be. I should be have more advice then.

Alright, back to this unknown physician project. At least I can tell right away that "Dr. Sages Webmaster" and "Dr. Northwest Hospital" are not real people.
dorchadas: (Chicago)
In a striking change to most years, the weather has not plunged like 30 degrees after the new year and the weather report even shows that it's above freezing for the next week! On the one hand it's nice to be walking to work and not have to button my coat--the universal sign that winter has arrived--but on the other hand a warm Chicago winter is not exactly an encouraging sign for the global temperature mean. Nonetheless, it's supposed to be 5°C today so maybe I'll take a walk along the river at lunch.

We finished all of our 年賀状 (nengajō, "New Year's Cards") this week--we were waiting on a few addresses. In Japan, 年賀状 are strictly formal without much personalization at all. They have a few set phrases offering good wishes for the new year, you stamp your personal seal on them by the dozen, and drop them in the mail. The mail carriers pick them up and hold them during the month of December and then deliver them in a blizzard--something like two billion 年賀状--on New Year's Day. They're premade and all you need to do was address them, and in past years that's mostly what I did, though I did translate the Japanese on them for the benefit of the mostly non-Japanese-speaking recipients. This year, [instagram.com profile] sashagee wanted the absolutely cutest 年賀状 out there, so I presented her with a few candidates and she went with this one:

Nengajou 2023

The year of the rabbit! It doesn't include the rest of the standard text, usually something like 旧年中は大変お世話になりました。今年も宜しくお願い致します。 ("You have been of great assistance to me in the last year and I look forward to our continued good relations in the new year"), but I suggested that we modify the tradition a bit and put photos on our family on it. I'm certainly never going to send anyone a Christmas card but there is social value in updating your friends on how your family looks, so I put a photo on there from our trip to the arboretum and [instagram.com profile] sashagee wrote a simple good wishes standard message (shades of the standard 年賀状). I ordered fifty of them and that's usually more than enough for my purposes but this year we ran out! Next year we'll have to order a hundred since we're sending 年賀状 to [instagram.com profile] sashagee's family and friends now which expands the circle of recipients by a lot. Next year, I'll be writing 年賀状 for a while at the end of December. At least two people working on them makes it faster.

I'm still working on my psychic powers mod for Cataclysm: Dark Days Ahead and last night I spent two hours trying to solve a problem. I decided to make the starting Teleporter profession an "Imperial Terran Navy Liaison," a psychic from an alternate dimension where Earth has an interstellar empire who got dumped on post-apocalyptic Cataclysm Earth after a jump drive accident, so I thought I would give them a hypertech gun that was standard issue in their home reality, balanced by virtue of never being able to reload it. Easy, I thought. Cue hours of "invalid ammo type" errors and me frantically scrolling through documentation, loading up a Teleporter and finding the ammo type was "0 Null", reading existing documentation and examples of guns and trying to figure out what was wrong, searching through the Discord and Reddit, the classic woes of computer programming. And sure, JSON doesn't involve math or formal logic, but it does involve proper semantics being extremely important, and something was missing.

In the end, I solved it by writing these four lines:
{
"type": "ammunition_type",
"id": "mom_fusion_ammo",
"name": "B47 fusion shot",
"default": "mom_fusion_ammo"
}

The problem was while I had defined the ITN B47 Fusion Pistol, and the magazine that goes in that pistol, and the physical ammo that's placed in that magazine, I hadn't made the definition of that physical ammo as an ammunition type--it was just an item with type AMMO, not an ammunition_type. Emoji Byoo dood As soon as I put in that extra definition, all the errors went away. At least for the other error I got (teleporter's "attune to location" ability not working) it was because I had assigned the same id to two different things. That ammo problem...ugh.

As my father often says, the more you know about computers, the more surprised you are they ever work.
dorchadas: (Cowboy Bebop Butterfly)
To work on a mod for Cataclysm: Darker Days Ahead, to add psychic powers to the game.

We'll see how far this goes.
dorchadas: (FFXIV Warrior of Light)
A year and a half ago, I wrote about how my Free Company in FFXIV managed to acquire a house for themselves, in what's often called Housing (Savage). Well, this time we completed Housing (Ultimate)

2022-04-16 - Spoony Bards acquire housing
[instagram.com profile] sashagee and I in front of our new large house!

We're moving from a small to a large, so while our old house was a sushi bar up top and a speakeasy on the bottom floor, now we have three floors, every one of which is bigger than our whole entire house was before. We also only have 400 item slots to fill the whole house--smalls get 200 items, mediums get 300 items while being over twice as big as a small, and larges get 400 while being twice as big as a medium--so we're really going to need to think about how we want to do the decorating. [instagram.com profile] sashagee wants to make it a museum to all the different Final Fantasies, with mannequins of their heroes. Right now, all we've done is the yard.

We got extra lucky, though, because we actually won. The FFXIV housing system is famously bad because there are only a limited number of houses--it's not instanced, they are real locations in the game world--and previously the winner was the first person who bought it, which meant that people woke up at 4 a.m. and sprinted to their house to buy it any time new houses were added. Any houses that went up for resale went up at a random time up to twenty-four hours after the original owner relinquished it, so people would spend hours clicking on the house in the hope that they would be the one to find the exact second it went on sale. That's how we got our previous house, after like twelve hours of hunting and clicking on housing placards, and we swore we would never do it again. But we did not have to, since this time the devs introduced a lottery! [instagram.com profile] sashagee, [facebook.com profile] aaron.hosek and I all put in our 50 million gil and ignored the house until the lottery results came due, where we found out that #3 had been drawn and [facebook.com profile] aaron.hosek won!

Most people had a much different experience, however--when the lottery results concluded, they went to the house with hope in their hearts and found that somehow #0 had won, and when they checked the results it said that there were zero participants. This was true even for houses with only a single bid. Each ward contains thirty houses, and in our ward maybe five people actually won. The medium-sized house down the stairs from us (we're on the highest point in the district) had several members from the same Free Company standing forlornly around it as I ran back and forth to the market board, and I chatted with them a bit to discover that #0 was the winner at their plot too. Emoji dejected

News just came today that the FFXIV team identified the bug and has the original data for who the winners were supposed to be, since it was apparently a communication error rather than an error with the actual lottery. So hopefully all the winners get their houses as intended! As for us, we have a lot of decorating to do.

Two memes

2019-Apr-07, Sunday 13:56
dorchadas: (Iocaine Powder)
I started on the next FreeCodeCamp project (based on React) and almost immediately got stuck. The answer turned out to be the IDE's fault--I had an unclosed comment at the end of the HTML section and, due to the way that CodePen separates out the parts of the page source, it was commenting out everything else without me actually knowing that was happening. Once I closed the comment, everything worked fine.

Computers. Emoji Psyduck Cylon

But before I figured that out, I did a search for the error message I got about abbreviation nodes, typed up part of the message and let Google autocomplete and, well:

Unable to Consume programming humor
Four common programming errors.

Unable to reach Ballmer Peak. Time to troubleshoot.

I also finished かぐや様は告らせたい ~天才たちの恋愛頭脳戦 / Kaguya-sama: Love is War today. A solid 8/10, with a story not based on stupid cliches, but rather based on the extremely-common modern desire to make the other person be vulnerable before you so you never have to risk any heartbreak. I've already bought the first volume of the manga, and while the sale of EbookJapan to Yahoo Japan means the old reader app I have no longer works--and thus, annoyingly, I need an active connection to read my books and can't download them all for reading on the L--I'm still going to make time to read it. A story about mind games borne out of insecurity but with a happy ending sounds like a treat.

But! The meme is actually based on a scene from the anime where they're in a taxi, trying to get to a fireworks performance before it ends. You can probably guess what it is from my Currently Listening section:


I sent this to [twitter.com profile] meowtima because I knew he would appreciate it, and now I share it with all of you in the hope that you will too.

Alright, back to Breath of the Wild while I put off chores for a bit longer. Emoji Link smilie
dorchadas: (Warcraft Face your Nightmares)
Yesterday, I had to maintain broken code!

So for background, months ago I completed a Random Quote Machine as a Free Code Camp project, but I'm reworking it as part of the revamped curriculum. As you can see if you click that link, it no longer works at all, and after a bit of exploration I discovered it's because the quote API I used is no longer serving data. "Alright," I said, "I'll find a new one."

That took some doing because I had to find an API served over HTTPS to avoid cross-domain requests, but eventually I found one that worked and then it kept displaying "undefined" for both quote text and author. Why? Why was this happening?

Well, it turns out that not every JSON object is formatted the same. Emoji embarrassed rub head I was using the object keys from the original API which didn't exist in the new API, so I went through the code and changed all the old keys to the new keys and it worked! Then I realized that was a bad solution, set two variables to the new author and text keys, and used those variables to display the data. Much more maintainable!

Of course, just now I realized what I should have done is split off the display code into a function invoked when the AJAX call is successful, so I'd only have to change the function call's parameters and the function would handle everything else itself. And indeed, I'm going to go do that next. This is why functional programming is a thing, so you're not search-replacing variable names and risking something getting screwed up (why isn't my code working at all? Oh, right. Let me just change "reponse" to "response"...).

At least this is a problem with a solution I figured out and implemented myself, rather than hours lost to not typing one }. I should treasure this feeling.

Tampered Monkeys

2018-Oct-18, Thursday 16:36
dorchadas: (Teh sex)
So I finally fixed a long-standing issue with the new database! There's a button to move records around that we have to click every time to enable drag-and-drop movement. It's not enabled by default and has never been enabled by default despite two years of asking for it and me bringing it up in meetings multiple times (yay external vendors!). So, I took two minutes and wrote a TamperMonkey script to click the button on page load, saving me several hundred clicks a day. And it works!

I showed it to my old boss and installed it for them, too, since their work requires clicking the button less often but they still have to do it for every record. They said they're going to share it around for everyone who has to work with the new database.

I mean, sure, hopefully I get recognized for this, but really I'm just happy I never have to click that button again. Emoji La
dorchadas: (FFVI Celes My Brain Hurts)
Last night, after a period of struggle, I finally finished all of the JavaScript exercises on Free Code Camp post-revamp. I did a few before they changed the entire curriculum around, like the ROT13 cipher that I posted about here, but post-revamp there are five major projects to complete the certification. Here's the last one that took me the longest: a cash register.

Here's the code )

I ran into two major problems while I was writing the code. The first was the While loop, where it kept quitting out without advancing the counter, and thus not checking every cash denomination in the register, and I couldn't figure out why. Eventually I added a second Else to advance the counter if either If statement was false, and then I remembered you can check for multiple conditions and only execute the If all of them are true. That took me like four hours to remember and when I added the &&, everything worked and I had my answer in the final form.

The second was with the last test case in the original problem. The answer was formatted strangely, with money returned from smallest denomination to largest rather than just the change given to the customer. This really confused me--did I need to add some kind of special condition to handle just this case? Why was it so different? What was I missing?

It turns out I didn't read the problem. Emoji embarrassed rub head The problem specifically specifies that if the change is all of the remaining contents of the register, return the entire register pre-transaction, which will probably have most drawers empty. Once I realized that, and reformatted the early part of the problem to function on a copy of the cid variable rather than on cid itself, it all worked out. And just now writing this I realized I don't need cidRemaining, which is a relic from before I added the workingCID variable. And there's a console.log still in there I should get rid of.

There. Did that. 💮

I managed to solve this without looking up any other solutions or checking forums for other people asking questions. Neither of those are bad, and in fact they are essential to a programmer's work (see this classic video for an succinct explanation), but I'm still proud I came up with this solution all on my own. The one thing I did have to look up was how to use map() on multidimensional arrays, which led to the understanding that I can map() on each instance of another map(), and that was the final puzzle bit I needed to finish off the function.

Next up on the curriculum is the section on libraries (Bootstrap, jQuery, React, etc), but tonight I'm going to take a break. Maybe I won't even study Japanese!

Well, I won't get ahead of myself. Emoji Nyoron
dorchadas: (Nyarlathotep)
They spent a week rebuilding the database and index, checking the entries, and then it immediately broke when I opened it after they said they were done. The very first physician I checked had no data attached. For this we spent all that time and money.

Just got an email that they are still looking into it. Emoji Psyduck Cylon

I saw an article on twitter about how Glyphosate (aka Roundup) is killing bees. There are previous studies that found no effects on bees' navigation skills or learning ability, but this new study checked bees' gut bacteria and suggests that exposure reduces bees' resistance to disease. So add that to the list of ways that humans are destroying the environment and didn't even realize it until decades later. (h/t to [twitter.com profile] TwentySidedCat for the link)

I went to an Anime Chicago discussion on Sunday about 四月は君の嘘 / Your Lie in April, and it turned out that I was the lone dissenting voice. It was a fun discussion, but I felt a bit like a wet blanket talking about how all the slapstick humor with care taken to animate the blood in an anime about trauma due to past abuse turned me off, and how in a show almost entirely about how music allows us to form connections beyond words, they kept interrupting the musical performances with the audience's internal (and external) monologues. And the main female character is a manic pixie dream girl dying of mysterious anime disease. I gave it a 4/10 and I think the average excluding me was more like 7.75. Perhaps I am a hater. Emoji Cute shrug

Other than that I did a lot of nothing this weekend. I some coding practice and made a Roman numeral converter (only Arabic -> Roman, though it'd be easy to make it work the other way too). That took about an hour and a half of staring at the problem with no idea what to do, and once I figured out an approach, writing the function took maybe ten minutes. Then I kept getting NaN as the result, changed stuff, changed other stuff, changed it back to how it started and...it worked. I'm not sure what sorcery occurred, but I'll take it.

I'm sure I changed something somewhere that fixed a bug, but damned if I know what it was.

[community profile] questionoftheday asks: If you were given the chance to be immortal, and to forever be the age of your choosing, what age would you be? Why?

My answer: 25. I mean, is there anyone who's going to answer differently? I guess some people would want to be younger than that, but given the choice would anyone want to be physically older assuming their mental experience came over unaltered? I don't see why.

Though if I were frozen at the age I am now I'd do okay. I'm 36, and I drank half a bottle of wine and stayed up to 1 a.m. last night talking with [twitter.com profile] lisekatevans and I'm fine today. As long as I can keep doing that, I'm good.
dorchadas: (Office Space)
Time lost to stupid mistakes in the last week:
  • Typing 0 instead of 1, thus iterating over the wrong array and repeatedly getting "undefined": Three hours.

  • Misplacing a bracket, causing the loop to always return true: Two hours.

  • Checking the wrong function input, thus causing the function to always return false: One hour.
Programming languages are like real languages, in that a single small error totally screws everything up. I'm reminded of my Japanese lesson this week, where Aya-sensei got completely confused when I talked about making 塩鮭 (shiozake, "Salted salmon"), because , "salmon," and , "alcohol," are pronounced exactly the same and I was talking about leaving it out on the counter to thaw, so she thought I had left three bottles of booze on the counter.

After those three hours lost to 0 and 1, I wish I had that booze on the counter. Emoji Picard facepalm

$Objectification

2018-Jun-27, Wednesday 08:57
dorchadas: (Office Space)
Last night after watching Porco Rosso (more on that later), I went back to do more coding practice and spent a while banging my head against this lesson on destructuring assignment.

It took me a while to even understand what the lesson was asking me to do, since a string is a string, right? Javascript treats a lot of things as objects (like functions), but what I forgot is that it treats string as objects (the String object; note capitalization) sometimes too, like when you write:
str.length
it very briefly treats the string as a object with a 'length' property which can be read.

And since I forgot, I googled the lesson and found this thread about it, with a lot of people pointing out perfectly reasonable things like "why not just use .length?" and "The lesson doesn't actually explain why you would want to do this or what benefit it has, especially based on what it requires you to do." There is a post that links to another post with real-world applications, so I do understand why destructuring is good. It's much easier to work with name than it is to work with clientList[currentRegion].clients[i].lastName. But while doing it to a string is supposed to be an easy operation to demonstrate how it works, I don't think it succeeds.

Tonight is the first Anime Chicago event I'm going to, a discussion about Porco Rosso. More on that after it happens.

I made an art!

2018-Jun-01, Friday 14:29
dorchadas: (Kirby Walk)
As part of an effort to get more practice with CSS, and after seeing this amazing portrait done with just CSS and HTML, I decided to try to make CSS art. Obviously, starting with something quite a bit simpler, though. Somewhere where you begin by drawing a circle.

Behold the Kirb.

I'm especially happy about the shading to give a 3D effect. It's not perfect, though--the border around the body cuts off the limbs, and I'd like to find a way to remove that if I can. That'll take a bit more effort, though, especially if I want to preserve the shading.

I'd also like to have a few buttons to press to make Kirby smile or move his arms. That'll be harder, but I don't think it'll be impossible.
dorchadas: (Kirby Walk)
I did not accomplish nearly as much as I wanted to this weekend, but isn't that always the case? Emoji Link swirly eyes

Friday was Starlight Radio Dreams, so I showed up, sat with [twitter.com profile] meowtima, and ate fish and chips while we watched the show. At intermission, [twitter.com profile] lisekatevans arrived fresh from her other show in time to perform in the second act, and [twitter.com profile] worldbshiny joined us at the table. The others left immediately after the performance ended, but [twitter.com profile] lisekatevans had brought friends visiting from Ohio, so she invited me to stay for a drink and chat with them afterwards. It was lovely, even when I got out after eleven and it was faster to walk four miles home than to wait for the bus. At least it was a lovely night for a walk, and I'm a fast walker.

Once again, I loved the episode of NPC, which this time dealt with a trap-filled maze dungeon. I've dealt with enough of those in the games I've played over the years.

Saturday I lost the whole day to playing Stellaris and was pretty disappointed with myself because of it. That hasn't happened for years and I had so many other things I wanted to accomplish--work more on the next coding challenge, read the first issue of Dill, clean the bathtub, finish up Hibike! Euphonium--and none of it got done. And in the end, I didn't even win! The ReapersContingency showed up as I was in the middle of building a stargate network and one of their Forge-Worlds was in the middle of Ayleid space on a crucial hyperlane chokepoint, so they wiped out my scattered fleets and started advancing on the homeworld. Emoji Commissar I gave up after that.

Sunday I started a new game, this time as a different kind of space elves, and again played longer than I wanted to, but I got presentable and headed out the door in time to make the performance of Prometheus Bound at the City Lit despite a bit of trouble finding the theatre. [twitter.com profile] lisekatevans had warned me that as Greek tragedy, the show would be a bit different than theatre I'm used to and that's not even counting that most of the characters were puppets. A lot of it was characters proclaiming to the audience rather than interacting, even in scenes where they were together on stage, which admittedly my love of kagura had conditioned me to expect. The puppet dancing as the chorus sang was less expected. I thought the person playing Prometheus and [twitter.com profile] lisekatevans (playing Io) did a very good job, especially considering they were the only humans on stage other than ninjas holding the puppets, and [twitter.com profile] lisekatevans said that the director told her that she should be concerned with the gadfly stinging Io and to stop looking at Prometheus. That must make it hard.
Kratos: "No one is absolutely free except for Zeus."
Hephaestus: "That is true."
Kratos: "Then get on with it!"
I had not previously realized that the main character of God of War was named after an actual Greek deity.

Afterwards, [twitter.com profile] lisekatevans invited me out to Ethiopian for dinner with some other people who had come to see the show. When dinner was done, two of the people peeled off to make the trpi back to Hyde Park past the Cubs game, but [twitter.com profile] lisekatevans, one other person, and me went to ice cream. But when we arrived, [twitter.com profile] lisekatevans looked at the time and realized her boyfriend would be in town earlier than she thought, so she excused herself. The other person and I ended up talking for two hours, and when she left to go to the beach she invited me along. We walked north to the terminus of the lakefront trail, then she went off to the beach and I went back to my apartment and stayed up too late reading.

Monday I set a hard limit on Stellaris playing and so actually got a lot done! The whole apartment is clean (except the bathtub...), sheets washed and laundry done, lunches made, food shopped for, and I thought of a way to rewrite part of my weather project so as not to have two separate methods of displaying the temperature depending on whether the page is first loaded or the temperature is toggled between C and F. If only I could have been that productive the whole weekend.

Short week ahead and nothing on the schedule unless that OneTable dinner I signed up for approves me (I have no idea why that one requires approval). Hopefully I can get more done this week, like figuring how to format a fetch() request...
dorchadas: (Not he who tells it)
Haven't had a great week and I'm not sure why. It might just be post-con blues, it might be something else. My therapist pointed out that seeking an immediately-proximate cause for something isn't always helpful, and she's right. It doesn't stop me from trying, though. Emoji embarrassed rub head

After watching the trailer for the Apocalypse expansion for Stellaris--it hit me right in the same place that the Earth Alliance president's speech Babylon 5's Battle of the Line does--I noticed that Stellaris was on sale and I immediately went out and bought it. I found a mod that allows space elves, so the Holy Ayleid Empire is currently expanding across the stars. I've only played for a couple hours so I don't have much of an opinion on it yet, but it seems fun. The people who told me to buy it were right.

I also finished another coding project! It's not super special, but I'm happy because I started breaking all the Javascript out into its own functions rather than trying to stuff everything into a single on-load function, which made it a lot easier to see what was going on. I also used a name-based track and CSS classes to dynamically change the backgrounds based on weather type and time of day with six lines of code and a bunch of CSS classes, rather than a giant switch statement or a massive if/else chain. Next time I'm going to see if I can do the whole thing without any JQuery at all. I should at least know how to write an XMLHttpRequest.

I just finished reading Locke & Key #1, after already reading Nutmeg #1 and Monstress #2 this month. I think the thing that always scared me away from Western comics is that 1) I'm neutral on superheroes as a concept and 2) I don't know where to start. With manga it's easy--start at the beginning. If I wanted to read about the X-men, where is the beginning? How much backstory am I missing? Listening to Jay & Miles X-plain the X-men especially makes me think that there are dozens of issues of backstory I'd need to appreciate what was going on, and that impression is always why I stayed away. But there are plenty of non-manga comics that follow a similar format, just like a lot of Western TV now has the same format as an anime series with a limited, self-contained run instead of just continuing until the money runs out or the creators get bored. I slept on Western comics for a long time, but I was just looking in the wrong places.

Tonight is another episode of Starlight Radio Dreams, so I'm going there later and getting fish and chips while I watch an episode of olde timey radio theatre. Other than that, I have no plans this weekend except maybe going to see Prometheus Bound on Sunday. Emoji Cute shrug Probably just stay in, play games, and study Japanese/coding. Maybe beat Shadowrun: Hong Kong and write about it. We'll see what else comes up.

Yrneavat gb Pbqr

2018-Apr-19, Thursday 14:57
dorchadas: (Broken Dream)
I just realized that I still have a Megatokyo icon in there. That demonstrates how long I've been posting on DW/LJ.

Post-Skyward Sword, I've returned to working more on the freeCodeCamp curriculum. Just today I finished the basic algorithms section, after many hours of banging my head against the wall. It's all simple stuff like adding multiple numbers, changing every element of an array, sorting a list numerically or alphabetically, splitting an array into piece (that one took a while), and so on.
Here's the code for my ROT13 encryption solution with comments removed:
function rot13(str) {
var answerStr = "";
for (var i = 0; i < str.length; i++) {
if (/[A-Z]/.test(str.charAt(i))) {
answerStr += String.fromCharCode((str.charCodeAt(i) % 26) + 65);
}
else {
answerStr += str.charAt(i);
}
}
return answerStr;
}

Here's how it works:
  1. takes in an uppercase string. It won't work for lowercase, for reasons I'll get to.
  2. Checks the string character by character. If it's not an alphabetic character--if it's a number, a space, punctuation, etc.--it just adds it to the answer.
  3. If it is an alphabetic character, it gets its HTML character code. For uppercase, this is between 65 and 90.
  4. It then modulos the answer by 26, which leaves a result between 0 and 25. This also converts it to the ROT13 equivalent. The character code for A is 65, but 65 % 26 is 13.
  5. Add 65 to the result of the previous equation, again giving each character a result of between 65 and 90. This is also why only uppercase works, since lowercase has character codes in a different range.
  6. Convert those character codes to the alphabet equivalent and add it to the answer.
  7. Repeat until the input is all processed.
I used to have a second If statement, where I'd add 13 to the character code unless it went over 90, in which case I'd subtract 13, but this implementation is cleaner.

And there are other ways to do it. When I finished I checked the thread for other solutions and saw a lot of people converted the string into an array and used the .map function to process each character and then .join to make an answer at the end. Some people wrote out an index, like var abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", and then used that to make the substitutions. One guy wrote a long multidimensinal array (var data = [["A", "N"], ["B", "O"], etc) and just swapped characters, which does technically work. One person wrote a 27-case switch statement. Emoji Smiling sweatdrop

Maybe that's what makes me interested in programming. In some ways it's like translation, taking a specific meaning and rendering into an understandable text, it's just that the text has to be understandable to computers. And much like learning a new human language, it requires creating a ton of garbage before anything worthwhile comes out. Emoji Oh dear

Next up is JSON and APIs, and then more dev projects. A random quote machine, the local weather (though the example for that project thinks I'm in Shuzenji in Shizuoka...), and a wikipedia viewer. I forsee a lot more banging my head against the wall.
dorchadas: (Default)
I made a thing! See here!
 
It's not very complicated and very late 90s web design, but I figured out how to make it myself. And now I'm working on a personal portfolio page here, though at the time I'm writing this, it's barely done. It took me a long time to implement the responsive menu at the top due to some leftover CSS from the first pre-Bootstrap version I made. It worked, but not on mobile, so I switched to Bootstrap and then spent hours trying to figure out why the links weren't justifying to the right. Turns out setting the contents of the navbar to inline-block means they're all grouped together. Oops.

I got my annual raise and bonus information yesterday and it’s higher than even my more optimistic projections. That’s good, considering. I’ll need the money. It’s not doing much to help my worried about spending, but every bit helps.
 
Tomorrow is the last part of the long-running Horror on the Orient Express game, and then Sunday my parents are coming to pick me up to go to the Orchid Show at the Chicago Botanic Garden, like we've gone for the past few years. Later that night, I'm having [twitter.com profile] lisekatevans and her roommate over for dinner to thank them for hosting me so often over the last month. This is the kind of weekend that previously would have made me dread the social engagement and the time in my schedule it took Emoji Oh dear, but...I'm looking forward to it. I'm amazed. I haven't looked forward to social events in a long time, even though I did enjoy them when I was there. I used to be much more social, and I'm not sure what changed other than getting older. Maybe that means I can work a change in myself and maintain this.
 
I do feel bad that I can't make the memorial for [livejournal.com profile] nytesenvy's father, though. The timing just doesn't work. Emoji Uncertain ~ face If the Orchid Show tickets were slightly later, I could stop in at the beginning...but I can't. And even though my attendance isn't expected, I feel guilty about that.

Alright. Off to a movie.
 
 
 

One step at a time

2018-Mar-10, Saturday 10:54
dorchadas: (Not he who tells it)
One foot after the other, one day at a time.

Yesterday afternoon, [twitter.com profile] pinandstutter invited me over play games and maybe go out for a drink after work. This is the kind of thing I would have just turned down out of hand previously, but that obviously wasn't serving me well, so I accepted. After a bit of wandering around trying to find the Washington Blue Line entrance--not something I typically have to worry about--and took it out to [twitter.com profile] pinandstutter's place. He's lived there for years, but apparently I've never been there before, so I got the tour and then we and [twitter.com profile] kelachris sat down to play Rock, Paper, Wizard, one of the many D&D-branded adjacent materials. A game takes about ten minutes and mostly consists of making hand gestures at each other, representing a group of wizards blasting each other with spells as they all run down a corridor trying to get to the treasure on the other end, knocking each other around, stealing gold, and otherwise causing mayhem. Emoji Hell Yeah Shock Cannon

The best part were the wild surges. Spells are cast from a pool equal to the number of players, and if two players cast the same spell on each other, the spells go wild and they draw random spells from the deck to cast. With only three players, this happened a lot, making the game hard to strategize for but certainly a lot of fun.

One the person we were waiting for arrived, we left and walked back toward the Blue Line to go to The Violet Hour, which I had never previously heard of. It has assigned seats like a restaurant, which kept the noise level lower and allowed us to actually talk to each other as we sank into the blue leather chairs, drank our dranks, and ate the fries and roasted chickpeas we ordered. I ordered a Riviera and took an artistic photo to commemorate the atmosphere:

2018-03-09 - Violet Hour drink

After one drink and some food, I followed everyone along as they stopped at Taco Bell for real ("real") food and then took the bus back north, went home, and fell asleep pretty early.

This morning, I made an account over at freeCodeCamp. I took a programming class back in 2013, but in retrospect there were two major problems, one with it and one with me. The problem with me is that I just let everything lapse once the class finished and never tried to expand my knowledge base using what the course had taught me, which is a huge failing on my part. If I had been doing that for the last four-and-a-half years, who knows where I would be now? The problem with it is that I was a bit dubious of the class when it turned out that they were using global variables to teach despite admitting that actually using global variables when programming is often a bad idea and should generally not be the first solution.

Well, I can't change the past, but I can work on the future.Emoji The Solar Exalted

2013 Retrospective

2014-Jan-01, Wednesday 22:31
dorchadas: (Default)
Let's talk about the last year!

I guess the biggest change from the perspective of this blog is that I started actually posting here again. I got inspired by RPGs--as is often the case, I admit--and started my Dungeons & Design series, and I think it was mostly the fact of posting those that got me into the habit of posting about other subjects. There are other factors too, like how I have enough down time here and there at work that I can write posts in notepad, send them home, and then post them. I also stopped friend-locking everything and started defaulting to public posts, even when they're about my life. It's essentially security through apathy--I can see how many people visit my blog, and on an average day it's a couple dozen. I post all these updates to Facebook and Twitter and the truth is that most people don't care. That may be a little sad, but it certainly tells me that the excessive care I was taking about talking about anything remotely personal is unwarranted. Whatever I say will mostly just get lost in the flow of the internet anyway, unless people are specifically looking to read it.

I was hoping that we'd be paid back by at least one of the people who owed us money this year, but it didn't happen. Aggressively didn't happen, in the case of the Japanese Pension Office. Or perhaps passive-aggressively? Regardless, it led to some tight moments at times, especially during the summer, though I do admit that some of that is because I refuse to touch the principal. Now that [personal profile] schoolpsychnerd has a steady paycheck from her internship everything is okay, though I admit my grasping miserliness does mean I'm less happy with our finances that their absolute quality should lead me to be, but overall it's been on an upward trend. And maybe someone will actually pay us this year. A man can dream.

Work continues much the same as it has been. I had my annual review and did better than I did last year, and my job's bureaucracy and policies means that I'll get an automatic raise and a yearly bonus commensurate with my performance. It's theoretically possible that we won't get the bonus, since the amount and whether it occurs at all is based on the AMA's overall performance during the year, but I haven't heard of anything that would indicate that it's not coming. Even if it doesn't, I'll still get the raise. The benefits of working for a non-profit with no shareholders!

In terms of personal improvement, I took up programming! I originally thought about doing it back in May and was given a lot of resources, and later took a Coursera course that I wrote all about. I've even seen found an implementation of Python for the iPad, and since I have my iPad with me all the time at work, I can get that and then have time to bash my head against programs at work as well as at home! Indeed, during my interview for the job I was asked if I knew anything about HTML or programming and I had to say that I did not, so if I can actually learn programming to a useful level I can hopefully get a promotion. The end project was an implementation of Asteroids, and I'd love to do a lot more to work on it than I had to do for the class to keep my hand in, but what I did accomplish is reasonably impressive, I think.

Also, studied Japanese, but on that subject I'm less confident. I maintained my ability, and that's about it.

Last year, I told myself that if I maintained the weight I had reached in August (~77 kg) for a whole year, I'd go get my wedding ring resized because it's rather large now and I'm kind of worried that it will slip off at some point. Well...I did maintain my weight, but I didn't actually get the ring resized--see the above-mentioned grasping miserliness. I also linked up my new iPhone's M7 chip with LoseIt and started tracking my steps and apparently my average number of steps per day is...5,218. Out of the 10K that's recommended. Exercise is healthy basically no matter what, and getting that number up is something I'd like to improve on in the future, but so far I'm doing pretty well on that front.

I made much more of an effort to be social in 2013. In 2012, I think I had the tendency to hermit a lot more, turning down people's invitations and not really inviting anyone over to [personal profile] schoolpsychnerd and my apartment. I'm not sure what exactly it was. It might have been some remaining difficulty with adjusting to the pace of social life in America vs. what it had been like in Japan, maybe some Anxiety Cat--there's a really old one that I thought fit me really well that said something like "too nervous to talk to people, come off as arrogant or standoffish"--maybe just my typical introverted personality, but this year I tried to avoid falling into the trap of staying home all the time. I like to think I succeeded, or at least reasonably well. And it turns out that traveling out to other places isn't really that bad, even on a work night. I tend to apply the maxim "past performance is no indication of future results" to social events if I'm not careful, in the sense that sure I had fun the last time I went to a party, and the time before that, and probably the time before that...but what about this time!?!? That's not a productive attitude to take, honestly. So this year, I made sure to try to shut that off at the pass. Once I get out of the house, then inertia takes over and I'm not exactly going to turn around halfway there. And it turns out that my friends are awesome people and fun to be around to an extent that far outweighs the annoyance of having to change my physical location. Who would have thought, right? Obviously, this has always been true, but it's convincing that little voice that's the trick, and in 2013 I beat it into submission. Or at least, I inflicted grevious wounds.

All in all, it's been a pretty fantastic year, and I'm looking forward to what 2014 will bring.

I realize that posting song lyrics is incredibly emo and so early-2000s as to be aggressively unhip, but it's pseudo-tradition for me, so:

A long December and there's reason to believe
Maybe this year will be better than the last
I can't remember the last thing that you said as you were leavin'
Now the days go by so fast
And it's one more day up in the canyons
And it's one more night in Hollywood
If you think that I could be forgiven...I wish you would
The smell of hospitals in winter
And the feeling that it's all a lot of oysters, but no pearls
All at once you look across a crowded room
To see the way that light attaches to a girl
And it's one more day up in the canyons
And it's one more night in Hollywood
If you think you might come to California...I think you should
Drove up to Hillside Manor sometime after two a.m.
And talked a little while about the year
I guess the winter makes you laugh a little slower,
Makes you talk a little lower about the things you could not show her
And it's been a long December and there's reason to believe
Maybe this year will be better than the last
I can't remember all the times I tried to tell my myself
To hold on to these moments as they pass
And it's one more day up in the canyon
And it's one more night in Hollywood
It's been so long since I've seen the ocean...I guess I should...
dorchadas: (Dreams are older)
Well, that's finished, then. You can play my final project in the form I submitted it here--click the arrow in the upper left to start the game.

In some ways, the fears I expressed in previous posts were correct. A lot of the syntax we learned dealt with the specific implementation of Python that was used for the class that is not going to be the same anywhere else. Ways to load images, and take in mouse clicks and keyboard commands, and implement elements of the GUI, and so on. It's possible that they're similar to some kind of standard interpretation, but if so, I have no idea because we didn't learn about that. But programming isn't all just memorizing specific commands. It's more about learning ways of thinking and problem-solving skills that you can transfer over into any other programming language other than the one you started learning on, though this is obviously more or less difficult depending on the construction of the particular language.

I did run into some fun moments when I was developing this:



That was how it looked after I implemented multiple asteroids spawning and multiple missiles firing, but before I included anything about collisions. I messed around with it not just for the picture, but also to see if it was possible to have so many objects on the screen at one time that the game crashed, which it didn't. It did suffer from a lot of slowdown, which you'll also see if you try to play the finished version, but fixing that is one of the things I want to mess with now that the actual course is done. Right now it checks for collisions 60 times a second and it doesn't take position into account at all so it checks the entire screen every time even if there's only two objects on opposite ends of the screen. Hacking that down to maybe 4 times a second would probably make it work a lot better. See, an increasing number of objects becomes geometrically more intensive, because each object has to check for collision with everything already there, and everything already there has to check collision with it. Doing that when there's 12 asteroids and a ship and a few missiles and it's all being done through a browser-based code implementation which already slows everything down anyway is overkill.

On a further subject, look at the explosions in the game above. They weren't required as part of the assignment, but they were listed as a bonus step if we felt like we would be able to implement them, and I figured I'd give it a try. It only took about 15 minutes and was pretty easy. It was just loading the game, shooting things, getting an error message, fixing that, repeat until I finally didn't get any error messages. It was pretty much the perfect ideal of what bug-fixing should be like. Though once it worked, the explosion graphic was cycling through the various frames way too quickly and in the wrong location for the sprites, so that had to be fixed, but that just required checking how big the sprite was to make sure that I would cycle through to the next frame properly.

There's still more I want to do now, for my own personal improvement. Make the playing area bigger and the ship and missiles smaller. Maybe add powerups, that make missiles go further, or that shoot out two or three missiles with each press of the fire button, or a shield that blocks a single hit. A limited teleport that moves the ship elsewhere. Make the asteroids only spawn near the edge of the screen and drift toward the center instead of randomly appearing out of nowhere. Porting it over to regular Python instead of Codeskulptor's version of it.

Would I recommend this class? Not really. Even for a free class, I think it focused far too much on the idiosyncrasies of the class's specific implementation of Python and had several lazy practices, like the use of global variables because the GUI can't handle input any other way. That's not to say that I thought it was worthless, because it wasn't, but there are a bunch of other free sources for learning programming if, like me, you're cheapassunwilling to spend money.

Profile

dorchadas: (Default)
dorchadas

May 2025

M T W T F S S
   1 234
5 67 891011
1213 14151617 18
19 202122232425
262728 29 3031 

Syndicate

RSS Atom