diff --git a/src/diary/entries/210318 b/src/diary/entries/210318 index 1ce8352..ff3ce96 100644 --- a/src/diary/entries/210318 +++ b/src/diary/entries/210318 @@ -1,23 +1,16 @@ -

making an rss feed

+

generating an RSS feed with python bottle

march 18, 2021
-#rss #webdev
+#bottle #rss #webdev

-After a few months of quietly running my blog as practice, I want to start sharing my articles with other people. I looked over my favorite gamedev communities and saw that GameDev.net apparently allows you syndicate a blog through RSS. I never thought about making an RSS feed, so why not?
+After a few months of quietly running my blog as practice, I want to start sharing my articles with other people. I looked over my favorite gamedev communities and saw that GameDev.net apparently allows you to syndicate a blog through RSS. I never thought about making an RSS feed, so why not?

what is RSS?


-Before the massive centralized content platforms came into the mainstream, the internet was more like a constellation of individual websites. In lieue of algorithm-driven feeds + push notifications from major social media, RSS was designed to bring content from individuals into one place.
+Before the massive centralized content platforms came into the mainstream, the internet was more like a constellation of individual websites. In lieue of algorithm-driven feeds and push notifications from major social media, RSS was designed to bring content from scattered websites into one place.

-RSS and its predecessors have been around since the 90s. RSS 2.0 (what blessfrey.me uses) was published in 2002. Even through it's old and falling in popularity, it's still used by some large aggregator websites today like Google News
and Spotify.
+RSS and its predecessors have been around since the 90s. RSS 2.0 (what blessfrey.me uses) was published in 2002. Even through it's old and falling in popularity, it's still used by some large aggregators today like Google News and Spotify.

-RSS files themselves are written in XML. They should contain the latest 10-15 entries with their things like their title, link, summary, date, and author.
-
-

how to make an RSS feed


-Blogging platforms like WordPress already take care of the RSS feed, but there's no shortage of third-party RSS creators on the internet. Since I have already written code to display + summarize my articles on the diary page, the 'latest' box in the diary's sidebar, and the 'news' box on the index page, I'm confident the process for generating an XML file with the same info won't too different.
-
-Apparely I need a DOM or ElementTree or something -

examples of RSS feeds


-Here's a few examples from around the internet:
+Here's a few examples from around the internet, a mix of large + small news websites and forums:

+

what goes into an RSS feed?


+RSS files themselves are written in XML. They should contain the latest 10-15 entries along with things like their title, link, summary, date, and author.
+
+Blogging platforms like WordPress already take care of the RSS feed, but there's no shortage of third-party RSS creators on the internet. Since I have already written code to display + summarize my articles on the diary page, the 'latest' box in the diary's sidebar, and the 'news' box on the index page, I figure I can format the data one more time into an XML file.
+
+Here's truncated version of blessfrey.me's feed as an example (also available on Pastebin:
+
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0">
+<channel>
+<title>blessfrey.me</title>
+<link>https://www.blessfrey.me/</link>
+<description>chimchooree's dev space</description>
+<language>en-us</language>
+<webMaster>chimchooree@mail.com (chimchooree)</webMaster>
+<item>
+<title>making an rss feed</title>
+<link>https://www.blessfrey.me/diary/entries//diary/entries/210318</link>
+<description>After a few months of quietly running my blog as practice, I want to start sharing my articles with ... </description>
+<pubDate>Thu, 18 Mar 2021 8:05 CST</pubDate>
+<guid>https://www.blessfrey.me/diary/entries//diary/entries/210318</guid>
+</item>
+</channel>
+</rss>
+
+I'll explain each tag, but they are also described on the RSS Advisory Board's Best Practices Profile. There are more tags, too, so research documentation + examples to see what suits your website.
+
+

XML declaration


+Identifies the document as XML and defines the version + character encoding. It's required and must be the first line.
+
+

RSS


+The top-level element that defines version number. It's required.
+
+

channel


+Nested within the RSS tags and describes the RSS feed. It's required.
+
+There's some tags nested within the channel. Title, Link, and Description are required.
+
+ +
+

item


+Nested within the channel. Each article will be defined with the item.
+
+There's some tags nested within the item. Title, Link, and Description are required.
+
+ +
+

how to make an RSS feed


+I'm generating the RSS every time I update my website. That way, it always exists on the server and can be served as a static file. If I used a template, the RSS file would not exist unless it was accessed. I'm not sure if that would be an issue and haven't experimented.
+
+Since Bottle is just Python, I can generate the file similar to how I format my articles into diary snippets, pages, and headlines.
+
+I'll share the main code, but the full code can be viewed on Pastebin.
+
+

code example


+def make_rss():
+ loc = 'diary/entries/'
+ info = {'items': list_items(gather_and_sort(loc)[0:15])}
+
+# Return list of items
+def list_items(articles):
+ f_name = "static/xml/blessfrey.xml" # the RSS file
+ loc2 = 'https://www.blessfrey.me/'
+ loc = 'diary/entries/'
+ loc3 = loc2 + loc
+ result = []
+
+ for article in articles:
+ path = loc + article
+ text = []
+ a = []
+ length = 0
+ text = article2list(article, loc)
+ a.append(find_title(text))
+ a.append(find_url(path))
+ a.append(clean_tags(prepare_rss_summary(text, path)))
+ a.append(find_timestamp(text))
+ result.append(a)
+
+ clear_file(f_name)
+ f = open(f_name, 'w')
+ f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + '\n')
+ f.write("<rss version=\"2.0\">" + '\n')
+ f.write("<channel>" + '\n')
+ f.write("<title>blessfrey.me</title>" + '\n')
+ f.write("<link>https://www.blessfrey.me/</link>" + '\n')
+ f.write("<description>chimchooree's dev space</description>" + '\n')
+ f.write("<language>en-us</language>" + '\n')
+ f.write("<webMaster>chimchooree@mail.com (chimchooree)</webMaster>" + '\n')
+
+ for r in result:
+ f.write("<item>" + '\n')
+ f.write("<title>" + r[0] + "</title>" + '\n')
+ f.write("<link>" + loc3 + r[1] + "</link>" + '\n')
+ f.write("<description>" + r[2] + "</description>" + '\n')
+ code = r[1].replace(loc,'')
+ code = code.replace('/','')
+ f.write("<pubDate>" + format_rss_time(code) + "</pubDate>" + '\n')
+ f.write("<guid>" + loc3 + r[1] + "</guid>" + '\n')
+ f.write("</item>" + '\n')
+
+ f.write("</channel>" + '\n')
+ f.write("</rss>" + '\n')
+ f.close()
+
+ return result
+
+# Serve XML
+@route('/static/xml/<filename:path>')
+def serve_xml(filename):
+ return static_file(filename, root='static/xml', mimetype='text/xml')
+
+## Main ##
+
+if __name__ == '__main__':
+ make_rss()
+ run(host='127.0.0.1', port=9001)
+
+

