Mimi Momo 4 years ago
commit b8a789ccf8

@ -1,7 +1,7 @@
<!--200918--> <!--201217,200903-->
<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>

@ -0,0 +1,13 @@
<!--201224,201015-->
<h1>free pixel font </h1>
august 20, 2020<br>
#assets<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>
<br>
Download it from fontstruct @ <a href="https://fontstruct.com/fontstructions/show/1596262/pixel-joy">https://fontstruct.com/fontstructions/show/1596262/pixel-joy</a>.<br>
<br>
<center><img src="/static/img/ent/pixeljoy.jpeg" alt="image: pixel joy font preview"></center> <br>
<br>
Font released under public domain. Sample text in the preview image is from Imogen Heap's "Pocket Sun," and the colors are from <a href="https://lospec.com/palette-list/aap-64">Adigun Polack's AAP-64 palette</a>. :)<br>
<br>

@ -1,7 +1,7 @@
<!--200931,201031--> <!--200930,201031-->
<h1>august 2020: new server, new site</h1> <h1>august 2020: new server, new site</h1>
august 31, 2020<br> august 31, 2020<br>
apache, css, html, nginx, php, server, website<br> #apache #css #html #nginx #php #server #website<br>
<br> <br>
<h2>tuesday, august 4</h2> <h2>tuesday, august 4</h2>
<ul> <ul>
@ -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>

