added lots of articles; articles are released at midnight server-time; bug fixes

small-nav
chimchooree 4 years ago
parent 950a76371f
commit 4a663dc10e

@ -1,7 +1,7 @@
<!--200918--> <!--200918-->
<h1>what is blessfrey? </h1> <h1>what is blessfrey? </h1>
august 10, 2020<br> august 6, 2020<br>
pitch<br> #pitch<br>
<br> <br>
<b>Blessfrey</b> is a 2D action RPG developed for PC by me, chimchooree. <br> <b>Blessfrey</b> is a 2D action RPG developed for PC by me, chimchooree. <br>
<br> <br>

@ -1,7 +1,7 @@
<!--200810--> <!--200810-->
<h1>free pixel font </h1> <h1>free pixel font </h1>
august 17, 2020<br> august 20, 2020<br>
assets<br> #assets<br>
<br> <br>
<b><a href="https://fontstruct.com/fontstructions/show/1596262/pixel-joy">pixel joy</a></b> is a small, round sans-serif pixel font, made using <a href="https://fontstruct.com/">fontstruct's FontStructor</a> for an old version of blessfrey. Freely use and edit for your personal and commercial projects. No credit needed. <br> <b><a href="https://fontstruct.com/fontstructions/show/1596262/pixel-joy">pixel joy</a></b> is a small, round sans-serif pixel font, made using <a href="https://fontstruct.com/">fontstruct's FontStructor</a> for an old version of blessfrey. Freely use and edit for your personal and commercial projects. No credit needed. <br>
<br> <br>

@ -44,27 +44,12 @@ apache, css, html, nginx, php, server, website<br>
<li>studied PHP with <a href="https://www.w3schools.com/php/php_intro.asp">W3Schools</a></li> <li>studied PHP with <a href="https://www.w3schools.com/php/php_intro.asp">W3Schools</a></li>
</ul> </ul>
<br> <br>
<h2>wednesday, august 12</h2>
<ul>
<li>J met his old co-worker, and he wanted to see my website. Oops. I don't have one yet...</li>
</ul>
<br>
<h2>friday, august 14</h2>
<ul>
<li>I'm getting more popular with J's friends. Happy.</li>
</ul>
<br>
<h2>saturday, august 15</h2> <h2>saturday, august 15</h2>
<ul> <ul>
<li>Made a Python script that spits out new skill scenes for Godot after answering a little command line questionnaire. I could make it an add-on for the engine, but it would be a lot slower to develop and functionally no better.</li> <li>Made a Python script that spits out new skill scenes for Godot after answering a little command line questionnaire. I could make it an add-on for the engine, but it would be a lot slower to develop and functionally no better.</li>
<li>Maybe I can rewrite it later in JSON, since Godot can read JSON.</li> <li>Maybe I can rewrite it later in JSON, since Godot can read JSON.</li>
</ul> </ul>
<br> <br>
<h2>sunday, august 16</h2>
<ul>
<li>First time attending for a conquest. Flameforger's is next week. Go Fire!</li>
</ul>
<br>
<h2>monday, august 17</h2> <h2>monday, august 17</h2>
<ul> <ul>
<li>Research PHP + MySQL while attending. I think MySQL is overkill for my purposes, since all my articles couldn't possibly be that much data. It might be interesting for analyzing data, though, like adding a word cloud of the most common tags or a search feature.</li> <li>Research PHP + MySQL while attending. I think MySQL is overkill for my purposes, since all my articles couldn't possibly be that much data. It might be interesting for analyzing data, though, like adding a word cloud of the most common tags or a search feature.</li>
@ -73,7 +58,7 @@ apache, css, html, nginx, php, server, website<br>
<h2>august 18 - august 21</h2> <h2>august 18 - august 21</h2>
<ul> <ul>
<li>Attend for the Fire Flight while trying out a new mmo - ArcheAge, since my friends play it.</li> <li>Attend for the Fire Flight while trying out a new mmo - ArcheAge, since my friends play it.</li>
<li>I told a friend I would play Go with him soon but was too busy with the raffle. Then someone told him I was online all the time in ArcheAge...oops...that looked bad lol. It wasn't like I played more than a few minutes at a time until the late evening.</li> <li>I told a friend I would play Go with him soon but was too busy with the raffle. Then someone told him I was online a lot in ArcheAge...oops...that looked bad lol. It wasn't like I played more than a few minutes at a time.</li>
<li>finally get access to the code for an mmo some friends work on. I start familiarizing myself with the code and start planning my new feature.</li> <li>finally get access to the code for an mmo some friends work on. I start familiarizing myself with the code and start planning my new feature.</li>
</ul> </ul>
<br> <br>
@ -84,7 +69,7 @@ apache, css, html, nginx, php, server, website<br>
<br> <br>
<h2>sunday, august 23</h2> <h2>sunday, august 23</h2>
<ul> <ul>
<li>I work on my friends' mmo more. I make my own branch and make my first changes. The work environment is Windows-only, and the server is live with active players - lots of new problems for me, but really interesting experience. </li> <li>I work on my friends' mmo more. I make my own branch and make my first changes. The work environment is Windows-only, and the server is live with active players. </li>
</ul> </ul>
<br> <br>
<h2>monday, august 24</h2> <h2>monday, august 24</h2>

@ -1,6 +1,6 @@
<!--200810--> <!--200810-->
<h1>my first game jam - #weeklygamejam </h1> <h1>my first game jam - #weeklygamejam </h1>
august 24, 2020<br> september 3, 2020<br>
game jam<br> game jam<br>
<br> <br>
<b><a href="https://weeklygamejam.itch.io/">WeeklyGameJam</a></b> is weekly theme-based game jam hosted through itch.io. It's fairly laid-back for a jam, giving you a full week's time, allowing for pre-made/stock assets and code, and being understanding of late submissions. Most people make videogames, but any kind of game is allowed. At the end of the week, streamers will play and critique the submissions while the devs hang out in their chat. <br> <b><a href="https://weeklygamejam.itch.io/">WeeklyGameJam</a></b> is weekly theme-based game jam hosted through itch.io. It's fairly laid-back for a jam, giving you a full week's time, allowing for pre-made/stock assets and code, and being understanding of late submissions. Most people make videogames, but any kind of game is allowed. At the end of the week, streamers will play and critique the submissions while the devs hang out in their chat. <br>

