Retrospective, by the numbers
- Started 2024-11-07 8:25, ended 2024-11-20 23:17. 14 days calendar time.
- Github: 243 commits, ~17.4 commits per day.
- Tasks: 175 tasks created and resolved, of which 23 were triaged, so ~10.9 tasks completed per day.
- 64 sprites imported, 56 objects defined, 3 music tracks used, 9 sound effects captured from my cat.
- 130 art asset packs browsed, 9 used (and credited).
- filter-data notes: 4798 lines in coding.md (mostly old), 2631 lines in gamemaker.md (mostly new)
- Obsidian notes: 4765 lines (mostly old)
- According to FitBit, 6h26m avg sleep per day (felt like less).
v.1.0.0 completed, published, game jam done
I've completed v.1.0.0, the Minimum Viable Product, and published it to itch.io. I've resolved the last of the issues in Jira. This marks the end of the development sprint.
Unlike the last game jam where I was happy with my effort even if I wasn't happy with the end product, this time I feel good about the end product too. The simple mechanics means higher skill will get higher scores but there's enough randomness to allow replayability. The sessions are quick, you can see how many points you can accumulate in 1 minute or you can see how many you can get by prolonging the game with trips to the water fountain.
The music feels like a good match. The meow and purr sound effects sound nice (to me). The graphics are much smoother and more varied than my first game jam, thanks to my custom asset-gallery tool for navigating asset packs.
The technical accomplishments of this game are much greater than my previous. I've a moving viewport that scales with browser resizing, has both text and image overlays, and a scrolling text box for the credits/licenses. I'm simulating 3D space on a 2D plane. I'll write up a more detailed retrospective after catching up on sleep.
1 hour 46 min, 2 tasks remain
I've drafted the itch.io page and tested my HTML5 deploymet there, it performs as well as on my own servers. I thought I had enough time to do some revision of the scoring even though on a professional project I'd have locked down the feature changes while close to deadline. I managed to get these changes done and I think it'll greatly increase the playability of the game.
The points earned from picking up and dropping an item will be increased both by the distance the item is carried and the height the item is carried. Pick up an item from the left of the room and carry it to the right, jumping off furniture on the way, and earn many points. This encourages players to explore and move more instead of camping the same items in the same spots. The mouse is also harder to catch because it'll become invisible while on it's cooldown timer, but it's still worth many points so good to chase when it appears.
I'm doing final testing runs now, then I'll cut v.1.0.0 and release it.
5 hours, 8 tasks remain
I've added more objects to the game space to platform off and interact with. HTML5 testing revealed a bug that doesn't show up in windows versions, namely that picked-up item sprites clip through the player sprite when moving downward. I'm glad to have put HTML5 testing in the schedule and surprised by how many issues arise specific to the web-based version.
10 hours, 12 tasks remain
I spent more time on the scrolling text box. alpha testing v.0.4 revealed it wouldn't resize properly when the browser window resized. Fixed now, but it was frustrating. That was the last major feature. The remaining tasks are refinement, testing, and final deployment. I've a list of good ideas for future improvements but I'm not going to risk a clean build by squeezing them in now.
Credits
If delivering executables, I'd distribute the license as a README file. Since this is web-based I wanted to build the full credits into the game. I've created a scrollable text box that can be toggled on the Game Over page with a key press.
I had it working well in a sandbox but when I migrated it to the main project I hit problems with scaling since my different screens have different underlying resolutions. I probably spent too long fiddling with it, given there are only 11 hours left in this sprint.
Special Thanks To...
- Quinn for her patience and support
- Alice for the clever title, Milky's Way
- Thor and Pirate Software for inspiring game developers
11/20 status, 18 hours, 16 tasks remain
I planned compartmentalized tasks such that those most likely to be triaged received little up-front effort and cutting them would throw away the least work. The triage went well and I think the remaining tasks can be accomplished within the time frame and result in a polished Minimum Viable Product. The biggest sunk cost was laying out the bedroom and kitchen tiles and trying to implement the kitchen furniture, which resulted in maybe six hours of lost dev time when I cut both zones from the game. I triaged 23 of 175 tasks and threw away maybe 10 hours dev time, which is pretty good considering all the non-jam emergency stuff that came up this past week.
Mostly refinement at this point. I need a display for special thanks text. I want to populate the room with more items. I need to test test test.
16 unresolved tasks carried over, 12 resolved yesterday, 5 triaged.
Triaged kitchen and bedroom
There's an issue with some of my sprites clipping through other sprites, I think related to my z-axis calculations for jumping and simulating 3d depth. I expect this to take non-trivial debugging so I've triaged the kitchen and bedroom from the game, leaving the living room as the game space. Better to have a small smooth zone than a large janky one. 33 hours remaining.
11/19 status and triage
Awoke at 6:13 to spend the morning triaging issues I'm confident I won't have time for. I cut 18, mostly around refining the art, creating a trailer video, and writing the retrospective. I can do the retrospective after the jam completes. There are 33 issues remaining, which will be tight to finish in the 38 hours until midnight tomorrow. Some of these issues are short and bundled, others have a lot of uncertainty. I'll push hard and see what comes of it.
Yesterday felt productive, just not productive enough. I found furniture sprites for the living room and kitchen and put them in the level, setting the initial collision physics for them. Early testing reveals issues in the logic causing sprites to clip through each other, which I'll need to either sort out with more precise calculations or shortcut by making the objects unclimbable. I need to finish all the art adjustments today, including populating the bedroom, so I'll have time to refine gameplay.
33 unresolved tasks carried over, 10 resolved yesterday, 18 triaged.
v.0.2.0 completed
New pixel art font. Title screen with music and pixel text. Controls screen with music and pixel text. Pause functionality in game, showing control help. Game Over screen with music and pixel text, ENTER to restart game. Heads Up Display text will resize correctly when browser window resized. Music will start/restart correctly if game window loses focus in HTML5.
GameMaker rooms, views, and GUI sizing [FIXED]
Overview of the fix:
I have a persistent obj_camera that, every step, checks if the game is running in a browser and if so, checks if the browser window has resized. If the window has resized, we calculate a windowScale, being the minimum of the browser_width/camWidth and browser_height/camHeight (i.e. our view will keep the same ratio, so we want to find the multiple to apply to all the GUI rendering).
I have a script that handles my text drawing, taking in params for buffer margins and text scaling. The params are multiplied by the windowScale, and the width and height of the active screen area where the GUI will be rendered are the view_camera*windowScale. view_camera doesn't change dimensions as the browser window is resized, but windowScale will.
The text-drawing script is called from within the "Draw GUI" step of objects so the drawn elements remain anchored to the screen and not to the world being viewed through the screen (which is what would happen if calling from the "Draw" step). Note the "Draw GUI" and "Draw" steps have different scales so the params you'd send through one won't match the params you'd send through the other (i.e. you'd need to tailor them separately).
GameMaker rooms, views, and GUI sizing
TL;DR: I was drawing to GUI dimensions and the text became misplaced when displayed in a web browser with different height-to-width ratios.
I've struggled with view resolutions in GameMaker, which has multiple layers that can have different sizes, some of which are resized when run in a browser as HTML5. I was drawing the info screen text to the GUI dimensions, and it looked good when run as a Windows app and looked fine when run in a browser that happened to have similar dimensions. But testing in a browser revealed the GUI dimensions changed with browser window size and sometimes caused the "center" of the screen to be outside the window, hiding much of the text.
To fix this I'll draw to the view dimensions instead, which are set in the code and don't change when the browser is resized. Because the GUI dimensions were different from the view dimensions, I'll need to recalibrate all of my font sizes and margins. Note that these are not the room dimensions, which are a third set of dimensions and are tied to the in-game world.
11/18 status
Yesterday was a good day. It felt like a lot of progress (all 3 info screens done, with pixel text) but still only 15 tasks resolved. I've accepted that I'll have to simplify many of my remaining tasks to fit time, and I'm keeping a mind open to triage tasks I come across that I don't think I'll have time for (like adding keyboard icons to explain the controls).
Still some debugging to complete v.0.2.0, alpha testing shows it's not resizing the info screens correctly when deployed as HTML5 (because we adjust based on browser size). The main push for today is level design, filling space with more interactable objects.
61 unresolved tasks carried over, 15 tasks resolved
Music not starting [FIXED]
TL;DR: It *was* timing-based.
Browsers suspend the audio engine at start and for events like inactivity or moving focus to a different tab. It takes a few steps before a user gesture on the browser page resets the "Audio Engine => Running" and we can play sound. I reworked my music controls to periodically check if engine running, then trigger check for sound playing, then restart music track if false or don't interrupt if true.
Music not starting
My first heisenbug of the sprint. "A heisenbug is a software bug that seems to disappear or alter its behavior when one attempts to study it."
When the game is deployed as HTML5, browsers won't play sound until the game is interacted with. This is intended behavior for the browser and a limitation for GameMaker. If we trigger the music before we get an interaction, such as trying to start the music as soon as the game loads, the music won't play but GameMaker will return true on checks for whether it is playing (in which case our logic says don't play if already playing).
GameMaker has a function that is supposed to return true if we *can* play sound, so I'm checking if we can play before checking if we're already playing before trying to start playing. When I have show_debug_message calls in the code, it works as intended. When I remove the debug messages, the music is no longer triggered correctly.
My current guess is that the debug messages are introducing a delay and the current issue is actually timing-based.
11/17 status
Yesterday was productive, but with the image corruption bug stealing a couple hours and the integration of sandbox code back into the main branch taking a lot more effort than expected, it wasn't a "good" day. The next batch of tasks is the creation of title, controls, and game-over screens. This is where my pickiness in the art will dictate how much time the tasks take, since mechanically they mostly aren't complicated. I can catch up on some lost time here.
76 unresolved tasks carried over, 11 tasks resolved yesterday, 1 unplanned task.
Git corrupting images
If you edit a sprite in GameMaker, there is no "undo" option to revert the changes. If you then save your GameMaker project (which auto-saves on game execute), some edits will show up as repo diffs. If you revert those repo diffs, the image files associated with the sprites become corrupted and don't register as changed with git, so now your sprites look empty and the repo isn't registering any changes.
Further experimentation revealed the problem is more widespread. I cloned the last good version and immediately git registers a bunch of changes to the .png files, even without having opened the project in GameMaker. I attempted to revert all changes but they show up again immediately in GitHub Desktop, without any chance to revert to an earlier commit.
It looks like this is an issue with "* text eol=lf" in .gitattributes affecting binary files, corrupting them. I've removed the offending line from all projects but I'll need to verify their integrity and reload corrupted images from the original sources.
11/16 status
I have a lot of catching up to do. After planning, much of my efforts yesterday were around reviewing reference materials and tutorials and I didn't resolve many tasks. For me to make the deadline, today and tomorrow *must* be productive.
86 unresolved tasks carried over, 5 tasks resolved yesterday.
11/15 planning
Now that I've done enough prototyping to establish reasonable expectations for what I can accomplish in the given time frame, I've spent the morning setting Minimum Viable Product scope and planning the remaining tasks to v.1.0.
On larger projects I'd do effort estimation and make a burndown chart, but the shortness of this game jam means I'll have to eyeball the rate of task completion and guess when to triage. After planning it out, I feel it'll be a really tight schedule.
4 unresolved tasks carried over, 6 tasks resolved since last planning, 83 new tasks planned.
11/15 status
I tried fixing the shadows yesterday so they projected onto objects and platforms and didn't create darker overlaps but it turns out there's a significant complexity jump between what I have and what I want. To get the shadows I want, and other effects to make the game look more 3D, I need "shaders", and according to the GameMaker manual "They are also among the most advanced features offered by GameMaker".
So I'm moving shadows to the backlog and re-focusing on gameplay. I need more surfaces to platform off and a lot more testing/tuning of the platforming physics. With only six days left in the sprint, I consider platforming the last *major* feature for Minimum Viable Product. I still need an updated visual interface, asset editing to reflect my real cat's appearance, and significantly more level design.
11/13 planning
Processed the backlog of all bugs and minor fixes, leaving only the large tasks intended for future versions. Movement has been smoothed, sound cue overlap and triggering made more consistent, and a background music track added. I've glanced through some tutorials on making platform games and intend to do some prototyping in sandboxes today before committing to adding this functionality, at which point I'll probably do another planning session.
2 unresolved tasks carried over, 10 tasks resolved since last planning, 3 unplanned tasks created, 5 new tasks planned.
11/12 planning
I'm still a few versions away from minimum viable product (MVP), but development velocity is good and I anticipate MVP completion with time to spare for refinement. No new issues planned, I have enough in the backlog to fill out the next version. I'm looking into adding jumping and platforming elements.
9 unresolved tasks carried over, 14 tasks resolved since last planning, 6 unplanned tasks created, 0 new tasks planned.
v.0.0.5 completed
Purr and meow sounds added to the game to accompany visual cues (thought bubbles). More thought bubbles for interactions. Exclamation bubble when trying to interact without an object. Question bubble when close to an object that can be interacted with. Game over message and restart prompt.
Audacity sound editor
Audacity is a free audio editor and recorder that can export to different formats. I've used it mostly for voice recording and cutting sections of audio, for which it has a very user-friendly interface. It also has many effects, generators, analyzers, and tools that I've not used, but would probably help in the production of music.
11/11 planning
I'm going to start sound design. I've been recording Milqqie on my phone and want to get meow and purr sounds into the game. I'll spend at least a little time looking for appropriately-licensed soft background music. I'll also spend some time on level design instead of a mostly-empty rectangular room.
8 unresolved tasks carried over, 11 tasks resolved since last planning, 6 unplanned tasks created yesterday, 9 new tasks planned.
v.0.0.4 completed
Score counter displayed and score increased when catch mouse or play with toy. Toys each require a delay between being set down and being picked up again, including a visual bubble cue when too early. Milky can get tired and take a nap, ending the game (currently set if he's thirsty for too long, but will change the trigger later).
filter-data
filter-data is a private TypeScript project I use for filtering through large volumes of notes and bookmarks. I accumulate writings in a markdown file, load it to the browser for parsing into articles based on keywords, then filter the articles using custom tags and tag groups. Tags and groups don't need predefinition, just add them to the markdown with a keyword.
It's a very low-friction system and helps me rediscover information when I've forgotten the specifics but remember enough to identify general topics. E.g. "What was that code example for creating sprite boxes in GameMaker? Let's check the articles with 'code_example' and 'sprite' tags."
Notepad++ text editor with syntax highlighting
Notepad++ is a free text editor with code syntax highlighting. Support for GameMaker Language (GML) can be added as a "User Defined Language" for *.gml files by following the instructions at yal.cc (link below). It's a simpler editor than VSCode and I use it for keeping code snippets in temporary scratchpads in windows on my secondary/tertiary monitors.
11/10 planning
Most of the effort yesterday went to writing scripts, updating tools, and dependency debugging. Not what I had originally intended to spend that time on, but it's important to create efficient processes early as the game design and programming implementation gets more complicated.
There is still some tool work for today, but I think I'll make it back to the original game development tasks by noon. My working hours have slipped into the early AM so Jira's graphs will show dramatic swings for issues created and resolved between days.
13 unresolved tasks carried over, 6 tasks resolved yesterday, 6 unexpected tasks created yesterday, no new tasks planned.
Backblaze cloud storage backup
I've used Backblaze for personal data backup for years and highly recommend it. The app automatically scans for file changes and can cover the entire computer plus external USB drives with unlimited data storage for $100/year, compared to the ~$210 Google Cloud storage would cost me to save ~7TB of data at their cheapest Archive level. Additionally, Backblaze has client-side encryption.
Dropbox file sharing
On personal projects I do most development on a Windows desktop PC, but I use a Windows laptop on travel or for multi-machine testing. Sometimes I collaborate with other developers. I've not encountered any problems placing an Obsidian vault in Dropbox for auto-updated replication between multiple endpoints, Obsidian's plain text markdown uses little space and is easily auto-merged.
I've tried using the Google Drive desktop app but it too frequently failed to merge file versions correctly, instead creating many copies of the same files.
Obsidian text editor
Obsidian is a free text editor using markdown files as data storage and formatting, with convenient cross-note linking and useful data processing plugins. This is the tool I graduate to when my initial Google Doc becomes cluttered. Obsidian allows me to split and organize notes into directory structures without losing any search functionality and keeping a separate Obsidian vault for each project, IDE, or programming language helps me context switch. Obsidian also supports code block syntax highlighting, an advantage over Google Docs.
11/09 planning
The movement and interactivity are a good enough proof-of-concept for playtesting, now to gamify it. We need a score for players to measure progress and a depleting resource to trigger an end-game state.
5 unresolved tasks carried over, 17 tasks resolved since last planning, 8 new tasks planned.
v.0.0.3 completed
Thought bubbles reveal Milky's reactions. Milky grows thirsty over time and can interact with a water bowl. Furniture blocks movement and must be maneuvered around (collision masks adjusted). The mouse can be interacted with to pause its movement. Toys can be picked up, carried, and set down.
11/08 planning
I've only 3 incomplete tasks so I'm spending time planning the next phase, which should be more environment interactivity. Pick up the mouse if the player hits the spacebar with the cat overlapping. Furniture objects to block movement. A water dish object the player can interact with.
I've created 12 new tasks in Jira.
I've just about hit the limits of my previous game programming experience so I expect further coding tasks to take longer as I figure out how to implement them.
v.0.0.2 completed
Room created with tiled images and collision-bounded edges. Player controls cat movement, bounded by room size. Mouse object automatically follows or flees from cat based on proximity, bounded by room size. Camera follows player, bounded by room size. Both cat and mouse objects have two states, idle and walk. They switch sprites based on state and flip sprite based on facing. All DONE Kanban issues in Jira cleared on every version release.
asset-gallery
asset-gallery is a private TypeScript project I created (prior to this game jam) to make image galleries from recursively scanned directories, allowing me to navigate downloaded asset packs easily.
I spent significant time during my previous game jam looking for specific sprites, my tool should save double-digit hours during this sprint.
GameDev Market game assets
GameDev Market offers free and paid game assets with no restrictions on use in commercial projects. I've purchased several of their asset packs through HumbleBundle deals, and have downloaded many of their free assets. To comply with the game jam restrictions, I won't be purchasing any new asset packs for this sprint.
Every asset pack I use will be listed in the game's README file alongside the related license.
CraftPix game assets
CraftPix offers free and premium game assets with no restrictions on use in commercial projects. I've found it extremely helpful for both single sprites or themed sets. To comply with the game jam restrictions, I won't be purchasing any new asset packs for this sprint.
Every asset pack I use will be listed in the game's README file alongside the related license.
GameMaker (engine)
I'm using the free version of GameMaker (v.2024.8.1.171) as my game engine. I've used it in a past Game Jam and am more comfortable with it than any other game engine. It handles the type of 2D side-scroller I'm making and can be configured to deploy as HTML5 or Windows executables fairly easily. I'm programming in the "GML Code" language.
Kanban task management in Jira
Store and organize information on bugs and tasks, particularly priority, dependencies, and which issues are currently being worked on. It's very important to have a place to dump information when encountering something unexpected and not wanting to lose concentration on the current work to address it. Jira's burndown dashboards are a pleasant bonus.
NOTE: The Jira mobile app isn't working on my Android and I can't access the website from mobile (redirects to app).
Staged rollouts
Prior to this game jam, I've set up separate development, demonstration, and production deployment targets for my personal projects that are web-based. I've made a private website to track the versions in each environment, with links to the corresponding GitHub repos. FileZilla and scripting is used to push the compiled files.
Discord
Discord is a useful free tool for low-friction timestamped journaling across desktop and mobile devices. I've created a text channel for my friends to follow my live status updates and thoughts while doing the game jam, and a separate text channel for me to do rubber duck programming (i.e. screaming into the void).
Game Jam Start
The Challenge: As a solo developer, create a game within 14 consecutive days (11/7 through 11/20). The theme is "pets".
Restrictions:
- The game must be accessible via web browser, though it does not need to be mobile-friendly.
- No Machine-Learning-generated content.
- Only use assets you have the commercial license for and no purchasing additional assets after jam start.
My game is going to be a 2D side-scroller called "Milky's Way", where you control my cat to make mischief.