@ -0,0 +1,76 @@
<!--200806,201126-->
<h1>my first game jam - #weeklygamejam </h1>
september 3, 2020<br>
#gamejam<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>
<br>
<center><img src="/static/img/ent/SmallThingThatMakesThings.png" alt="(image: Key art of Elwell and Small Thing, buried in dogs)" width="500" height="223.77"></center> <br>
<br>
<br>
<h2>small thing that makes things</h2>
<br>
I participated in Week 85 under the theme Offspring, submitting my game on February 27, 2019. My game was Small Thing That Makes Things, an adventure platformer. You can play it on itch.io @ <a href="https://chimchooree.itch.io/small-thing-that-makes-things">https://chimchooree.itch.io/small-thing-that-makes-things</a>.<br>
<br>
You play as Hamish T. Elwell, the hero accountant of an overcrowded animal shelter, investigating the recent explosion of the local stray population. You can walk, jump on platforms, collect items, and chat with NPCs. There's multiple endings, depending on your choices. <br>
<br>
<br>
<h2>positives </h2>
<br>
For a week-made game, I think STTMT is pretty cute, and I'm pretty happy with it.<img src="/static/img/emo/star.gif" alt=":)"> <br>
<br>
I actually finished a game, and someone actually finished playing it on a stream. That's really cool, even if STTMT isn't all that good. The deadline forced me to make final decisions, complete features, and move on, and there's a lot of value in actually finishing instead of forever polishing ideas and assets. <br>
<br>
The short time-frame forced me to get around to every aspect of game development, many of which I had never done before. I had to learn how to export my Godot project, upload an HTML5 game, and make sure the exported game was complete and playable. Lots of the features were first-times for me, too. I've never written code for platformer movements or moving cameras. This also was the first time I've really gotten branching and conditional dialog working in Godot. <br>
<br>
<br>
<h2>mistakes</h2>
<br>
I recolored OPP's pixel art and lost the high contrast for the rock ledges. They blend into the rocky background, so you can't tell you can jump on them. Joshua McLean pointed this out during his stream, and I didn't even noticed until then. Having more eyes on your game is so important.<br>
<br>
Also the level design is just not interesting. I spent lots of time on the choices and adventure game aspects, while the platforming as an extreme afterthought. It's a game jam, though, what do you expect lol?<br>
<br>
I took the easy way out with animation. I might have learned more working from scratch, but modifying OPP's sprites to suit my character designs was way faster when I was already struggling to finish on time.<br>
<br>
<br>
<h2>screenshots </h2>
<center>
<a target="_blank" href="/static/img/ent/SmallThingThatMakesThings_flatland.png">
<img src="/static/img/ent/SmallThingThatMakesThings_flatland.png" alt="(image: Elwell and Small Thing in a jumble of dogs)" width="500" height="300.92">
</a><br>
Experimenting with Small Thing's summoning mechanic. In this version, the characters are just blocks with collision that can move around the flat, empty world with WASD.<br>
<br><br>
<a target="_blank" href="/static/img/ent/chimchooree_weekly_game_jam.gif">
<img src="/static/img/ent/chimchooree_weekly_game_jam.gif" alt="(gif: Elwell rides a broken-physics dog across the valley)" width="500" height="215.77">
</a><br>
The dog spawning physics was (and still is) really broken, so dogs go flying pretty frequently. It was reliable enough in this version to be used as a moving platform. <br>
<br><br>
<a target="_blank" href="/static/img/ent/SmallThingThatMakesThings_rainingdogs.png">
<img src="/static/img/ent/SmallThingThatMakesThings_rainingdogs.png" alt="(image: Elwell watches the rainfall of dogs from his window)" width="500" height="282">
</a><br>
Dogs rain down upon Elwell's animal shelter in the finished version. <br>
<br><br>
<a target="_blank" href="/static/img/ent/SmallThingThatMakesThings_rainingdogs.png">
<img src="/static/img/ent/SmallThingThatMakesThings_dialog.png" alt="(image: Dialog)" width="500" height="265.12">
</a><br>
Dialog between Elwell and his boss. <br>
</center>
<br>
<br>
<h2>conclusion</h2>
<br>
If you're looking for a jam to jump into, WeeklyGameJam is a cute one to try. You aren't too rushed, you get to watch people play your game, you get useful criticism, and the community is pretty chill. The themes are always inspiring, too.<img src="/static/img/emo/heart.gif" alt="<3"> <br>
<br>
<br>
<h2>credits</h2>
<ul>
<li>coding + art by chimchooree</li>
<li>Open Pixel Project (OPP) (animations & tiles, edited to fit my characters & palette) @ <a href="http://www.openpixelproject.com/">http://www.openpixelproject.com/</a></li>
<li>Music track "forest" by syncopika under CC-BY 3.0 @ <a href="https://opengameart.org/content/forest">https://opengameart.org/content/forest</a> & <a href="https://greenbearmusic.bandcamp.com/album/bgm-fun-vol-5">https://greenbearmusic.bandcamp.com/album/bgm-fun-vol-5</a></li>
<li>Bad ending image from Wikimedia, credit to Jon Sullivan @ <a href="https://tinyurl.com/y6oswx8v">https://tinyurl.com/y6oswx8v</a> (url contains spoilers)</li>
<li>SimpleJPC-16 Palette by Adigun Polack @ <a href="https://lospec.com/palette-list/simplejpc-16">https://lospec.com/palette-list/simplejpc-16</a></li>
<li>pixel joy font by chimchooree @ <a href="https://fontstruct.com/fontstructions/show/1596262/pixel-joy">https://fontstruct.com/fontstructions/show/1596262/pixel-joy</a></li>
<li>Tools: <a href="https://godotengine.org/">Godot Engine 3.0.6</a>, <a href="https://graphicsgale.com/us/">GraphicsGale</a></li>
<li>Weekly Game Jam 85, "Offspring" theme @ <a href="https://itch.io/jam/weekly-game-jam-85">https://itch.io/jam/weekly-game-jam-85</a></li>
</ul>
<br>

@ -0,0 +1,83 @@
<!--201001,201112-->
<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,7 +1,7 @@
<!--200831,201031--> <!--200831,201031-->
<h1>september 2020: bye php, hello bottle</h1> <h1>september 2020: bye php, hello bottle</h1>
september 30, 2020 september 30, 2020
bottle, css, git, html, regex, regular expressions, website<br><br> #bottle #css #git #html #regex #regularexpressions #website<br><br>
<br> <br>
<h2>tuesday, september 1</h2> <h2>tuesday, september 1</h2>
<ul> <ul>