@ -0,0 +1,83 @@
<!--200810-->
<h1>coroutines in godot engine </h1>
september 17, 2020<br>
programming<br>
<br>
<b>Coroutines</b> are functions that, instead of running to completion, can yield until certain criteria is met. Godot Engine supports coroutines through <a href="https://docs.godotengine.org/en/stable/classes/class_@gdscript.html#class-gdscript-method-yield"><b>yield</b> ( Object object=null, String signal="")</a>, <a href="https://docs.godotengine.org/en/stable/classes/class_gdscriptfunctionstate.html#class-gdscriptfunctionstate-method-resume"><b>resume</b></a>, and the <a href="https://docs.godotengine.org/en/stable/classes/class_gdscriptfunctionstate.html"><b>GDScriptFunctionState</b></a> object.<br>
<br>
<h2>why use a coroutine? </h2>
<br>
Coroutines allow for scripted game scenarios that respond dynamically to the player and the changing game world. They let you bounce between functions, step-by-step, and respond to interruptions. <br>
<br>
They allow for functions to be called at the completion of other functions, animations, player actions, in-game events, or timers. Add in interruptions and conditionals, and you have a tool for building a responsive game world. <br>
<br>
<br>
<h2>stoplight example </h2>
<br>
As a basic example of coroutines in Godot Engine, I made a stoplight. Follow along with my code on <a href="https://gitlab.com/chimchooree/stoplight">GitLab</a>. <br>
<br>
In my example, the light changes every few seconds, going from green, yellow, then finally red. The light changes immediately if the Walk Button is pressed. This project demonstates methods that wait + resume, and also demonstrates the player affecting the timing of events through his actions.<br>
<br>
<center>
<a target="_blank" href="/static/img/ent/stoplight_demonstration.gif">
<img src="/static/img/ent/stoplight_demonstration.gif" alt="(gif: demonstration)" width="500" height="281.67">
</a><br>
</center>
<br>
<br>
<h2>how does it work? </h2>
<br>
<h3>node hierarchy </h3>
<br><center>
<img src="/static/img/ent/stoplight_nodehierarchy.png" alt="(image: node hierarchy - Root is a node named Main. It's children are TextureRect BG, AnimatedSprite Stoplight, Sprite WalkButton, and a Label. Stoplight's child is a Sprite. WalkButton's child is a TextureButton.)"><br>
</center>
<br>
<br>
I have a TextureRect background, an AnimatedSprite stoplight, a Sprite walk button with a TextureButton, and a label for displaying a timer. Since this is a simple example, most of the code is attached to the root. It's better to have code closer to where it's being used and to watch your separation of concerns in real projects, though. <br>
<br>
<br>
<h3>animation</h3>
<br>
<center>
<img src="/static/img/ent/stoplight_nodehierarchy.png" alt="(image: the AnimatedSprite Stoplight has 4 animations - default (which is no light), green, red, and yellow.)"><br>
</center><br>
The light is changed by setting its animation to one of these options. Each is one-frame - just the stoplight with the one of the lights colored in. <br>
<br>
<br>
<h3>the code </h3>
<br>
This project has two scripts: Main.gd, which is attached to the root node, and Label.gd, which is attached to the Label. <br>
<br>
<b>Main.gd</b> - code available on <a href="https://gitlab.com/chimchooree/stoplight/-/blob/master/Main.gd">GitLab</a><br>
<center>
<img src="/static/img/ent/stoplight_main.png" alt="(image: Main script.)"><br>
</center>
<br>
<b>Label.gd</b> - code available on <a href="https://gitlab.com/chimchooree/stoplight/-/blob/master/Label.gd">GitLab</a><br>
<center>
<img src="/static/img/ent/stoplight_label.png" alt="(image: Label script.)"><br>
</center>
<br>
<br>
<h3>how the code works </h3>
<br>
At _ready(), wait() is assigned to the GDScriptFunctionState 'result' and is called for the first color, green. _ready() yields until the given function (wait) is completed. <br>
<br>
The wait method yields for the given amount of seconds then sets the stoplight to the given color. <br>
<br>
At wait's completion, _ready() calls wait() for yellow, then red. Each is called one at a time, waiting for the color to complete before moving on. <br>
<br>
<br>
<h3>interrupting the stoplight </h3>
<br>
The Wait Button interrupts the wait times between colors. Before _ready() yields, it connects the 'pressed' signal on the Wait Button. <br>
<br>
If the Wait Button is clicked during wait()'s yield, the GDScriptFunctionState 'result' resumes immediately, ignoring wait()'s yield timer. This time, 'result' has a string arg 'interrupted on green,' so it will print the result, change the stoplight's color, then print 'done: green.' The wait method is complete, so _ready() resumes and calls wait() for the next color. <br>
<br>
<br>
<h2>applications </h2>
<br>
Here, I supplied a string to be printed at a button press, but the actual logic can be swapped out for anything. I use coroutines in blessfrey's skills to manage the flow of phases from activation, different phases of effects, cooldown, and interactions with any counters. I also use it in the basic weapon attack so the character continuously swings at the rate of his attack speed until he cancels, uses a skill, or moves. It could also be used for something like cars that stop and honk when the player steps in front of them and drive off once the path is clear. <br>
<br>
Coroutines enable lots of practical ways to improve the flow and interactivity of your game, so just keep experimenting. <br>
<br>

