{"id":80,"date":"2015-05-23T15:32:14","date_gmt":"2015-05-23T15:32:14","guid":{"rendered":"http:\/\/tale-of-tales.com\/Sunset\/blog\/?p=80"},"modified":"2015-06-18T11:51:16","modified_gmt":"2015-06-18T11:51:16","slug":"infinite-machinations","status":"publish","type":"post","link":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/2015\/05\/23\/infinite-machinations\/","title":{"rendered":"Infinite machinations"},"content":{"rendered":"<p><a href=\"http:\/\/Tale-of-Tales.com\/Sunset\">Sunset<\/a> is by far the most complicated thing we&#8217;ve created in Unity. When we made our first Unity game, <a href=\"http:\/\/Tale-of-Tales.com\/TheGraveyard\">The Graveyard<\/a>, we quickly realized that the tool was only going to be useful to us for making simple games. We came from the grand luxury of realtime visual programming offered by Quest3D with which we, artists and programming idiots, had built a multiplayer online game (<a href=\"http:\/\/Tale-of-Tales.com\/TheEndlessForest\">The Endless Forest<\/a>) and a horror game with semi-autonomous characters (<a href=\"http:\/\/Tale-of-Tales.com\/ThePath\">The Path<\/a>). The fact that Unity only offered script-based programming immediately meant that we had to dial down our ambitions. Our artist minds can perform magic with visuals but code makes our brains hurt. And compiling is the death knell for realtime creativity.<\/p>\n<p>Luckily in the mean time, the problem has been alleviated somewhat by Unity add-ons that at least offer the possibility to program visually (although realtime non-compiled programming is still not possible to my knowledge). <a href=\"http:\/\/Tale-of-Tales.com\/bientotlete\">Bient\u00f4t l&#8217;\u00e9t\u00e9<\/a> was programmed with Antares Universe and then recoded in Javascript for performance. <a href=\"http:\/\/Luxuria-Superbia.com\">Luxuria Superbia<\/a> ditto. Since we didn&#8217;t like having to recode things, we decided to give PlayMaker a chance when we started programming our first prototypes of Sunset.<\/p>\n<p>In the end we used a combination of PlayMaker FSMs, Javascript and C sharp code to make the whole thing run. Code looks infinitely boring and is hard to read but PlayMaker&#8217;s Finite State Machines make programming clear and fun. And the fact that it doesn&#8217;t need to check whether we put all our semicolons in the right places or didn&#8217;t misspell something means it&#8217;s a lot faster to work with (Unity&#8217;s recompiling of scripts each and every time you make the slightest change is quite unnerving in a big project like Sunset).<\/p>\n<h3>Spoilers!<\/h3>\n<p>So here&#8217;s some of the state machines that make Sunset tick.<\/p>\n<figure id=\"attachment_83\" aria-describedby=\"caption-attachment-83\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/session_title-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-83 size-large\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/session_title-FSM-1024x229.png\" alt=\"This is the title screen that show the date of the session that is about to start.\" width=\"604\" height=\"135\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/session_title-FSM-1024x229.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/session_title-FSM-300x67.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/session_title-FSM.png 1746w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-83\" class=\"wp-caption-text\">This is the title screen that shows the date of the session that is about to start.<\/figcaption><\/figure>\n<figure id=\"attachment_84\" aria-describedby=\"caption-attachment-84\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/start-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-84\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/start-FSM-1024x510.png\" alt=\"This is what happens when a session starts. Spoiler warning: ignore the right side of the graph if you're not very far in the game yet.\" width=\"604\" height=\"301\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/start-FSM-1024x510.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/start-FSM-300x149.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/start-FSM.png 1289w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-84\" class=\"wp-caption-text\">This is what happens when a session starts. Spoiler warning: ignore the right side of the graph if you&#8217;re not very far in the game yet.<\/figcaption><\/figure>\n<figure id=\"attachment_85\" aria-describedby=\"caption-attachment-85\" style=\"width: 941px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/thinking-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-85 size-full\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/thinking-FSM.png\" alt=\"This is the logic for looking around and thinking about things in view. The red blocks are actually not used anymore.\" width=\"941\" height=\"543\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/thinking-FSM.png 941w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/thinking-FSM-300x173.png 300w\" sizes=\"auto, (max-width: 941px) 100vw, 941px\" \/><\/a><figcaption id=\"caption-attachment-85\" class=\"wp-caption-text\">This is the logic for looking around and thinking about things in view. The red blocks are actually not used anymore.<\/figcaption><\/figure>\n<figure id=\"attachment_86\" aria-describedby=\"caption-attachment-86\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/touching-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-86 size-large\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/touching-FSM-1024x772.png\" alt=\"Similar to the above, this is the logic for touching things that you can interact with.\" width=\"604\" height=\"455\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/touching-FSM-1024x772.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/touching-FSM-300x226.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/touching-FSM.png 1027w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-86\" class=\"wp-caption-text\">Similar to the above, this is the logic for touching things that you can interact with. The yellow blocks on the left are a backup in case the object doesn&#8217;t know which text to show.<\/figcaption><\/figure>\n<figure id=\"attachment_87\" aria-describedby=\"caption-attachment-87\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/prompt_display-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-87\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/prompt_display-FSM-1024x710.png\" alt=\"Depending on the kind of thing that you touch, you get a different prompt.\" width=\"604\" height=\"419\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/prompt_display-FSM-1024x710.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/prompt_display-FSM-300x208.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/prompt_display-FSM.png 1134w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-87\" class=\"wp-caption-text\">Depending on the kind of thing that you touch, you get a different prompt.<\/figcaption><\/figure>\n<figure id=\"attachment_88\" aria-describedby=\"caption-attachment-88\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/activity-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-88\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/activity-FSM-1024x530.png\" alt=\"This is the logic that runs when you're doing a task, while the game shows the sun setting faster.\" width=\"604\" height=\"313\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/activity-FSM-1024x530.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/activity-FSM-300x155.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/activity-FSM.png 1234w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-88\" class=\"wp-caption-text\">This is the logic that runs when you&#8217;re doing a task, while the game shows the sun setting faster.<\/figcaption><\/figure>\n<figure id=\"attachment_89\" aria-describedby=\"caption-attachment-89\" style=\"width: 880px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/atmosphere-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-89\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/atmosphere-FSM.png\" alt=\"This pretty graph is run in the beginning of a session to initialize the time of day.\" width=\"880\" height=\"544\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/atmosphere-FSM.png 880w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/atmosphere-FSM-300x185.png 300w\" sizes=\"auto, (max-width: 880px) 100vw, 880px\" \/><\/a><figcaption id=\"caption-attachment-89\" class=\"wp-caption-text\">This pretty graph is run in the beginning of a session to initialize the time of day.<\/figcaption><\/figure>\n<figure id=\"attachment_90\" aria-describedby=\"caption-attachment-90\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/penthouse_ambience-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-90\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/penthouse_ambience-FSM-1024x331.png\" alt=\"To evoke a sensation of silence, Sunset uses a complex system of ambient room tones.\" width=\"604\" height=\"195\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/penthouse_ambience-FSM-1024x331.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/penthouse_ambience-FSM-300x97.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/penthouse_ambience-FSM.png 2041w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-90\" class=\"wp-caption-text\">To evoke a sensation of silence, Sunset uses a complex system of ambient room tones.<\/figcaption><\/figure>\n<figure id=\"attachment_91\" aria-describedby=\"caption-attachment-91\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/switch-sitting_standing-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-91\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/switch-sitting_standing-FSM-1024x469.png\" alt=\"This one helps us switch between standing up and sitting down. Had a lot of trouble with this little bugger.\" width=\"604\" height=\"277\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/switch-sitting_standing-FSM-1024x469.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/switch-sitting_standing-FSM-300x137.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/switch-sitting_standing-FSM.png 1089w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-91\" class=\"wp-caption-text\">This one helps us switch between standing up and sitting down. Had a lot of trouble with this little bugger.<\/figcaption><\/figure>\n<figure id=\"attachment_92\" aria-describedby=\"caption-attachment-92\" style=\"width: 912px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/system_cursor-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-92 size-full\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/system_cursor-FSM.png\" alt=\"Deciding when to show the cursor and when to hide it was a nightmare.\" width=\"912\" height=\"508\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/system_cursor-FSM.png 912w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/system_cursor-FSM-300x167.png 300w\" sizes=\"auto, (max-width: 912px) 100vw, 912px\" \/><\/a><figcaption id=\"caption-attachment-92\" class=\"wp-caption-text\">Deciding when to show the cursor and when to hide it is more complicated than one might expect.<\/figcaption><\/figure>\n<figure id=\"attachment_94\" aria-describedby=\"caption-attachment-94\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/save-session_end-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-94\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/save-session_end-FSM-1024x303.png\" alt=\"I love this one. The logic called at the beginning and the end of a session. It used to do a lot but many of its former functions got delegated.\" width=\"604\" height=\"179\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/save-session_end-FSM-1024x303.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/save-session_end-FSM-300x89.png 300w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-94\" class=\"wp-caption-text\">I love this one. The logic called at the beginning and the end of a session. It used to do a lot but many of its former functions got delegated.<\/figcaption><\/figure>\n<figure id=\"attachment_95\" aria-describedby=\"caption-attachment-95\" style=\"width: 604px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/text-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-95\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/text-FSM-1024x426.png\" alt=\"This is how you parse text visually. Drives real programmers crazy.\" width=\"604\" height=\"251\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/text-FSM-1024x426.png 1024w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/text-FSM-300x125.png 300w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/text-FSM.png 1888w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-95\" class=\"wp-caption-text\">This is how you parse text visually. Drives real programmers crazy.<\/figcaption><\/figure>\n<figure id=\"attachment_96\" aria-describedby=\"caption-attachment-96\" style=\"width: 878px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/exit_sequence-FSM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-96\" src=\"http:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/exit_sequence-FSM.png\" alt=\"And finally here's how you exit a session, when you're all done working for se\u00f1or Ortega.\" width=\"878\" height=\"330\" srcset=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/exit_sequence-FSM.png 878w, https:\/\/tale-of-tales.com\/Sunset\/blog\/wp-content\/uploads\/2015\/05\/exit_sequence-FSM-300x113.png 300w\" sizes=\"auto, (max-width: 878px) 100vw, 878px\" \/><\/a><figcaption id=\"caption-attachment-96\" class=\"wp-caption-text\">And finally here&#8217;s how you exit a session, when you&#8217;re all done working for se\u00f1or Ortega.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>I love how visual programming gives me an overview of the logic that helps me decide whether it is correct. Maybe it&#8217;s superstition but when a graph looks pretty I think the logic runs better. A good looking state machine cannot have bugs.<\/p>\n<p>Obviously some of the things above would be faster to program in code. If you know what you want before you start. And if you can keep a big game like Sunset in your head. But when experimenting or just forgetting about certain things, to me these graphical representations are much easier to read and much &#8220;lighter on the brain&#8221;. The excessiveness of some of the graphs helps me think about the logic. And the fact that you simply cannot make any typos in PlayMaker is a huge time saver. Now if they would only add realtime programming to Unity\u2026<\/p>\n<p>\u2014 Micha\u00ebl Samyn.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sunset is by far the most complicated thing we&#8217;ve created in Unity. When we made our first Unity game, The Graveyard, we quickly realized that the tool was only going to be useful to us for making simple games. We came from the grand luxury of realtime visual programming offered by Quest3D with which we, &hellip; <a href=\"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/2015\/05\/23\/infinite-machinations\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Infinite machinations<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-80","post","type-post","status-publish","format-standard","hentry","category-the-making-of"],"_links":{"self":[{"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/posts\/80","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":15,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"predecessor-version":[{"id":129,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions\/129"}],"wp:attachment":[{"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tale-of-tales.com\/Sunset\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}