{"id":51084,"date":"2012-01-12T02:44:44","date_gmt":"2012-01-12T02:44:44","guid":{"rendered":"http:\/\/barrycarlyon.co.uk\/wordpress\/?p=51084"},"modified":"2015-02-11T03:45:23","modified_gmt":"2015-02-11T03:45:23","slug":"minecraft-math","status":"publish","type":"post","link":"https:\/\/barrycarlyon.co.uk\/wordpress\/2012\/01\/12\/minecraft-math\/","title":{"rendered":"MineCraft Math"},"content":{"rendered":"<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/barrycarlyon.co.uk\/wordpress\/wp-content\/uploads\/2012\/01\/MinecraftLogo.png?resize=248%2C46\" alt=\"\" title=\"MinecraftLogo\" width=\"248\" height=\"46\" class=\"alignright size-full wp-image-51088\" \/><\/p>\n<p>So, I tend to now and again do random bits and pieces to MineCraft Servers.<\/p>\n<p>Of late I have been working with <a href=\"http:\/\/ZimDoorCraft.tk\/\">ZimDoorCraft<\/a>, took the existing relatively static site, and flipped it over to a Mini PHP Powered Content Management System, that I wrote and roll out to smaller sites.<br \/>\nCouple of MySQL powered bits to make updates easier (Staff list and the like).<\/p>\n<p>In time more complex and interesting things will be added (it was for a while running a Login with Mojang\/MineCraft account, but that means you type your MineCraft login into the site&#8230;), how that works is a subject for another post. As is what ever I build next \ud83d\ude00<\/p>\n<p>The MineCraft server in this case is running a derivative of Bukkit, which means it supports plugins, so we are using the JSON Api plugin, and making a call to the getWorld() data resource.<br \/>\nWhich passes back information about the world in a nice handy format.<\/p>\n<p>Heres an example<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n    &#x5B;world] =&gt; stdClass Object\r\n        (\r\n            &#x5B;remainingWeatherTicks] =&gt; 14670\r\n            &#x5B;hasStorm] =&gt; \r\n            &#x5B;time] =&gt; 4964\r\n            &#x5B;environment] =&gt; normal\r\n            &#x5B;isThundering] =&gt; \r\n            &#x5B;name] =&gt; world\r\n            &#x5B;fullTime] =&gt; 2903932964\r\n        )\r\n<\/pre>\n<p>If your running Vanilla you can grab the same information just by decoding the level.dat file in the World Directory, however opening a file currently being written to, is not often a good idea, and the level.dat is written to a lot.<\/p>\n<p>Like a lot of games, Minecraft uses ticks, in this case operating at 20 ticks per second, and running to 24000 ticks per Minecraft day, which means a Minecraft day is about 20mins.<\/p>\n<p>Just to be interesting 0 ticks is Sunrise, rather than midnight. And midnight itself is 18000 ticks.<\/p>\n<p>Also contained in the data packet is a count down to when the weather changes, in this case there are 7500 (ish) ticks to go.<\/p>\n<p>Which works out as<\/p>\n<p>14670 \/ 20 to get Real Seconds = 733.5 Seconds, and then its arbitrary to flip this to a human readable time. We have about 12 minutes, or half a MineCraft day, until the weather changes.<\/p>\n<p>Reading out a more recent packet<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n    &#x5B;world] =&gt; stdClass Object\r\n        (\r\n            &#x5B;remainingWeatherTicks] =&gt; 7339\r\n            &#x5B;hasStorm] =&gt; 1\r\n            &#x5B;time] =&gt; 3827\r\n            &#x5B;environment] =&gt; normal\r\n            &#x5B;isThundering] =&gt; \r\n            &#x5B;name] =&gt; world\r\n            &#x5B;fullTime] =&gt; 3902379827\r\n        )\r\n<\/pre>\n<p>Looks like there is a storm on&#8230;. But its only Rain no Thunder and Lighting. With 6 mins to go.<\/p>\n<p><strong>On a side note!<\/strong>, watch out for FullTime, as its likely to run away, on a long running server, to something a 32 bit system might not be able to handle! Refer to my Post on <a href=\"http:\/\/barrycarlyon.co.uk\/wordpress\/2011\/11\/01\/facebook-credits-the-order-id-and-dealing-with-large-integers-in-32-bit-php\/\">Facebook and the Order ID<\/a> on some thoughts about dealing with that.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/barrycarlyon.co.uk\/wordpress\/wp-content\/uploads\/2012\/01\/ZimDoorCraft.jpg?resize=237%2C90\" alt=\"\" title=\"ZimDoorCraft Time and Weather\" width=\"237\" height=\"90\" class=\"alignright size-full wp-image-51085\" \/><br \/>\nUsing Tick to Seconds math, means that it is also possible to display the current server time and weather on the website.<\/p>\n<p>I&#8217;m using a bit of CSS, and the MineCraft time piece (craftable in game) to show the current time visually. In this case I&#8217;ve taken the 16&#215;16 PNG&#8217;s and expanded them (by hand) to 32&#215;32, finally converting the time from ticks to the relevant chunk of 360 degrees, offsetting as needed to account for the fact that Sunrise is 0 instead of Midnight.<\/p>\n<p>I do this by adding 6000 ticks and from there treating the ticks complete as a percentage and scaling to meet 360 degrees. Some of the code involved needs a little tweaking and tidying to improve efficiency, but the angle is being calculated by a CRON Job powered script and stored with the full World JSON packet, in an extended object and cached in a file on the file system ready to be read by the web server when a request comes in. So it&#8217;s not a top priority to clean up yet.<\/p>\n<p>I was finding that after taking into account the addition 6000 ticks to offset for Sunrise, the whole Sun Moon picture was upside down. So I just added 180 degrees, and corrected it when the angle was greater that 360. Since why bother rotating thru a whole 360 degrees?<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n\r\n$time = $world-&gt;time;\/\/ grab from data packet from JSON Api Call\r\n$time += 6000;\/\/ add 600 for sunrise\r\n\r\n\/\/ work out the scale factor 360 degrees \/ ticks in a Minecraft day\r\n$scale = 360 \/ 24000;\r\n$angle = $scale * $time;\/\/ calculate the &lt;span class=&quot;hiddenGrammarError&quot; pre=&quot;&quot;&gt;&lt;span class=&quot;hiddenGrammarError&quot; pre=&quot;&quot;&gt;&lt;span class=&quot;hiddenGrammarError&quot; pre=&quot;&quot;&gt;angle\r\n$angle&lt;\/span&gt;&lt;\/span&gt;&lt;\/span&gt; = number_format($angle, 0);\/\/ clean up\r\n\/\/ correct\r\n$angle = $angle + 180;\/\/ the image is upside down :-(\r\nif ($angle &gt;= 360) {\/\/ clean up again\r\n\t$angle -= 360;\r\n}\r\n<\/pre>\n<p>The rotation component was quite difficult to initially decide how to do, PHP wasn&#8217;t quite cutting it so switched to a CSS Transform.<br \/>\nHTML wise it consists of a pair of divs, a pair of images, and a chunk of CSS.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;div class=&quot;worldtime&quot;&gt;&lt;div class=&quot;inner&quot;&gt;&lt;\/div&gt;&lt;\/div&gt;\r\n<\/pre>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/barrycarlyon.co.uk\/wordpress\/wp-content\/uploads\/2012\/01\/large_inner.png?resize=32%2C32\" alt=\"\" title=\"Sun\/Moon\" width=\"32\" height=\"32\" class=\"alignright size-full wp-image-51086\" \/><br \/>\nWorldTime being the one behind contains the Sun Moon Picture as a background image.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/barrycarlyon.co.uk\/wordpress\/wp-content\/uploads\/2012\/01\/large_watch.png?resize=32%2C32\" alt=\"\" title=\"Watch Overlay\" width=\"32\" height=\"32\" class=\"alignright size-full wp-image-51087\" \/><br \/>\nAnd Inner contains the Watch overlay also as a background image.<\/p>\n<p>Apply the CSS transformation to rotate the Sun Moon Picture is just a little nasty, because in rotating the Sun Moon picture it also rotated the overlay (inner).<br \/>\nI decided to apply rotation to the overlay, in the reverse direction (so just sticking a negative sign in front).<br \/>\nWorks quite well, but if you can think of a better way to spit out this with the rotation please comment below.<\/p>\n<p>Heres my current Style Code<\/p>\n<pre class=\"brush: css; title: ; notranslate\" title=\"\">\r\n&lt;style type=&quot;text\/css&quot;&gt;\r\n\t.worldtime .inner {\r\n\t\twidth: 32px;\r\n\t\theight: 32px;\r\n\t\tbackground: url('large_watch.png') left top no-repeat;\r\n\t    \/* CSS3 then proprietary code *\/\r\n\t    rotation: -336deg;\r\n\t    -webkit-transform: rotate(-336deg);\r\n\t    -moz-transform: rotate(-336deg);\r\n\t    filter: progid: DXImageTransform.Microsoft.BasicImage(-rotation=4);\r\n\t}\r\n\t.worldtime {\r\n\t\tfloat: left;\r\n\t\twidth: 32px;\r\n\t\theight: 32px;\r\n\t\tmargin: 0 10px;\r\n\t\tbackground: url('large_inner.png') left top no-repeat;\r\n\t    \/* CSS3 then proprietary code *\/\r\n\t    rotation: 336deg;\r\n\t    -webkit-transform: rotate(336deg);\r\n\t    -moz-transform: rotate(336deg);\r\n\t    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=4);\r\n\t}\r\n&lt;\/style&gt;\r\n<\/pre>\n<p>The whole WorldTime Div is then wrapped in another Div and jQuery used to once per minute go and fetch the updated time, weather and CSS rotation.<\/p>\n<p>At first I did try using the PHP function to rotate the image, but the quality drop off when rotating by an angle not divisible by 90 was shocking.<br \/>\nSo ended up resorting to CSS, which does work a hell of a lot better.<\/p>\n<p>This only covers how to do this using the JSON API, in a future post I&#8217;ll talk about decoding level.dat and other Minecraft Files.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, I tend to now and again do random bits and pieces to MineCraft Servers. Of late I have been working with ZimDoorCraft, took the existing relatively static site, and flipped it over to a Mini PHP Powered Content Management System, that I wrote and roll out to smaller sites. Couple of MySQL powered bits &hellip; <a href=\"https:\/\/barrycarlyon.co.uk\/wordpress\/2012\/01\/12\/minecraft-math\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;MineCraft Math&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[88,45,232],"tags":[220,242,210,239,241,234,238,233,235,106,222,240,236,334,84,237],"class_list":["post-51084","post","type-post","status-publish","format-standard","hentry","category-code-geekery","category-geekery","category-minecraft","tag-32-bit","tag-ajax","tag-api","tag-bukkit","tag-crn","tag-css3","tag-html","tag-image-manipulation","tag-image-rotation","tag-jquery","tag-json","tag-json-api","tag-math","tag-minecraft","tag-php","tag-tick"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/comments?post=51084"}],"version-history":[{"count":6,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51084\/revisions"}],"predecessor-version":[{"id":51694,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/posts\/51084\/revisions\/51694"}],"wp:attachment":[{"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/media?parent=51084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/categories?post=51084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/barrycarlyon.co.uk\/wordpress\/wp-json\/wp\/v2\/tags?post=51084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}