@ -1,6 +1,6 @@
<!--200810--> <!--200810-->
<h1>inventory as a system diagram </h1> <h1>inventory as a system diagram </h1>
august 24, 2020<br> october 1, 2020<br>
system diagram, game mechanics<br> system diagram, game mechanics<br>
<br> <br>
<b>System diagrams</b> illustrate how components interact within a system. It saves so much headache to step back and plan a system out like this before jumping into the code. <br> <b>System diagrams</b> illustrate how components interact within a system. It saves so much headache to step back and plan a system out like this before jumping into the code. <br>

@ -1,6 +1,6 @@
<!--200902,201001--> <!--200902,201001-->
<h1>web development resources</h1> <h1>web development resources</h1>
october 10, 2020<br> october 15, 2020<br>
accessibility, color, css, html, web design<br> accessibility, color, css, html, web design<br>
<br> <br>
<ul> <ul>

@ -0,0 +1,65 @@
<!--200810-->
<h1>blessfrey in japanese </h1>
october 29, 2020<br>
internationalization, localization<br>
<br>
Instead of hard-coding text, keep it in a spreadsheet instead. It's easier to organize, edit, and it also makes possible future translations a much smoother process. <br>
<br>
I followed along with GoTut's <a href="https://www.gotut.net/localisation-godot/">"Localisation in Godot"</a> guide, but the process is pretty simple. It's a great guide, so honestly just follow theirs instead. I'll echo the process here in case it's taken down, though. <br>
<br>
<h2>step 1 - make your spreadsheet </h2>
<br>
<center>
<a target="_blank" href="/static/img/ent/internationalization_spreadsheet.png">
<img src="/static/img/ent/internationalization_spreadsheet.png" alt="(image: spreadsheet with three columns - id, en, and ja. id has ids, en has English text, and ja has Japanese text.)" width="500" height="232.26">
</a><br>
</center>
<br>
Instead of writing your text directly into Godot, refer to the text by ids instead. These ids will be kept in the first column of your spreadsheet. Don't use spaces. <br>
<br>
The rest of the columns will hold the corresponding text in different languages. Name these columns after the language's locale code. English's is en, and Japanese's is ja. You can find the more codes in the <a href="https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html#doc-locales">Godot Docs</a>. <br>
It works just fine if you're only using one language. If you have multiple languages but don't provide a translation for a specific id, whenever your game is set to that language, references to that script will show blank text. <br>
<br>
Save your spreadsheet as a .CSV file. <br>
<br>
<br>
<h2>step 2 - import your spreadsheet </h2>
<br>
Make sure your .CSV spreadsheet is in your game folder, so Godot can automatically import files. Wherever you import your text, make sure you check 'Comma' for the delimiter or separator options. You'll get a few .TRANSLATION files. <br>
<br>
<center>
<img src="/static/img/ent/internationalization_translations.png" alt="(image: Project Settings>Localization>Translations shows a TRANSLATION file for each language.)"><br>
</center>
<br>
From Godot's top menu, go to Project>Project Settings...>Localization>Translations and add all your .TRANSLATION files. They'll be right next to wherever you saved your .CSV. <br>
<br>
<br>
<h2>step 3 - refer to your ids in your scripts </h2>
<br>
<center>
<img src="/static/img/ent/internationalization_script.png" alt="(image: example of an id used in a script)"><br>
</center>
<br>
It's really simple stuff. Anywhere you would have written a string, like "quit game," you instead use its id wrapped in tr(). So instead of <code>label.set_text("quit")</code>, you'd write <code>label.set_text(tr("quit_game"))</code>. In this example, the id is "quit_game" and its corresponding text in English is "quit."
<br>
<br>
<h2>step 4 - set the game's language </h2>
<br>
<center>
<img src="/static/img/ent/internationalization_setlocale.png" alt="(image: example of setting the locale in a script)"><br>
</center>
<br>
Set the locale in your script, somewhere like _ready() or on a 'change language' button. Here's the line for setting the locale: <code><a href="https://docs.godotengine.org/en/stable/classes/class_translationserver.html">TranslationServer</a>.<a href="https://docs.godotengine.org/en/stable/classes/class_translationserver.html#class-translationserver-method-set-locale">set_locale</a>(<a href="https://docs.godotengine.org/en/stable/tutorials/i18n/locales.html">"ja"</a>)</code>
<br>
<br>
<h2>step 5 - continue adding to your spreadsheet </h2>
<br>
Now that everything's in place, you can keep adding new ids and translations, and Godot will automatically update your changes. <br>
<br>
<h2>that's the basics </h2>
<center>
<img src="/static/img/ent/internationalization_japanese.png" alt="(image: blessfrey screenshot in Japanese)" width="500" height="370.46"><br>
</center>
<br>
It all comes together for an old screenshot of blessfrey's main menu in my broken Japanese. やべーな!<br>
<br>

@ -73,13 +73,13 @@ bottle, python, website<br>
<br> <br>
<h3>saturday, october 17 </h3><br> <h3>saturday, october 17 </h3><br>
<ul> <ul>
<li>worked at the cafe today. Since his battery is dead, he finally read some May I Ask For One Final Thing? I love that manga!</li> <li>worked at the cafe today. Since my husband's battery is dead, he finally read some May I Ask For One Final Thing? I love that manga!</li>
<li>Refactored the main Bottle script. I wrote it hard and fast, so it was reading all the diary entries multiple times per refresh. It's not only cleaner, it also only reads the files twice.</li> <li>Refactored the main Bottle script. Before, I wrote it hard and fast, so it was reading all the diary entries multiple times per refresh. It's not only cleaner now, it also only reads the files twice.</li>
</ul> </ul>
<br> <br>
<h3>monday, october 19 </h3><br> <h3>monday, october 19 </h3><br>
<ul> <ul>
<li>did some sketches for the story slideshow for the game page. they are an iteration of some cg art for the real game, too. I really don't draw enough...been getting back into reading manga again, and it's inspiring me to draw more.</li> <li>did some sketches for the story slideshow for the game page. they are an iteration of some cg art for the real game, too. I really don't draw enough...</li>
<li>added the 'recommended articles' section to the bottom of diary entries.</li> <li>added the 'recommended articles' section to the bottom of diary entries.</li>
<li>added 'extra' articles, for articles that are unlisted from the main directory. I'm using it to include more GDC talk notes per talk while keeping the GDC talk article general and summarized.</li> <li>added 'extra' articles, for articles that are unlisted from the main directory. I'm using it to include more GDC talk notes per talk while keeping the GDC talk article general and summarized.</li>
</ul> </ul>

