Live telemetry: Health, position, inventory updates stream to all connected clients
WASD controls: Keyboard input via WebSocket, bot movement in <50ms
Mouse look: Right-click drag translates to bot camera rotation instantly
Multi-bot support: Switch between bots, all synced in real-time
3D world viewer: Watch your bot’s perspective update live via prismarine-viewer The Magic When you press W in the browser, it fires a WebSocket message. The server calls bot.setControlState(‘forward’, true). The bot moves. The 3D viewer updates. All in real-time, no HTTP requests, no polling. Try it yourself: http://mc.craycon.no:4000 (Control Center) | http://mc.craycon.no:3000 (Bot Viewer) PS: the secret auth token is YOLO_SWAG
When someone creates a production order in Dynamics 365, how fast does the Minecraft bot react?
Answer: Instantly. No polling. No delays. Just push.
The Problem with Polling
Most systems check for new work every few seconds:
Bot asks server: “Any new orders?”
Server says: “Nope.”
Bot waits 5 seconds.
Bot asks again: “Any new orders?”
Server says: “Nope.”
Bot waits 5 seconds.
Bot asks again: “Any new orders?”
Server says: “Finally yes, here’s one from 10 seconds ago.”
Slow. Wasteful. Annoying.
Our Solution: Service Bus Push
Order created in D365
↓
Azure Service Bus receives event
↓
ASB Listener gets notified INSTANTLY
↓
Backend API processes and forwards to bot
↓
Bot starts working in under 1 second
No waiting. No polling. The moment an event hits the queue, our listener knows about it.
How It Works
We built a dedicated ASB Listener service using TypeScript and the Azure Service Bus SDK. It sits there with an open subscription to the queue.
The listener uses ServiceBusClient to connect to Azure, creates a ServiceBusReceiver that subscribes to the queue with peekLock mode, and processes messages the instant they arrive.
receiver.subscribe({
processMessage: async (message) => {
await forwardToBackend(message.body);
}
});
When a message arrives, the listener parses the order data, forwards it to the backend API via HTTP, and the backend triggers the Minecraft bot. All of this happens in real time.
Why Service Bus
We could have used HTTP webhooks, but Service Bus gives us guaranteed delivery, built-in retry and dead-letter queues, auto-scaling, decoupling between producer and consumer, and native Azure integration.
The flow is clean:
Production Order → Service Bus Queue → ASB Listener → Backend API → Minecraft Bot
No database polling. No scheduled jobs. Just pure event-driven architecture.
In the our Model builder app, which is helping customer recover lost recipes from the single shot, We are using websockets to update the progress of the task for model crafting.
Technical details
For the backend implementation we are using bun ServerWebSocket implementation.
In the Frontend app, we have subscription to handle different events of the tasks:
In our solution, users will be gathering ingredients using object detection in a Canvas App. The AI model used for this has been trained on objects around the conference venue, and so we wanted to enhance the connection between the app and the real world. Already having access to the users geo location through the geolocation web API inside the Canvas App and any PCF components, we decided to these data to place the active users on a 3D representation of the venue, expressing our power user love by merging 3D graphics with the OOB Canvas App elements.
We were able to find a simple volume model of the buildings on the map service Kommunekart 3D, but these data seem to be provided by Norkart, which is not freely available.
Like the thieving bastards we are, we decided to scrape the 3D model off of the site, by fetching all the resources that looked like binary 3D data. We found the data was in B3DM format and we found the buildings in one of these. We used Blender to clean up the model, by removing surrounding buildings and exporting it to glTF 3D file format, for use in a WebGL 3D context.
The representation of the 3D model, we decided to do with Three.js, which let us create an HTML canvas element inside the PCF component and using its WebGL context to render out the model in 3D. The canvas is continuously rendered using requestAnimationFrame under the hood, making it efficient in a browser context. The glTF model was loaded using a data URI, as a workaround for the web resource file format restrictions.
The coordinates from the user’s mobile device comes in as geographical coordinates, with longitude, latitude and altitude. The next step was to map these values relative to a known coordinate in the building, which we chose to be the main entrance. By using the main entrance geographical coordinates, we could then convert that to cartesian coordinates, with X, Y and Z, do the same to the realtime coordinates from the user, and subtract the origin, to get the offset in meters. The conversion from geographic to geocentric coordinates were done like so:
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type CartesianCoordinates = { x: number; y: number; z: number };
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type GeographicCoordinates = { lat: number; lon: number; alt: number };
// Conversion factor from degrees to radians
const DEG_TO_RAD = Math.PI / 180;
// Constants for WGS84 Ellipsoid
const WGS84_A = 6378137.0; // Semi-major axis in meters
const WGS84_E2 = 0.00669437999014; // Square of eccentricity
// Function to convert geographic coordinates (lat, lon, alt) to ECEF (x, y, z)
export function geographicToECEF(coords: GeographicCoordinates): { x: number; y: number; z: number } {
// Convert degrees to radians
const latRad = coords.lat * DEG_TO_RAD;
const lonRad = coords.lon * DEG_TO_RAD;
// Calculate the radius of curvature in the prime vertical
const N = WGS84_A / Math.sqrt(1 - WGS84_E2 * Math.sin(latRad) * Math.sin(latRad));
// ECEF coordinates
const x = (N + coords.alt) * Math.cos(latRad) * Math.cos(lonRad);
const y = (N + coords.alt) * Math.cos(latRad) * Math.sin(lonRad);
const z = (N * (1 - WGS84_E2) + coords.alt) * Math.sin(latRad);
return { x, y, z };
}
This gave us fairly good precision, but not without the expected inaccuracy caused by being indoors.
In our solution the current position is then represented by an icon moving around the 3D model based on the current GPS data from the device.
To connect this representation to realtime data from all the currently active users, we decided to set up an Azure SignalR Service, with an accompanying Azure Storage and Azure Function App for the backend, bringing it all to the cloud, almost like a stairway to heaven. With this setup, we could use the @microsoft/azure package inside the PCF component, receiving connection, disconnection and location update message broadcast from all other users, showing where they are right now.
14:41: Updated to include additional information around embedding the map in a mobile app and searching in multiple ways.
You want to see if other professors are around in the school? We found a magical map in the School form of our OwlExpress app. The Marauder’s Map is using Websockets magic to track everyone on the school premises Right Now.
It also is using device embedded voice recognition to understand your spells, you need to say: “I solemnly swear that I’m up to no good.” if you want to see the map.
When you are done and want to hide the map you must say: “Mischief Managed!”.
Do you like the glossy pixels of this map?
Mobile Map
We have also managed to embed this into a canvas app for a mobile delivery for sneaky students upto no good.
Searching in many ways
We have also introduced a glossy new feature for searching our student database in multiple magical ways, searching via standard text boxes, searching by scanning a business card, drawing a students name and utlising Copilot.
PowerPotters of Cepheo: Brewing Badge-Winning Elixirs with Pro-Code Potions and Beyond!”
Greetings, magical tech community! 🧙♂️✨ Team PowerPotters of Cepheo is thrilled to unveil our progress in automating elixir production for the ACDC 2025 hackathon. Our solution blends the powers of pro-code Python and low-code Power Platform to craft a system that’s both functional and badge-worthy. Today, we’ll reveal how we’re targeting the Pro-Code Potions category as well as these coveted badges:
Right Now
ACDC Craftsman
Thieving Bastards
Power User Love
Let’s dive into the details of how our Python-powered magic aligns with these badge aspirations!
1. Claiming the “Right Now” Badge: Python – The Heart of Our Brew
The “Right Now” badge rewards smart, clean, and efficient code that elevates solutions beyond the realm of low-code alone. For us, Python isn’t just an enhancement—it’s the engine of our magical elixir automation.
Python Scripts: Unlocking Advanced Functionality
Our Python scripts (sensor_script.py, voice_script.py, integration_script.py) are designed for tasks that Power Platform cannot handle natively:
Direct Hardware Interaction: Using RPi.GPIO, our sensor_script.py captures real-time data from the potion cauldron’s liquid level sensor. Power Platform simply cannot replicate this hardware integration.
AI-Powered Voice Recognition: Our voice_script.py leverages the OpenAI Whisper API for advanced speech-to-text processing, turning verbal commands into actionable automation triggers.
Intelligent Orchestration: The integration_script.py ties everything together—sensor readings, voice commands, and workflows via Power Automate.
With these examples, we demonstrate how Python serves as the lifeblood of our system, embodying the essence of “Right Now.”
2. The “ACDC Craftsman” Badge: Best Practices in Code
The “ACDC Craftsman” badge celebrates development and deployment excellence. Our commitment to best practices is reflected in every line of Python code we write.
Highlights of Craftsmanship:
Modular Structure: Each script (sensor_script.py, voice_script.py, etc.) has a single responsibility, ensuring clarity and maintainability.
Error Handling and Logging: Robust try...except blocks and detailed logging ensure stability and traceability
Mocking for Testability: The Mock folder includes a GPIO.py mock module, allowing us to test sensor logic without a physical Raspberry Pi. This approach accelerates development while maintaining code quality.
By embracing modularity, testability, and robust error handling, we ensure our code stands as a shining example of “ACDC Craftsman” principles.
3. The “Thieving Bastards” Badge: Leveraging External Tools and APIs
The “Thieving Bastards” badge rewards the clever use of third-party tools to amplify solutions. Here’s how we “borrowed” brilliance:
Open-Source Libraries:
RPi.GPIO and requests for hardware and API interaction.
sounddevice and scipy for audio recording and processing.
python-dotenv for secure environment variable management.
OpenAI Whisper API: This external AI service powers our voice recognition functionality, enabling seamless integration of advanced speech-to-text capabilities without reinventing the wheel.
We’ve strategically combined these tools to accelerate development and expand functionality, earning our place as “Thieving Bastards” in the best sense!
4. The “Power User Love” Badge: Pro-Code and Low-Code Unite
The “Power User Love” badge highlights the magic that happens when pro-code customization enhances low-code platforms. Our project is a perfect example:
Power Platform for Low-Code Power: Power Automate orchestrates workflows, while Power BI visualizes potion progress.
Python for Pro-Code Power: Python bridges the physical and digital realms, enabling sensor integration and AI-driven voice commands.
Together, these platforms create a seamless, intelligent, and user-friendly potion production system.
Conclusion: Badge-Winning Elixir Automation!
With our meticulously crafted Python pro-code and Power Platform low-code synergy, we’re confident our solution is a contender for:
Right Now
ACDC Craftsman
Thieving Bastards
Power User Love
PowerPotters of Cepheo are proud to combine technical excellence with magical creativity. We look forward to seeing the results and continuing to share our journey. Stay tuned, fellow wizards!
NOTE TO THE JURY: we have taken your comment in and added details in the bottom of this article.
In our Wayfinder Academy, we take a comprehensive and magical approach to understanding the student’s history, aspirations, and potential to recommend the best possible new school. The process is detailed, thorough, and personalized, ensuring the student is matched with an environment where they can thrive.
Just to remind the process, here we assume a student who didn’t feel right about their current faculty, filed an application. Immediately after that we request the tabelle from their current faculty (historical data), ask a student to upload some photos from most memorable moments, and then invited to an interview. While we are still working on the interview step and will share the details later, with this article we want to add more details about one of our approaches to mining extra insight from the student’s interview by analysing the emotions.
We use this emotional recognition along with the interview, to get 360 degree insight on the student`s reaction to the questions, that are designed to figure out their values, aspirations, fears, etc we can use to calculate the probability of their relation to the faculties and identify the one with the highest score (the scoring approach will be shared in a different post).
So, we are using a video stream capture to record an interview session and extract the emotional dataset.
It allows us to receive one more dimension that will extend standard datasets of the student, such as feedback, historical data from previous schools, etc.
We use the imentiv.ai API to analyze the video and grab the final report. We then make the final dashboard in Power BI (we love it)
and embed it into OneLake.
Imentiv AI generates emotion recognition reports using different types of content, such as video, photos, text, and audio.
We implemented the single-page application to create an interactive experience by recognizing the emotions in the image captured via the webcam on our tablet. The analysis of the video stream takes more time, so we will demonstrate it later.
The app consists of two parts: a PoC to recognize the emotions in a photo from a webcam and an example of an emotion recognition report.
To build that PoC application, we decided to use the NodeJS stack. The engine is based on Bun, which is a modern and highly effective alternative to NodeJs. Compared to NodeJs, Bun was written with Rust.
For the front end, we are using React and ChartJs. We are hosting the PoC on our laptop. To make it available to the public internet, we are using CloudFlare tunnels. It also covers the SSL certificate termination, so your service will be secured by default without any significant effort.
The app server and the client app run inside a docker container, so you can deploy easily with a single command: docker-compose up—build.
To optimize the final container size and improve the speed of the build, we are using docker files with two stages: one to build the app and the second one to run the final artifacts.
PS:
Badges we claim:
Thieving bastards – we are using third party platform to recognize emotions in video and photo.
Hipster – we use BUN to run the application
Hogwarts Enchanter – we use Mystical AI imentiv.ai API to grab the emotional reports and visualize it in an user friendly way (see the screenshot above). Our enchanted workflow is using the data and making it available in OneLake. Wizarding world becomes closer when we see the AI based deep insight from various data sources in one place, in easy to read and interpret format.
Right now – we are using web socket server to implement real time communication between client and server site.
Client side salsa – we use React to implement front end.
PS2: pls come over to our camp and test it out! We want to know how you feel! 🙂
What is it good that you can have improved customer communication with chatbots and forums, if the plumbers can’t get notified in realtime of relevant cases? Moreover, Mario and Luigi as CEO and CTO respectively want real-time data for improving decision support (e.g. plumber allocation) and PlumbQuest trends for further analysis.
Dataverse Webhook on Incident reports
To extract real time data, we created a Web hook using the plugin tool box for Dataverse, which calls our Azure Function whenever a new PlumbQuest is made.
XRMToolbox to add a Web hook to Dataverse for real time PlumbQuest analysis
To ensure safe access, function level authentication is applied, where the toolbox allows for HTTP Query parameters, safely accessing our Function which uses a traditional HTTP-trigger:
However – Here is the hacky part. The Web hook payload is too large, which makes the traditional JSON-payload corrupted with highly dynamic lengths and content of each PlumbQuest. Therefore we had to do some custom string manipulation to extract the values of most business and de-corrupt the JSON and preparing it for analysis – Almost a Complete ETL-pipeline (*cough*)!
But to access this real-time data in an Analytics environment – Fabric is the way to go (as by Microsoft huge Hype-wave). We created a Custom app Source for an Event Stream in Fabric with an EventHub output binding, which then can map to many different destinations, including a Lakehouse for historisation and trend analysis, as well as Data Factory Reflexes for reactive actions in real-time.
With Data Activator’s Reflexes directly on the stream, one can e.g. trigger additional flows for highly acute PlumbQuest from members in distress, or highlight plumbers who did not provide proper service according to the PlumbQuest review.
Our Fabric Event Stream with the Custom app as Source and the Lakehouse for historisation and down-the-line processing and analysis
In addition, we set up a Dataverse Shortcut (Link) to Fabric, allowing for direct access to Dataverse without ETL or ingestion, providing ease of access and down-the-line deeper analysis on key business metrics, trends and community engagement.
Our PlumbQuests in Fabric Lakehouse using a Dataverse Connection for e.g. a more complete 365 customer view using Fabric items
Reproducible deployment
Although we are nasty hackers, we are reproducible hackers. As these were the only Azure resources used (directly), we deployed them using bicep and the Azure CLI. Sensitive variables are marked as secure and not included in the scripts, but parameterised.
The main bicep deployment definitions for our Azure Function app and related resources, the resource group naturally had a separate BICEP definition.
So if you want to do it hacky, at least make it traceable.
To make our amazing service Tubi work, a lot of cloud is needed. We aim to make the plumber’s job easier by recommending the best layout for where the pipes should go, and for that, we need AI. We have trained a model in Custom Vision to recognize all components in a bathroom that need water. So, when the plumber uploads a floor plan to our Static Web App, the image is sent to our Azure Function App backend in C# Asp.net through our own API. But both the image and the equipment list must be stored somewhere. Therefore, we have also connected to Azure Blob Storage. Then last but not at all least. The people working in the back office have instant interactive reports available to help them with filing and billing through Power BI and alerting the using an automated flow (Badges: Feature Bombing)
Sometimes it works, and that’s plenty
Databases are good, but sometimes it’s easier to just dump everything in one place until you need it again. Yes, it might not be very scalable or very normalized. SQL became too heavy, and we already needed a Blob storage to store the images, so we also dump the order data in the same blob storage as JSON files. It’s old fashioned way of serverstorage, and a bit dirty, but it works! (Badges: Nasty hacker, Retro badge)
Power the backoffice
As the final list of components are decided, they still have to be approved from the accounting team in the office. To make sure they have all the information they require, we have developed a Power BI dashboard to crawl through our registered data and make sure the orders are handled properly (Badges: Crawler, Dash it Out, Dataminer). And to make sure the orders are handled easy and fast, the dashboard is embedded into teams and an alert is automated by using a logic app to make sure the workers can receive and cooperate in realtime (Badges: Embedding Numbnuts, Go with the flow, Pug N’ Play, Power user love, Right Now, Stairway to heaven).
Client Side Salsa – for the react code for PCF control
Hipster – for using node.js for secure communication
Right now – for socket io for real time communication with the active users in Model driven app
Nasty Hacker – for incredibly awesome solution with dirty hack on the model driven side
Power User Love – for using socket io with Azure Function in low-code power apps
High Level Diagram
Implementation
All realtime communication is implemented via the soket.io that hosted on Azure.
Project Update: Real-Time Communication and Enhanced User Interaction!
We’re excited to share the latest update on our project, featuring a significant enhancement in real-time communication capabilities. Now, administrators and backend integrations can seamlessly send messages to users who have opened specific records. This means that when there’s a change in the record status (e.g., case completion, modification), users will receive instant notifications prompting them to update their page for the latest changes.
This feature not only streamlines communication but also serves as a handy tool for various onboarding processes. Additionally, it facilitates users in understanding what has changed post the deployment of a new release.
Behind the scenes, we’ve implemented Clippy PCF, built upon the ClippyJs project, to empower this real-time communication. Leveraging the power of socket.io hosted on Azure, our solution ensures swift and efficient message delivery.
Moreover, the backbone of the real-time communication lies in Azure Functions, written in Node.js. These functions diligently send out notifications to the socket.io instance hosted on Azure, creating a seamless and responsive user experience.
Exciting times lie ahead as we continue to innovate and refine our project to meet the evolving needs of our users. Stay tuned for more updates, and thank you for being a part of our journey!
Business scenario
It supports real-time communication. So, Administrator or backend integration can send the message to the user that has opened the record. For instance: backend integration changed the status of the record (case has been completed, changed, etc..), all user that has opened record will receive the notification that they need to update the page to receive the lates changes.