@ -0,0 +1,35 @@
<!--200917,201112-->
<h1>inventory as a system diagram </h1>
october 1, 2020<br>
#systemdiagram #gamemechanics<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>
<br>
<center><img src="/static/img/ent/systemdiagram_inventory.jpeg" alt="(image: system diagram for inventory)" width="500" height="250"></center> <br>
<br>
<br>
<h2>stop + plan before coding </h2>
I want to move blessfrey's inventory into an app on the player character's smartphone. Before, it was displayed in a random pop-up window. It was poorly planned, so the programmatic inventory and the UI were tightly coupled so I couldn't just pop it into the phone. Instead of wrestling, it's easier to start over and actually plan before I code this time. <br>
<br>
<br>
<h2>list out your nouns </h2>
A simple way to start thinking about a system is to list out its nouns and verbs. Jot down the entities that interact with your system. <br>
<br>
For blessfrey's inventory, that's the inventory (programmatic), the player character, the inventory app (UI), and base items. The inventory app is related to the smartphone and inventory items. Items are related to floor items, which are related to rooms. <br>
<br>
(blessfrey has three different kinds of items. <b>Base Items</b> are the code, which hold all the data relevent for the item no matter how it's expressed. <b>Floor Items</b> are the version that sit on the ground and get picked up by characters. <b>Inventory Items</b> are the version that are displayed in inventories, store windows, containers, etc. Floor and Inventory Items hold a base item inside them, that gets popped out and traded around as the item needs to be expressed in different forms.) <br>
<br>
<br>
<h2>connect your nouns with verbs </h2>
I wrote the entities in pink and moved them around until the placement was decently readable. Then I connected the concepts with arrows. These arrows represent the verbs, which I explicitly labeled in yellow. <br>
<br>
The flow of these arrows can be very important. If you are modeling AI, for instance, no matter what path the program takes, there shouldn't be dead-ends. Seeing mistakes like that is easier with a diagram than lines of code. Otherwise, the flow is generally useful for figuring out which methods are needed for each class and how they connect. <br>
<br>
<br>
<h2>write the code </h2>
At this point, coding is a bit easier, now that it's in some ways a transcription of the diagram. The entities are data (classes or objects) and the arrows are logic (methods). <br>
<br>
<br>
<h2>conclusion </h2>
Your diagram doesn't have to be too fancy or formal to get the point across to yourself, and it just takes a minute to save all the headache later. Don't skip this step or you'll have to rewrite the inventory system just to display it in a different window. <br>
<br>

@ -1,9 +0,0 @@
<!--200902,201001-->
<h1>web development resources</h1>
october 10, 2020<br>
accessibility, color, css, html, web design<br>
<br>
<ul>
<li><a href="https://validator.w3.org/nu/#textarea">W3's Nu Html Checker</a> - automatically check the validity of your html + css.</li>
<li><a href="https://webaim.org/resources/contrastchecker/">WebAIM's Contrast Checker</a> - check whether your font color contrasts well against your background color, at least in the eyes of a computer</li>
<li><a href="https://coolors.co/75dbcd-c9dbba-dcdba8-f5cda7-faa381">Coolors</a> - select and lock colors then generate palettes by pressing space. Click on a color to view shades + tints, so you can tweak contrast without losing hues.</li>

@ -0,0 +1,13 @@
<!--201224,200806-->
<h1>web development resources</h1>
october 15, 2020<br>
#accessibility #color #css #html #webdesign<br>
<br>
I'll collect frequently used resources for web design here. <br>
<br>
<ul>
<li><a href="https://cssgrid-generator.netlify.app/"><b>CSS Grid Generator</b></a> - build a basic CSS Grid by changing the number of columns + rows, adjusting their dimensions, and adding containers. </li>
<li><a href="https://validator.w3.org/nu/#textarea"><b>W3's Nu Html Checker</b></a> - automatically check the validity of your html + css. </li>
<li><a href="https://webaim.org/resources/contrastchecker/"><b>WebAIM's Contrast Checker</b></a> - check whether your font color contrasts well against your background color, at least in the eyes of a computer. </li>
<li><a href="https://coolors.co/75dbcd-c9dbba-dcdba8-f5cda7-faa381"><b>Coolors</b></a> - select and lock colors then generate palettes by pressing space. Click on a color to view shades + tints, so you can tweak contrast without losing hues. </li>
</ul>

@ -0,0 +1,65 @@
<!--201001,201112-->
<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>

@ -1,7 +1,7 @@
<!--200831,200931--> <!--200930,201130-->
<h1>october 2020: a blog that works</h1> <h1>october 2020: a blog that works</h1>
october 31, 2020<br> october 31, 2020<br>
css, html, python, website<br> #css #html #python #webdev #website<br>
<br> <br>
<h2>week 1 </h2><br> <h2>week 1 </h2><br>
bottle, python, regular expressions, website <br> bottle, python, regular expressions, website <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 @@
<!--201210,201029-->
<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 @@
<!--200806,200903-->
<h1>pretendOS - a game inspired by windows XP </h1>
november 26, 2020<br>
#sideproject<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,29 @@
<!--200831,200931-->
<h1>november 2020: dear diary </h1>
november 30, 2020<br>
#blogging #bottle #skills #webdev<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>

@ -0,0 +1,43 @@
<!--200810-->
<h1>blessfrey graphic updates + mockups </h1>
december 24, 2020<br>
#mockups #screenshots<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>
<br>
<center>
<a target="_blank" href="/static/img/ent/screenshot_August152018.jpeg">
<img src="/static/img/ent/screenshot_August152018.jpeg" alt="(image: Cassia and Bad Cat on the pink carpet tilemap)" width="500" height="313">
</a><br>
August 15, 2018 - Early experimenting with Godot Engine. Collision was just added for sprites and walls. The buttons to the right are for switching between characters (who each have different skillbars). <br>
<br><br>
<a target="_blank" href="/static/img/ent/screenshot_January132019.jpeg">
<img src="/static/img/ent/screenshot_January132019.jpeg" alt="(image: Angel in a periwinkle room full of Bad Cats)" width="500" height="330.72">
</a><br>
January 13, 2019 - Videogame perspective is so different from perspective in illustration. Scale of characters vs environment is another quirk of games I had 0 experience with. I was vaguely going for an old Western RPG style with tall, somewhat realistic sprites with nondistinct faces. Something like Divine Divinity. <br>
<br><br>
<a target="_blank" href="/static/img/ent/screenshot_April232019.png">
<img src="/static/img/ent/screenshot_April232019.png" alt="(image: Angel blasting a neighborhood coyote with fire)" width="500" height="375">
</a><br>
April 23, 2019 - This is a mockup, but the game did look like this for a while. The fireball projectile didn't come until later, though. Here, I was trying to get a little more of a top-down view but not really. Instead of cats, Angel's fighting with a coyote. The government stopped removing coyotes from my old neighborhood, so they killed all the neighborhood cats except one and I saw him running away from a big coyote during a storm, so maybe he's gone now, too. It's just not right. <br>
<br><br>
<a target="_blank" href="/static/img/ent/screenshot_May252019.png">
<img src="/static/img/ent/screenshot_May252019.png" alt="(image: Angel and Chloe in front of a slanted house)" width="500" height="375.18">
</a><br>
May 25, 2019 - The slanted edition was so annoying. It's not isometric, it's just at an obscure angle because I drew these assets more for fun than to actually be practical. I do reuse the tree + bushes a lot, though. I also tried a more chibi sprite because they are soo common, might as well try it out. <br>
<br><br>
<a target="_blank" href="/static/img/ent/screenshot_June292019.png">
<img src="/static/img/ent/screenshot_June292019.png" alt="(image: Lots of Angels and other characters at a shopping center)" width="500" height="278.66">
</a><br>
June 29, 2019 - Trying a shopping center level now. It's reeally spaced apart. It's inspired by a real shopping center;; <br>
<br><br>
<a target="_blank" href="/static/img/ent/screenshot_July252020.png">
<img src="/static/img/ent/screenshot_July252020.png" alt="(image: Angel and some slimes in a cavern)" width="500" height="281.04">
</a><br>
July 25, 2020 - There's some missing in this gap, so I'll add in more pics if I find any. This is the first version of a cavern level for the blessfrey demo. It's inspired by local caves. <br>
<br><br>
</center>
<h2>you're up to date.</h2>
<br>
Hope you enjoyed seeing the different art I've used for blessfrey over the years. Even if I never really polish anything, it's nice to iterate to get a sense of game art and blessfrey's personal style. Hopefully it ends up looking okay okay when I do start polishing. But until then, in the words of YandereDev, "All art is placeholder."<br>
<br>

@ -0,0 +1,28 @@
<!--200810-->
<h1>my favorite GDC talks </h1>
january 7, 2020<br>
#gamedesign #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>

@ -1,13 +1,13 @@
import datetime, os, re import datetime, os, re
from bottle import error, response, route, run, static_file, template, TEMPLATE_PATH from bottle import error, response, route, run, static_file, template, TEMPLATE_PATH
# List up to 3 recommended articles for current article
def list_rec(page): def list_rec(page):
loc = 'diary/entries/' loc = 'diary/entries/'
result = [] result = []
rec = [] rec = []
comment = "" comment = ""
if isinstance(page, int): if isinstance(page, int):
# Collect recommended articles from comment line
with open('diary/entries/' + str(page)) as f: with open('diary/entries/' + str(page)) as f:
comment = f.readline() comment = f.readline()
comment = comment.replace('<!--','') comment = comment.replace('<!--','')
@ -15,14 +15,19 @@ def list_rec(page):
comment = comment.replace(' ','') comment = comment.replace(' ','')
comment = clean(comment) comment = clean(comment)
rec = comment.split(',') rec = comment.split(',')
# Convert into array for template to display
for article in rec: for article in rec:
if is_it_time(article):
path = loc + article path = loc + article
data = [] data = []
try:
with open(path) as f: with open(path) as f:
f.readline() f.readline()
data.append(clean(f.readline().replace('<br>',''))) data.append(clean(f.readline().replace('<br>','')))
data.append(path) data.append(path)
result.append(data) result.append(data)
except EnvironmentError:
print("No article @ " + path)
return result return result
# List latest 5 articles as headline links # List latest 5 articles as headline links
@ -126,9 +131,15 @@ def clean(result):
result = result.replace('\n','') result = result.replace('\n','')
result = result.replace('<br>','') result = result.replace('<br>','')
result = re.sub(r'<a href=.*?>', '', result) result = re.sub(r'<a href=.*?>', '', result)
result = re.sub(r'<img src=.*?>', '', result)
result = re.sub(r'<a target="_blank" href=.*?>', '', result)
result = result.replace('</a>','') result = result.replace('</a>','')
result = re.sub(r'<h\d>','',result) result = re.sub(r'<h\d>','',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('<b>','')
result = result.replace('</b>','')
return result return result
# Return first 300 words of article + " ... " # Return first 300 words of article + " ... "
@ -144,15 +155,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
@ -182,13 +210,13 @@ 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 # Projects Page - Game Template - system, character, story info
@route('/game') @route('/projects')
def game(): def projects():
"""game page""" """projects page"""
info = {'css': 'game', 'title': 'blessfrey - about the game', 'year': datetime.datetime.now()} info = {'css': 'game', 'title': 'blessfrey - about the game', 'year': datetime.datetime.now()}
return template('game.tpl', info) return template('game.tpl', info)
@ -210,15 +238,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(curate_files(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 )
@ -229,7 +259,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 )

@ -12,7 +12,7 @@ ul { list-style-position: inside; }
.grid { .grid {
display: grid; display: grid;
grid-template-columns: auto 533px 267px auto; grid-template-columns: auto 533px 267px auto;
grid-template-rows: 25px 90px 40px repeat(2, auto); grid-template-rows: 25px 90px 40px auto 40px auto;
grid-column-gap: 0px; grid-column-gap: 0px;
grid-row-gap: 0px; grid-row-gap: 0px;
} }
@ -124,7 +124,7 @@ ul { list-style-position: inside; }
} }
.diary-dir {. .diary-dir {.
grid-area: 3 / 1 / 4 / 5; /* grid-area: 3 / 1 / 4 / 5; */
background-color: #080410; background-color: #080410;
color: #F9B3D7; color: #F9B3D7;
font-size: 20px; font-size: 20px;
@ -142,6 +142,9 @@ ul { list-style-position: inside; }
.diary-dir a:active { .diary-dir a:active {
color: #f463ad; color: #f463ad;
} }
.diary-dir.top {
grid-area: 3 / 1 / 4 / 5;
}
.body-row { .body-row {
grid-area: 4 / 1 / 5 / 5; grid-area: 4 / 1 / 5 / 5;
@ -237,8 +240,12 @@ ul { list-style-position: inside; }
padding-bottom: 15px; padding-bottom: 15px;
} }
.footer-row { .diary-dir.bottom {
grid-area: 5 / 1 / 6 / 5; grid-area: 5 / 1 / 6 / 5;
}
.footer-row {
grid-area: 6 / 1 / 7 / 5;
background-color: #080410; background-color: #080410;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 KiB

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: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 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: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -3,6 +3,69 @@
<br><br> <br><br>
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>
<h1>Website To-Do</h1>
<ul>
<li>Write some diary entries</li>
<li>Make sure their dates + filenames match</li>
<li>Make sure their tags are formatted correctly</li>
<li>Proofread</li>
<li>Make sure their formatting is consistent</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>
<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>
<li>2/28 - DIARY</li>
<li>3/31 - DIARY</li>
</ul>
<br>
<br>
<h1>Try to Do...</h1>
<h2>Weekly, Monthly</h2>
<ul>
<li>Keep monthly journal up to date</li>
<li>Add an article every week or two</li>
<li>Convert old infographics into articles</li>
</ul>
<h2>Sometime</h2>
<ul>
<li>Update Trello and share it</li>
<li>Diary - Add snippet art assets</li>
<li>Game - Add slideshow for story</li>
<li>Graphics - Concept Art</li>
<li>Graphics - Character Sheets</li>
<li>Graphics - Screenshots, GIFs</li>
<li>Graphics - Music</li>
<li>Graphics - Trailer</li>
<li>Presskit - Make a downloadable PDF version</li>
<li>Just...better art and writing for everything...</li>
</ul>
<br>
<br> <br>
<h1>Articles, Resources</h1> <h1>Articles, Resources</h1>
<ul> <ul>
@ -12,18 +75,79 @@
<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>Web Design</h1> <br>
<ul> <h1>Lowest Sale Price</h1>
<li>https://www.otomate.jp/home/game/ - any of their games. so pretty</li> <table>
<li>https://www.otomate.jp/amnesia/switch/</li> <tr>
<li>https://www.otomate.jp/varibarri/</li> <th>Regular Price</th>
<li>https://www.otomate.jp/tierblade/fd/</li> <th>Sale Price</th>
<li>https://www.otomate.jp/chouchoujiken/</li> <th>Brand</th>
<li>https://www.otomate.jp/bw_alice/</li> <th>Product</th>
<li>https://www.otomate.jp/psychedelica/aa-nisus/</li> <th>URL</th>
<li>https://www.otomate.jp/collar_malice/</li> </tr>
<li>https://www.otomate.jp/bw_alice/twilight/</li> <tr>
<li>https://www.nintendo.co.jp/n08/agfj/index.html</li> <th>$24</th>
</ul> <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>

@ -16,6 +16,8 @@
<h1>latest</h1> <h1>latest</h1>
<div class="latest-text"> <div class="latest-text">
<ul> <ul>
% if len(latest) > 0:
% print(str(len(latest)))
% for l in latest: % for l in latest:
<li>&#9;<a href=/{{l[0]}} rel="nofollow">{{!l[1]}}</a></li> <li>&#9;<a href=/{{l[0]}} rel="nofollow">{{!l[1]}}</a></li>
% end % end

@ -1,7 +1,7 @@
% rebase('frame.tpl') % rebase('frame.tpl')
% import re % import re
<div class="dir-row"> </div> <div class="dir-row"> </div>
<div class="diary-dir"> <div class="diary-dir top">
<center> <center>
% max_pages = int((total - 1) / limit) % max_pages = int((total - 1) / limit)
<% <%
@ -91,5 +91,65 @@
</div> </div>
% end % end
</div> </div>
<div class="diary-dir bottom">
<center>
% max_pages = int((total - 1) / limit)
<%
# page never below 0
if page <= 0:
page = 0
end
# page never over maximum
if page > max_pages:
page = max_pages
end
%>
% # << is always active link pointing to 0
<a href=/diary/0 rel="nofollow">&lt;&lt;</a>
% # < points to 0 if page 0 or below
% if page <= 0:
<a href=/diary/0 rel="nofollow">&lt;</a>
% # < points to previous page otherwise
% else:
<a href=/diary/{{page - 1}} rel="nofollow">&lt;</a>
% end
% # fill out number cluster to the left when page is high
% if max_pages > cluster and page > max_pages - cluster:
% for j in range(cluster - max_pages + page):
<a href=/diary/{{max_pages - cluster * 2 + j}} rel="nofollow">{{max_pages - cluster * 2 + j}}</a>
% end
% end
% # form cluster of number links around page
% for i in range(max(0,page - cluster), min(max_pages + 1,page + cluster + 1)):
% # bold current page number
% if i == page:
<b>{{i}}</b>
% # form neighboring numbers into links
% else:
<a href=/diary/{{i}} rel="nofollow">{{i}}</a>
% end
% end
% # fill out number cluster to the right when page is low
% if page <= cluster - 1 and max_pages > page + cluster:
% for j in range(cluster - page):
<a href=/diary/{{page + j + cluster + 1}} rel="nofollow">{{page + j + cluster + 1}}</a>
% end
% end
% # > points to max if page is at or above maximum
% if page >= max_pages:
<a href=/diary/{{max_pages}} rel="nofollow">&gt;</a>
% # > point to next page otherwise
% else:
<a href=/diary/{{page + 1}} rel="nofollow">&gt;</a>
% end
% # >> is always active link to maximum page
<a href=/diary/{{max_pages}} rel="nofollow">&gt;&gt;</a>
</center>
</div>
% include diary-boxes.tpl % include diary-boxes.tpl

@ -13,6 +13,7 @@
<div class="more"><h1>more like this...</h1></div> <div class="more"><h1>more like this...</h1></div>
% end % end
<div class="rec-box"> <div class="rec-box">
% if len(recommends) > 0:
% for s in recommends: % for s in recommends:
<div class="snip"> <div class="snip">
<div class="snippet-title"> <div class="snippet-title">
@ -20,6 +21,7 @@
</div> </div>
</div> </div>
% end % end
% end
</div> </div>
</div> </div>

@ -15,7 +15,7 @@
<img src="/static/img/btn/skillbtn.png" alt="game" style="width:85px;height:55px;"> <img src="/static/img/btn/skillbtn.png" alt="game" style="width:85px;height:55px;">
</a> </a>
<div class="nav-link"> <div class="nav-link">
<a href="/game">game</a> <a href="/projects">projects</a>
</div> </div>
</div> </div>
<div class="nav-diary"> <div class="nav-diary">

Loading…
Cancel
Save