@ -0,0 +1,33 @@
<!--200810-->
<h1>tidying up my skill phases </h1>
november 12, 2020<br>
#programming #skills<br>
<br>
In Godot Engine, you can call methods from a parent class by prefixing it with a period (.). So to access the <code>move()</code> method from a parent, call <code>.move()</code>. This is called a <b>super method</b>. <br>
<br>
I used to use super methods to make skills, but there's a better way.<br>
<br>
Just so you know, blessfrey's skills have a number of phases of effects that must happen in order: skill press > activation > initial phase > main phase > end phase > cooldown <br>
<br>
<br>
<h2>the old way </h2><br>
Initially, I used super methods to give each phase custom effects and call the next phase. This was messy. If I ever redesigned the flow of the skill phases, I'd have to edit every single skill script. It also causes a lot of repetitive code in the individual skill scripts while the base script is tiny. <br>
<br><center>
<img src="/static/img/ent/supermethod_old.png" alt="(image: GDscript code using old method)"><br>
</center>
(You can see the old method's code on <a href="https://pastebin.com/DDu1Q7Q6">Pastebin</a>.)
<br>
<br>
<h2>the new way </h2><br>
<br>
Instead, I can bring all the repetitive steps into the base class, sandwiching in a subfunction where the custom effects would take place. Now I only need to add what makes my skill unique inside the subfunction. <br>
<br>
I named the subfunction after its main function and added an underscore to the front. So in the base script, I fit <code>_functionality(user, action_target)</code> into the <code>functionality(user, action_target)</code>. Then the individual skill scripts only need the subfunction, none of the other repetitive code from before. The subfunction is empty in the base class and filled with unique code in the child classes. Since skills inherit, the unique <code>_functionality</code> subfunction will be called automatically from the base script's <code>functionality</code>. <br>
<br>
<center>
<a target="_blank" href="/static/img/ent/supermethod_old.png">
<img src="/static/img/ent/supermethod_new.png" alt="(image: GDscript code using new method)" width="500" height="355.36">
</a>
</center>
(You can see the new method's code on <a href="https://pastebin.com/teeYn9jP">Pastebin</a>.)
<br>

@ -0,0 +1,49 @@
<!--200810-->
<h1>pretendOS - a game inspired by windows XP </h1>
november 26, 2020<br>
side project<br>
<br>
Getting started with blessfrey's AI was overwhelming, so I took a break and worked on a new game. I didn't get very far, but it's very very cute to me. It's not even on my hard drive anymore. <br>
<br>
Unlike blessfrey, where coding takes up 90% of the effort, pretendOS is mostly reasonably polished assets and sounds with barely any functionality. It's a UI game, after all. Since it's a game requiring a completely opposite skill-set, I was able to make progress on <i>something</i> while reading up on game AI. (Programming Game AI by Example by Mat Buckland was a good resource to me, by the way.) I also got to work on things I never get around to with blessfrey, like particle effects. <br>
<br>
<br>
<h2>Inspiration </h2>
<br>
<h3>Windows XP</h3>
The game takes strong aesthetic inspiration from Windows XP. It almost fits the 90s vaporwave trend at the moment, but I'm too young to really remember Windows 95. I obviously have nostalgia for it as my first operating system (as far as I remember - I was a toddler then), but I mostly knew it as the Lego Island machine propped up in the dining room. As my family upgraded computers over the years, Windows never really impacted me as anything more than something that can run some videogames and whatever popular web browser of the time. That is, until Windows XP. <br>
<br>
XP really hooked me. It was the first operating system I spent as much time exploring as I spent using software. XP's edition of Paint was my favorite yet, I loved fiddling with the themes and accessibility options, especially Microsoft Sam, Rover, and Clippy. I started watching Youtube videos on how to use the Command Prompt. XP was just fun to use. I've found better desktop environments and operating systems since, but I never got over that aesthetic: smooth, blended graphics with hard pixel edges in 32-bit color with an alpha channel, right at the cusp between pixel art and vector graphics. My vaporwave would be XP in Luna olive green, or the "Fisher-Price interface" as Ars Technica users called it. <br>
<br>
<img src="/static/img/ent/wikipedia_luna.png" alt="(image: Wikipedia excerpt: Critics who did not like the theme characterized it as a 'Fisher-Price interface'.)"><br>
(screenshot from <a href="https://en.wikipedia.org/wiki/Windows_XP_visual_styles">Wikipedia</a> - referencing articles from <a href="https://web.archive.org/web/20091008081626/http://www.pcworld.com/article/117427/full_disclosure_your_take_on_windows_worst_irritations.html">PCWorld</a> and <a href="https://arstechnica.com/information-technology/2014/04/memory-lane-before-everyone-loved-windows-xp-they-hated-it/">Ars Technica</a>)<br>
<br>
<br>
There were a few other experiences behind the game, too. <br>
<br>
<h3>Mother's Day E-Card</h3>
I finally got my husband to try Godot Engine, and he used it to make a digital Mother's Day card for his mom. Opening the card displayed a 3D heart (a "cardioid") that bounced to the beat of a song while 2D cardioid particles rained down. It was all programmatically generated using geometry instead of 3D + 2D assets, so the application was very small. He made the graphics side of things look really interesting, and I wanted to play around with particles, too. Just...not as fancy;; <br>
<br>
<h3>Secret Little Haven</h3>
I also just played a cute pretend OS game on itch called <a href="https://ristar.itch.io/secret-little-haven">Secret Little Haven</a> It's quite short, very story-driven, and kind of buggy, telling Alex's struggle with gender identity through IMs. Honestly, pretend OS games and coming-of-age chat sims are nothing special, but Secret Little Haven's believability makes it really stand out. Instead of defending against cheesy + inaccurate deep web hacking attempts, you use an in-game terminal to get around child locks set by Alex's dad. Those terminal puzzles are the most realistic and relatable hacking I've seen in these games. SLH isn't super sophisticated or in-depth, but it shows how cute and believable a pretend OS game can be. I'd love to make a little environment like that, that's as fun to fiddle around with as XP was for me. <br>
<br>
<br>
<h2>pretendOS </h2>
<br>
So what's pretendOS? Like I said, not much besides pictures. I only worked on it for a few days. <br>
<br>
What really bogged it down was Cat Chat. I wanted an AI chat personality that talked like a cat. I could do that, but that kind of thing takes a lot of time, when this project was really just procrastinating working on AI. <br>
<br>
The rest is cute, though. The icon winks when you click it, the cursor's kinda 2000s-free-animated-cursors, and it's got those Fisher-Price colors and bubbly sounds everywhere that I liked as a kid. <br>
<br>
<center>
<a target="_blank" href="/static/img/ent/pretendOS_catchat.jpeg">
<img src="/static/img/ent/pretendOS_catchat.jpeg" alt="(image: pretend desktop with a Cat Chat application)" width="500" height="281.25">
</a><br>
</center>
<br>
<br>
<h2>the future</h2>
<br>
It's cute. I'd like it to be finished in some way. I went ahead and cloned my old repo. Maybe I'll fill it out with some more applications for a game jam or something or at least finally get that cool Secret Little Haven curved screen shader working. <br>
<br>

@ -0,0 +1,53 @@
<!--200810-->
<h1>nothing </h1>
nothing<br>
nothing<br>
<br>nothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingnonothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingnonothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingnonothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingnonothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingnonothi ngnothing nothing nothingnothi ngnothing
nothingnothing nothingn oth ingnothingno thingnothingn
othingnoth ingno thingnothin gnothingno thingnothingno
thingn othingnoth ingnothing nothingn othingnothingnot
hingnothi ngnothingn othingnoth ingnothi ngnothingnot
ingnothing nothingno thingnot hingnothingnothingnoth
ingnothing nothingno thingnothing nothingnothingnothi
ngnothi ngnothingn othingnothin gnothingnothingnothin
nothingn othing nothingno thingnothingno

@ -0,0 +1,29 @@
<!--200831,200931-->
<h1>november 2020: dear diary </h1>
november 30, 2020<br>
<br>
<br>
<h2>on topic </h2>
Between the <b>8th and 15th</b>, I wrote a Python script for generating Godot skill scenes from JSON files. As opposed to the questionnaire script I used before, this one can generate multiple skills at a click of a button. It isn't a perfect solution either, though, since my JSON script and the skills I have in the game aren't synced. It'd be better for the skills to be something like JSON files that are read by the game at run-time, unless that would be too costly. That way, I only edit skills in one location and don't need to worry about different versions. <br>
<br>
Skill inheritance is more sophisticated now and allows the script to generate a lot of the functionality of most types of skills now. <br>
<br>
I spend a lot of time on how to make skills because this is a core mechanic of my game, and I plan to have a hundred or more of them. I need an efficient way to update and create the game's skill pool. <br>
<br>
On <b>November 24, 2020</b>, I finally added a diary navigation bar <i>under</i> the diary snippets, so you don't have to scroll back up to go to the next page anymore. <br>
<br>
On <b>November 25, 2020</b>, I retroactively added diary entries based on old tweets. I added one for my pixel font, one for my Weekly Game Jam submission, one for my inventory system diagram, and one for blessfrey's graphic updates. I finally got Bottle to support self-hosted images instead of using imgur for everything (lol), and fixed lots of bugs related to actually having imbedded images in articles. <br>
<br>
As cool as it is to work on gamedev, this website is also a priority for me as a sort of portfolio. So it would be nice to have lots of articles about my process and different projects. It would be super nice to have pretty graphics everywhere, but as usual, the placeholders are probably going to stay around for a while since they're already half-decent-looking. <br>
<br>
<b>November 26, 2020</b> is Thanksgiving during a pandemic. Wrote up an article for my pretendOS game and my coroutines example. Also, the diary shows 8 snippets per page instead of 4. <br>
<br>
<b>November 27, 2020</b> - is Black Friday. I ordered navy eyeshadow and fancy sunscreen.<img src="/static/img/emo/star.gif" alt="<3"> Added an article for skill phases + super methods and slimeAI's state transition diagram.<br>
<br>
<b>November 28, 2020</b> is my birthday. <img src="/static/img/emo/heart.gif" alt="<3"><br>
<br>
<h2>off-topic </h2><br>
I joined a Japanese manga translation group on a whim and now provide Japanese-to-English transcripts for a new chapter of a manga about every week and a half. It wasn't obvious, but understanding Japanese is a different skill than rewriting Japanese into English while keeping the jokes, character voice, and cliffhangers/foreshadowing intact;; <br>
<br>
Also, Election Day-turned-Weeks took up a few extra days of anxious news-watching than it usually does, even though I tuned out long before Georgia was called. <br>
<br>

@ -0,0 +1,35 @@
<!--200810-->
<h1>slimeAI - state transition diagram </h1>
december 10, 2020<br>
#ai #programming<br>
<br>
<br>
blessfrey's slimes use finite state machines. <b>Finite state machines</b> (FSM) are models with a finite number of states that either decide to generate output or transition to a new state based on input. They can only be in one state at a time. <br>
<br>
<br>
<h2>why use a finite state machine? </h2><br>
Because they are simple and flexible, while still allowing for interesting behavior. FSMs reflect our own mental model of how slimes behave (attack mode, wander mode, sleep mode, etc). These different modes or states are written as manageable chunks that easy to code, debug, update, and refactor. It's also efficient with processor time, since the behavior is abstracted to basic conditionals. <br>
<br>
A state can be as broad or specific as you need, so long as it's granular. So they can be more easily debugged and swapped out with one another, it's a good idea to have one entry point and one exit point for all your states.<br>
<br>
Of course, since FSMs can be used for anything with states and transitions. You can think of specific menus, mechanics or even your entire game in terms of states. I'm just using them here for understanding the AI for my slime monster. <br>
<br>
<br>
<h2>designing AI </h2><br>
Planning ahead is extra important, since any dead-ends will halt your slime. I used a state transition diagram to design the slime's AI. In the diagram, circles represent states and arrows represent transitions, triggered by some kind of event. I marked the initial state with a star, but Buckland recommends a double circle. <br>
<br>
The slime is a simple creature. It idles, chases anything that gets too close, and attacks until its target dies. Here's the diagram version of that:<br>
<br><center>
<img src="/static/img/ent/slimeai_diagram.png" alt="(image: a state transition diagram for slime ai.)" width="500" height="250"><br>
</center>
<br>
The states are Idle, Choose Target, Attack, and Move to Target. The initial state is Idle. <br>
<br>
If there's a valid target, the slime enters Choose Target. If there's no longer a valid target, it returns to Idle. If it successfully gets a target, it begins moving to target. If the target becomes invalid, it returns to Idle. Once the target is in attack range, it enters Attack. If the foe moves out of range, it returns to Move to Target. If the target becomes invalid, it returns to Choose Target. And the cycle continues. <br>
<br>
No matter how you follow the arrows, there are no dead-ends and all states can be reached eventually, so it'll work okay when it's implemented as code. <img src="/static/img/emo/heart.gif" alt="<3"><br>
<br>
<br>
<h2>reference </h2><br>
<a href="https://www.goodreads.com/book/show/161139.Programming_Game_AI_by_Example"><b>Programming Game AI by Example by Mat Buckland</b></a>. It's an easy to understand introduction to game math + AI concepts. The code examples are in C++, but they are still useful for understanding the underlying principles. I didn't even know where to begin before I started reading and it got me pretty decent groundwork for AI creatures with different behavior that reacts to the players.<img src="/static/img/emo/heart.gif" alt="<3"> <br>
<br>

@ -1,6 +1,6 @@
<!--200810--> <!--200810-->
<h1>blessfrey graphic updates + mockups </h1> <h1>blessfrey graphic updates + mockups </h1>
august 24, 2020<br> december 24, 2020<br>
screenshots, mockups<br> screenshots, mockups<br>
<br> <br>
I iterate over the graphics periodically, so I can practice without worrying about polish. Here's some screenshots of different styles I've tried. (Though April 23, 2019's is actually a mockup, that style did run in-engine for a few weeks.)<br> I iterate over the graphics periodically, so I can practice without worrying about polish. Here's some screenshots of different styles I've tried. (Though April 23, 2019's is actually a mockup, that style did run in-engine for a few weeks.)<br>

@ -0,0 +1,28 @@
<!--200810-->
<h1>my favorite GDC talks </h1>
january 7, 2020<br>
game design, marketing<br>
<br>
I really should be keeping a list of these with descriptions, so why not keep them in an article? <br>
<br>
<h2><a href="https://www.youtube.com/watch?v=W20t1zCZv8M">Automated Testing and Instant Replays in Retro City Rampage </a></h2><br>
Vblank Entertainment's Brian Provinciano (2015) <br>
log button inputs to replay the game, for use in preproducing bugs, sharing replays on the community leaderboard, running cutscenes, and even controlling AI. It is 100% accurate in deterministic engines but also helpful in less deterministic engines.
<br>
<ul>
<li><a href="/static/extra/SimpleInputRec.cpp">I backed up the code he shared here. </a> It is a simple example of how to record and playback button input, written in C++.</li>
</ul>
<br>
<br>
<h2><a href="https://www.youtube.com/watch?v=UJiv14uPOac">Empathizing with Steam: How People Shop for Your Game </a></h2><br>
Chris Zukowski (2020) <br>
tips for how to design your Steam store page based on Zukowski's screenshare and shopping diary observations of ordinary people shopping on Steam <br>
<br>
<ul>
<li>Essentially, make your gameplay genre absolutely clear within the first 4 screenshots and in the short description so that people will wishlist your game to buy during a seasonal Steam Sale. </li>
<li>Approach your wishlisters as complete newcomers. Jazz up your Steam page before a Steam Sale. Release an update, post in your forums, put a Santa hat on your character. When wishlisters return to your page, they will see an active game and be sold on it all over again. </li>
<li>His conclusions are very similar to how I shop on Steam, except I could care less for the tag section. </li>
<li>The romantic indie fiction section on Amazon dwarves the indie game section on Steam. To be immediately visible to their audience, romance authors follow a clear visual language on their covers to communicate their genres and sub-genres. Zukowski uses this as an extreme method for attracting your audience using the tropes of your genre, pointing out common UI elements and the shooter guy on every FPS cover. </li>
<li>More notes @ <a href="/diary/entries/extra/gdc-design-steam-store">/diary/entries/extra/gdc-design-steam-store </a>
</ul>
<br>

@ -137,6 +137,8 @@ def clean(result):
result = re.sub(r'</h\d>','',result) result = re.sub(r'</h\d>','',result)
result = result.replace('<center>','') result = result.replace('<center>','')
result = result.replace('</center>','') result = result.replace('</center>','')
result = result.replace('<b>','')
result = result.replace('</b>','')
return result return result
# Return first 300 words of article + " ... " # Return first 300 words of article + " ... "
@ -152,15 +154,32 @@ def sort_files(files):
files.sort(reverse=True) files.sort(reverse=True)
return files return files
# Return list of all diary entries (exclude raws + extras) def curate_files(files):
def gather_files(loc): # remove folders
files = os.listdir(loc)
if 'raw' in files: if 'raw' in files:
files.remove('raw') files.remove('raw')
if 'extra' in files: if 'extra' in files:
files.remove('extra') files.remove('extra')
# remove
clean = []
for f in files:
if is_it_time(f):
clean.append(f)
return clean
def is_it_time(date):
today = datetime.datetime.now()
today_string = today.strftime("%y") + today.strftime("%m") + today.strftime("%d")
return int(date) <= int(today_string)
# Return list of all diary entries (exclude raws + extras)
def gather_files(loc):
files = os.listdir(loc)
return files return files
def gather_and_sort(loc):
return sort_files(curate_files(gather_files(loc)))
## Static ## ## Static ##
# Serve CSS # Serve CSS
@ -190,7 +209,7 @@ def error404(error):
def index(): def index():
"""home page""" """home page"""
loc = 'diary/entries/' loc = 'diary/entries/'
info = {'css': 'index', 'news': list_headlines(sort_files(gather_files(loc))[0:10]), 'title': 'chimchooree\'s dev space - blessfrey', 'year': datetime.datetime.now()} info = {'css': 'index', 'news': list_headlines(gather_and_sort(loc)[0:10]), 'title': 'chimchooree\'s dev space - blessfrey', 'year': datetime.datetime.now()}
return template('index.tpl', info) return template('index.tpl', info)
# Game Page - Game Template - system, character, story info # Game Page - Game Template - system, character, story info
@ -218,15 +237,17 @@ def diary(page):
"""diary page""" """diary page"""
loc = 'diary/entries/' loc = 'diary/entries/'
assert isinstance(page, int) assert isinstance(page, int)
info = {'css': 'diary', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'snippets': list_snippets(sort_files(gather_files(loc))), 'latest': list_headlines(sort_files(gather_files(loc))[0:5]), 'total': len(gather_files(loc)), 'limit': 4, 'cluster': 3, 'page': page} info = {'css': 'diary', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'snippets': list_snippets(gather_and_sort(loc)), 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'total': len(gather_files(loc)), 'limit': 8, 'cluster': 3, 'page': page}
return template('diary.tpl', info) return template('diary.tpl', info)
# Entry Page - Feature Template - for articles # Entry Page - Feature Template - for articles
@route('/diary/entries/<page:int>') @route('/diary/entries/<page:int>')
def entry(page): def entry(page):
"""diary entry""" """diary entry"""
if not is_it_time(page):
return error404(404)
loc = 'diary/entries/' loc = 'diary/entries/'
info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'entry': retrieve_article(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(sort_files(gather_files(loc))[0:5]), 'page': page} info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'entry': retrieve_article(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(gather_and_sort(loc)[0:5]), 'page': page}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__)) abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views') abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path ) TEMPLATE_PATH.insert(0, abs_views_path )
@ -237,7 +258,7 @@ def entry(page):
def extra(page): def extra(page):
"""diary extra""" """diary extra"""
loc = 'diary/entries/extra/' loc = 'diary/entries/extra/'
info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'entry': retrieve_article(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(sort_files(gather_files('diary/entries/'))[0:5]), 'page': page} info = {'css': 'feature', 'title': 'blessfrey - developer diary', 'year': datetime.datetime.now(), 'entry': retrieve_article(page, loc), 'recommends': list_rec(page), 'articles': "Articles", 'latest': list_headlines(gather_and_sort('diary/entries/')[0:5]), 'page': page}
abs_app_dir_path = os.path.dirname(os.path.realpath(__file__)) abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
abs_views_path = os.path.join(abs_app_dir_path, 'views') abs_views_path = os.path.join(abs_app_dir_path, 'views')
TEMPLATE_PATH.insert(0, abs_views_path ) TEMPLATE_PATH.insert(0, abs_views_path )

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -4,59 +4,45 @@
How did you find this page?<br> How did you find this page?<br>
It's my secret page.<br> It's my secret page.<br>
<br> <br>
<h1>Holiday Sales Watch</h1> <h1>Website To-Do</h1>
<table>
<tr>
<th>Regular Price</th>
<th>Sale Price</th>
<th>Brand</th>
<th>Product</th>
<th>URL</th>
</tr>
<tr>
<th>$5</th>
<th>$3.75 @ 25&#37; off 11/27-11/30</th>
<th>Sydney Grace</th>
<th>Indiana Love</th>
<th>http://sydneygraceco.com/indiana-love/</th>
</tr>
<tr>
<th>$5</th>
<th>$3.75 @ 25&#37; off 11/27-11/30</th>
<th>Sydney Grace</th>
<th>Saturn, Sweetheart, Pandora, Sutter, Designer, or Deep Water?</th>
<th>http://sydneygraceco.com/</th>
</tr>
<tr>
<th>$24</th>
<th>$18 @ 25&#37; off w/ UDFRIENDS25</th>
<th>Urban Decay</th>
<th>Eyeshadow Primer Potion</th>
<th>https://www.urbandecay.com/eyeshadow-primer-potion/UD515.html?dwvar_UD515_color=Original</th>
</tr>
<tr>
<th>$30</th>
<th>$21 @ 30&#37; off expires 11/29</th>
<th>Biossance</th>
<th>Squalane + Zinc Sheer Mineral Sunscreen</th>
<th>https://biossance.com/collections/all/products/squalane-zinc-sheer-mineral-sunscreen-spf30</th>
</tr>
<tr>
<th>$15.99</th>
<th>$7.99 @ $8 off expires 12/31</th>
<th>Neutrogena</th>
<th>Sheer Zinc Face Dry Touch Sunscreen SPF 50</th>
<th>https://www.ulta.com/sheer-zinc-face-dry-touch-sunscreen-spf-50?productId=xlsImpprod15721137</th>
</tr>
</table>
<ul> <ul>
<li>SG shipping = $4</li> <li>Write some diary entries</li>
<li>UD shipping = $8</li> <li>Plan a regular release date for them</li>
<li>B shipping = free</li> <li>Make sure their dates + filenames match</li>
<li>Also, I kinda want Outer Worlds, but half-off is still a lot, and idek if it's that good. I wouldn't mind trying Baldur's Gate 3, but it's pricey-pricey, too. I wouldn't stop playing Legacy of Kain anyways. </li> <li>Make sure their tags are formatted correctly</li>
<li>Proofread</li>
<li>Make sure their formatting is consistent</li>
<li>Make an automatic deployment for them if I need to</li>
<li>ALSO</li>
<li>turn game tab into a project tab to showcase completed code, etc</li>
<li>make presskit page decent</li>
<li>include downloadable presskit PDF, etc, on presskit page</li>
<li>update art assets</li>
</ul> </ul>
<br> <br>
So...2 SG shadows is $11.50. <br>Then I can either get fancy birthday sunscreen for $21 or regular sunscreen for $15.99 + whatever Ulta impulse buy. <br>So maybe $32.50-27.49 total. <br>And I can wait a few months for a UD primer sale.<br> <br>
<h1>Articles</h1>
<ul>
<li>8/6 - blessfrey</li>
<li>8/20 - pixel joy</li>
<li>8/31 - DIARY</li>
<li>9/3 - jam</li>
<li>9/17 - coroutines</li>
<li>9/30 - DIARY</li>
<li>10/1 - inventory system diagram</li>
<li>10/15 - web design resources</li>
<li>10/29 - Japanese</li>
<li>10/31 - DIARY </li>
<li>11/12 - skills + super methods</li>
<li>11/26 - pretendOS</li>
<li>11/31 - DIARY</li>
<li>12/10 - AI diagram</li>
<li>12/17 - AI code - https://twitter.com/lilchimchooree/status/1206399601881812994</li>
<li>12/24 - Graphics</li>
<li>12/31- DIARY</li>
<li>1/7 - GDC</li>
<li>1/31 - DIARY</li>
</ul>
<br> <br>
<br> <br>
<h1>Try to Do...</h1> <h1>Try to Do...</h1>
@ -88,5 +74,80 @@
<li>https://support.google.com/webmasters/answer/6062598?hl=en&ref_topic=6061961 - Google robots.txt tester</li> <li>https://support.google.com/webmasters/answer/6062598?hl=en&ref_topic=6061961 - Google robots.txt tester</li>
<li>add &lt;meta name=”robots” content=”noindex,nofollow”&gt; to pages to not index or follow links on that page</li> <li>add &lt;meta name=”robots” content=”noindex,nofollow”&gt; to pages to not index or follow links on that page</li>
</ul> </ul>
<br>
<br>
<h1>Lowest Sale Price</h1>
<table>
<tr>
<th>Regular Price</th>
<th>Sale Price</th>
<th>Brand</th>
<th>Product</th>
<th>URL</th>
</tr>
<tr>
<th>$24</th>
<th>$12 on Primer Day</th>
<th>Urban Decay</th>
<th>Eyeshadow Primer Potion</th>
<th>https://www.urbandecay.com/eyeshadow-primer-potion/UD515.html?dwvar_UD515_color=Original</th>
</tr>
<tr>
<th>$30</th>
<th>$21 on Black Friday</th>
<th>Biossance</th>
<th>Squalane + Zinc Sheer Mineral Sunscreen</th>
<th>https://biossance.com/collections/all/products/squalane-zinc-sheer-mineral-sunscreen-spf30</th>
</tr>
<tr>
<th>$15.99</th>
<th>???</th>
<th>Neutrogena</th>
<th>Sheer Zinc Face Dry Touch Sunscreen SPF 50</th>
<th>https://www.ulta.com/sheer-zinc-face-dry-touch-sunscreen-spf-50?productId=xlsImpprod15721137</th>
</tr>
<tr>
<th>$6.99</th>
<th>$0.97</th>
<th>Crystal Dynamics</th>
<th>Legacy of Kain: Defiance</th>
<th>https://www.gog.com/game/legacy_of_kain_defiance</th>
</tr>
<tr>
<th>$6.99</th>
<th>$0.97</th>
<th>Crystal Dynamics</th>
<th>Legacy of Kain: Blood Omen 2</th>
<th>https://www.gog.com/game/legacy_of_kain_blood_omen_2</th>
</tr>
<tr>
<th>$59.99</th>
<th>$29.99</th>
<th>Obsidian</th>
<th>THE OUTER WORLDS</th>
<th>https://www.gog.com/game/the_outer_worlds</th>
</tr>
<tr>
<th>$59.99</th>
<th>???</th>
<th>PlatinumGames</th>
<th>ASTRAL CHAIN</th>
<th>https://www.humblebundle.com/store/astral-chain</th>
</tr>
<tr>
<th>$59.99</th>
<th>???</th>
<th>Nintendo</th>
<th>Super Mario Odyssey</th>
<th>https://www.humblebundle.com/store/super-mario-odyssey</th>
</tr>
<tr>
<th>$59.99</th>
<th>???</th>
<th>Nintendo</th>
<th>Pokémon Mystery Dungeon™: Rescue Team DX </th>
<th>https://www.humblebundle.com/store/pokemon-mystery-dungeon-rescue-team-dx</th>
</tr>
</table>
<br> <br>
<div class="footer-row"> </div> <div class="footer-row"> </div>

Loading…
Cancel
Save