double-check


+The RSS Advisory Board and W3C have feed validation services that can check the syntax of Atom or RSS feeds. It's nice to check but don't feel pressured to meet all the recommendations if they don't suit your needs.
+
+

double-check


+Now I have an RSS feed, available at https:/blessfrey.me/static/xml/blessfrey.xml. Feel free to use it if you prefer to read through an aggregator and contact me if there's technical problems.
+
+Last updated March 19, 2021
+
diff --git a/src/diary/entries/210401 b/src/diary/entries/210401 index 4304886..1cd7b6a 100644 --- a/src/diary/entries/210401 +++ b/src/diary/entries/210401 @@ -14,13 +14,13 @@ april 1, 2021

tuesday, march 2


wednesday, march 3

@@ -34,7 +34,7 @@ april 1, 2021

friday, march 5


saturday, march 6

@@ -43,7 +43,66 @@ april 1, 2021
  • I had an Old School RuneScape account under the official blessfrey email? lol why
  • When I get a working version of Blessfrey that has all the current features together again, I'll upload it to blessfrey.me and itch.io. It'd be nice to just have something up at all, even if it's not so great.
  • I also should start seriously thinking about making videos, streams, podcasts, etc. I have lots of gamedev experience to draw from now that could make okay video essays + tutorials. I just...need to learn how to make videos. I wonder how much effort it would take to make one video a month? That wouldn't be a great gamedev channel, but just the idea of having videos sounds nice. Streaming would be easier once all the pretty scenes and channel art is set up. The format's better suited towards "watch me code"-style content, so I could probably stream more often than release videos. It's just awkward to explain what you're doing and make mistakes and read documentation live.
  • -
  • Too bad the little-bitty streaming sites never stay around for long - I prefer streaming on the smaller, more engaged communities than on Twitch or Youtube any day. Rest in peace.
  • +
  • Too bad the little-bitty streaming sites never stay around for long - I prefer streaming on the smaller, more engaged communities than on Twitch or Youtube any day. Rest in peace, my favorite stream sites.
  • At the end of the day, I'm mostly looking to have fun. I don't really have anything I want to promote or sell right now, but I like talking to people about gamedev.

  • +

    monday, march 8

    + +
    +

    friday, march 12

    + +
    +

    saturday, march 13

    + +
    +

    sunday, march 14 - Pi Day

    + +
    +

    friday, march 19

    + +
    +

    saturday, march 20

    + +
    +

    friday, march 26

    + +
    +

    saturday, march 27

    + +
    +

    sunday, march 28

    + +
    +

    monday, march 29

    + +
    +Last Updated: April 2, 2021
    +
    diff --git a/src/diary/entries/210402 b/src/diary/entries/210402 new file mode 100644 index 0000000..8b33612 --- /dev/null +++ b/src/diary/entries/210402 @@ -0,0 +1,56 @@ + +

    a look into my achievement system

    +april 2, 2021
    +#achievements #knowledgebase
    +
    +Designing an achievement system without any octopus tangles.
    +
    +
    (image: an illustration of an octopus tangling up UI, Dialog, and other game systems.)

    +
    +

    what does blessfrey consider an achievement?


    +
    +An achievement is generally an objective used to create a metagame. They can vary in difficulty from an obscure discovery to repetitive use of mechanics to basic participation in the main story. Achievements can even be entirely external to the base game's system like The Stanley Parable's "Go outside" achievement, requiring you to not play for five years. Since achievements can be earned through any in-game system, the achievement system is closely tied to all other game systems.
    +
    +Completing an achievement usually awards a trophy, gamer points, or possibly something more practical, like a new game mode or an in-game item.
    +
    +Blessfrey feeds every in-game interaction through its achievement system, and its reward delivery is flexible enough not only to give a trophy but to cause anything to happen in response. Giving a trophy for finding a secret room is technically similar to gaining a Fire Resistance skill after standing on a bed of coals for 2 minutes or opening a new store after $1000 is spent at the mall. The only difference is actually notifying the player that an achievement was completed. Ironically, even though I ignore achievements in most games, Blessfrey's achievement system has become the backbone of player progression and world events.
    +
    +
    +

    how to design an achievement system


    +
    +Octopus-tangling is a major design concern for a system that is so interconnected with every other system. I could scatter achievement code through every other system, but that would be a problem if I ever need to make a fundamental change to the achievement system. Also, it will clutter the other systems if each system has a bunch of achievements tacked onto the bottom.
    +
    +Instead, Blessfrey's achievement system, the Knowledge Base, looks more like a mailman between game progress and the achievement system. A mailman Each granular action or world event that contributes to earning an achievement is called a piece of knowledge, which is identified by a key id number. Knowledge is categorized into topics. Event handlers subscribe to topics, waiting for news that a specific piece of knowledge has been encountered. The Knowledge Base itself stores all knowledge and facilitates the learning and forgetting of pieces of knowledge. Event handlers subscribed to the "knowledge_learned" topic will pay out awards. The MessageBus is the mailman that receives information about encountered knowledge and passes it off to all event handlers subscribed to that topic. The event handlers allow me to freely make and delete achievements, and the MessageBus keeps everything separate.
    +
    +
    +

    an example


    +
    +Let's say you get an achievement for finding the Nurse's Office. The moment the player loads into the Nurse's Office, data will zip back and forth between the MessageBus and the nurse's office object, different event handlers and the Knowledge Base.
    +
    +
      +
    1. (Event Handler) At ready, event handlers call the MessageBus and subscribe to topics.
    2. +
    3. (Nurse's Office) The player enters the Nurse's Office. The room object sends itself to the MessageBus.
    4. +
    5. (MessageBus) Receives room object + sends it to all event handlers subscribed to the "place_entered" topic.
    6. +
    7. (Event Handler) NursesOfficeEntered receives room object. If the room is the Nurse's Office, send its corresponding knowledge key to the MessageBus. It can also verify pre-requisites and gather additional data for the Knowledge Base. This way, the system supports anything I'd like to track about when or how knowledge was learned.
    8. +
    9. (MessageBus) Receives the knowledge key + sends it to the Knowledge Base.
    10. +
    11. (Knowledge Base) Finds the knowledge identified by the incoming key. "Learns" by setting that knowledge to true and filling in additional fields if extra data was sent. Sends the knowledge key to the MessageBus.
    12. +
    13. (MessageBus) Receives the knowledge key + sends it to all "learned" event handlers.
    14. +
    15. (Event Handler) KnowledgeLearned receives the knowledge key + calls code for any changes resulting from learning this knowledge. Maybe you'll get a Steam achievement, but if the Knowledge Base was being to facilitate game progression, a quest could update, the dialog system could unlock the option to ask about the Nurse's Office, or you could gain a Codex entry about the new location. The changes can be conditional, too, so the handler can track whether all necessary keys have been received before enacting the change.
    16. +

    +
    +To use the achievement system for cyclical world events, you could trigger knowledge to be "forgotten" or ultimately set back to false in the Knowledge Base. This way, the phases of an event could begin anew.
    +
    +
    +

    summary


    +
    +Achievements can come from any combination of in-game actions, so an achievement system should be designed separately from the rest of the game. I achieve this through a couple of separate objects.
    +
    +