⬆️ ⬇️

Calltracking in Minecraft or how to quickly make a three-dimensional UI

A couple of months ago, I showed Minecraft to children, and a little later, I bought them a book on programming in MineCraft. True, the children bought ches-word. Well, he took a look, well, wrote a couple of scripts ...



At this point, the story would have stopped, but the other day I had the opportunity to participate in the hackathon of a single calltracking service. For those who do not know, calltracking is such a thing that provides call statistics. And what is important for our history is that these statistics are available by API.



At this moment, the separate parts formed into a whole picture and I thought - oh! call statistics in Minecraft.

')





Well, the hackathon format has to insane ideas, but this idea seemed crazy enough to be realized.



But seriously - who said that the interfaces should be two-dimensional?

And who said that the three-dimensional interface is long and difficult?

The whole idea took 3 hours (57 lines on the python), given that for the first half hour I understood how to parse the python parsons Jason.



Under the cut - the whole story, the video with the result and the bonus for those who read it to the end - all 3 hours of development in a 3-minute time-lapse video.



To make it all work, it took me 3 simple steps:



1. We lift the Minecraft server which allows to interact with the world of Minecraft on API on Python

2. We take call statistics by calltracking API

3. Create cubes in Minecraft.



Ok, let's go!



1. Minecraft server



The minecraft server with the beautiful name bukkit was already ready for me (you can download it from the book’s website along with very detailed video instructions).

The game version is 1.6.4, we will write scripts in Python, since this server understands them.



2. We take the statistics of calls by API



Here, too, everything is simple, a couple of lines on the python and everything is ready:



import json, requests data = requests.get("https://istat24.com.ua/api/{your_api_key}/calls.json?counter_start_date=2016-02-01&counter_end_date=2016-02-05") json = json.loads(data.content) 


A few words about the API itself.



I use the API calltracking service of iStat24 (in the development department of which this same hackathon took place), it returns the call log to JSON, and to get the data for a specific account you need to generate API_key in this account, which I had prepared for the hackathon in advance.



An example of a call from JSON:



 { call_id: 5555555, numberA: "380555555555", numberB: "380555555555", start: "2016-02-05 15:11:13", duration: "00:03:57", wait_duration: "00:00:07", speak_duration: "00:03:50", record: "http://url_to_the_audio_record.mp3", accepted: 1, direction: "incoming", reklama_name: "Google organic", reklama_id: 729 } 


From all this we are interested in:

wait_duration - call waiting time (beeps, in short)

speak_duration - talk time

accepted - the value 1/0 determines if the call was accepted or missed.



Total, we have an array of calls. Now it remains only to present them visually.



3. Create cubes in Minecraft



Before that, everything was simple, right? not even easy - trivial.

You probably think some magic will start from this place? And no.

The fact is that everything is written before us.

There is a wonderful python library - minecraftstuff , which can do all the basic things in Minecraft.

We only need to describe where and what type of cube we want to create.



We connect and initialize the library:



 import mcpi.minecraft as minecraft import mcpi.block as block import mcpi.minecraftstuff as minecraftstuff mc = minecraft.Minecraft.create() mcdrawing = minecraftstuff.MinecraftDrawing(mc) 


Now coordinates. Minecraft is a three-dimensional world, so obviously we need x, y and z.

You can take the current coordinates of the character with the mc.player.getTilePos () command, but I decided to hardcover a certain place in the Minecrft world (simply because after each iteration I needed to clear the entire space with the previous attempt of “building”.) For debug it’s more convenient, in general



The cube is drawn with the mc.setBlock command (x, y, z, blockType).



How to remove the cube? As it turned out - the air in Minecraft is also a cube. Therefore, instead of removing the cubes - you just need to draw the cubes with air. You can do this individually using the same mc.setBlock command (x, y, z, block.AIR.id) - indicating the block type “block.AIR.id”. And you can use the command mc.setBlocks () which clogs a rectangular area with cubes of the desired type. The book says that it is faster than drawing cubes one by one.



In the end, I got this code to clean the space:



 mc.postToChat("START") startX=146; startY=0; startZ=-30 //    # Clean up mc.setBlocks(startX-2, startY-20, startZ+5, startX+2, startY+200, startZ-250, 8) time.sleep(2) mc.setBlocks(startX-3, startY-1, startZ+6, startX+3, startY+210, startZ-551, block.AIR.id) time.sleep(2) # cleanUp(pos.x, pos.y, pos.z, 40) # Clean up self mc.postToChat("Clean up is done") 


Livehack Here I first fill the space with dice with ID = 8 and then I fill the same space with air.

This is done solely for debug, so that you can see exactly which area will be cleared after 2 seconds. Otherwise, it is absolutely not obvious and takes a lot of time to guess the necessary coordinates.



In general, this whole section of code can be replaced with just one command: mc.setBlocks (startX-3, startY-1, startZ + 6, startX + 3, startY + 210, startZ-551, block.AIR.id), everything else only for debug.



To make it more beautiful, I decided that each call would be presented in the form of a tower 2 cubes wide (and thick) - and the duration of the bell would be represented by the height of the tower (1 second = 1 cubic). Therefore, a simple procedure that draws a tower of a given height:



 def drawCall(x, y, z, length, blockType): length = (length, 200)[length>200] for i in range(y, y+length): mc.setBlock(x, i, z, blockType) mc.setBlock(x+1, i, z, blockType) mc.setBlock(x+1, i, z+1, blockType) mc.setBlock(x, i, z+1, blockType) 


Note that distortion is built into it - because the height of the world in Minecraft, as it turned out, is 255 cubes, so if the call was longer than 255 seconds (and there are of course many), they go above the “roof of the world” and continue from the “bottom of the world “Which is certainly not aesthetic.



Now we have everything ready to draw calls.

Just go over the array of calls received from the API and draw towers (using cubes of different types to visually represent call waiting time, talk time and missed calls - in red).



 for call in json: offset+=3 duration = get_sec(call['duration']) wait_duration = get_sec(call['wait_duration']) speak_duration = get_sec(call['speak_duration']) if call['accepted'] == 1: drawCall(startX, startY, startZ-offset, wait_duration, 41) # wait_duration drawCall(startX, startY+wait_duration, startZ-offset, speak_duration, 133) #speak_duration else: drawCall(startX, startY, startZ-offset, duration, 152) # duration 




That's all, go to minecraft and admire the three-dimensional statistics of calls.



By the way, I recorded one video myself, and the second one was recorded by a child. Guess what where?







Yellow cubes - waiting time (beeps), green - talk time, red - missed call.



[ Script source in Python ]



And the promised at the beginning of the post video 3 hours of development compressed to 3 minutes:







And finally, the question, what processes / data, in your opinion, would look better in three-dimensional form?

Offhand:

- Dashboards for displaying production servers, in case of any of them falling - the script automatically adds a dynamite cube and blows it up :) if Minecraft is brought to the office monitor and the volume is adjusted loudly - it should be impressive.

Any more ideas?

Source: https://habr.com/ru/post/278995/



All Articles