Blog

Intro to Holoearth’s Server-Side Tech

Intro to Holoearth’s Server-Side Tech

Author introduction "Yukihiro Nishine" Position: Engineering Dept. Manager Date joined: October, 2023 Industry experience: 11 years of development and admin experience in web services and online games, mostly as a C# server-side engineer. Yukihiro has been the recipient of the Microsoft MVP for Developer Technologies award (2020 - 2022). Hi everyone, my name is Yukihiro Nishine and I’m a manager in the Holoearth engineering team. When speaking of Holoearth’s development, it likely conjures images of the Unity-based client-side implementation, the avatar system, or concert events and the like. But this time around I would like to speak to some of the server-side technology that we put to use. I hope this will be interesting for those of you who are interested in the behind-the-scenes development of Holoearth. Contents ・Programming Languages Used ・Cloud Environment and Tools ・About Cloudflare ・Final Thoughts Programming Languages Used We primarily use Go, with a handful of other languages as well including PHP, C#, TypeScript, and Rust. Rather than a single application, the Holoearth servers are composed of multiple applications that each use a different language. ▼Application segmentation ・Sandbox game ・Lobby (Entrance Hall, Alternative City, etc.) ・Infrastructure for account management, payments, etc. ・Others The server side of the initial sandbox game development was done in PHP. From there, the communication lobby and underlying system was made with Go, and currently Go is the primary server-side language being used. On the other hand, the other languages not used until this point may be used when the appropriate case calls for it. For example, a new system being developed requires in-game logic to be handled in real-time by the server side, so by using C# on the server side as well we can ensure the developers working in Unity can develop the client side in lockstep with the server side. As for other languages, we use TypeScript in Cloudflare’s FaaS (Cloudflare Workers), which works in conjunction with Cloudflare resources, and Rust is used in the communication infrastructure that is currently in development. Cloud Environment and Tools The Holoearth cloud environment predominantly uses AWS, of which the main services utilized include EKS, ECS, EC2, Lambda, Aurora, DynamoDB, and ElastiCache. For storage and CDN we do also use S3 and CloudFront, however, to reduce costs we moved much of this to Cloudflare. For monitoring tools we use Datadog, and Snowflake is our platform for data analytics. COVER may not be a web services and game specialty company, but we are establishing a development environment that can go toe-to-toe with such companies in the industry. About Cloudflare Cloudflare was initially well-known as a CDN service, but these days it offers a range of different services. Holoearth migrated its CDN needs over to Cloudflare to make use of its ecosystem. Besides its CDN service, we are also utilizing Cloudflare Stream, Cloudflare Images, and Cloudflare Workers, among others. In particular, we make heavy use of Cloudflare Stream. The video streaming rooms we made available to users during New Year’s and hololive EXPO were made possible by Cloudflare Stream. I was actually first introduced to using Cloudflare Stream after joining COVER, and I was amazed at both how easy and cost-effective it is to implement video streaming. For those of you interested in video streaming development I definitely recommend giving it a try. Final Thoughts That wraps it up for a brief introduction to Holoearth’s server-side technology stack, which until now hasn’t really been revealed. Our own CTO, Ikko Fukuda, has previously shared that metaverse platform development is a sort of “mixed martial art concerning the world,” which is spot on. Holoearth development is not always straightforward, but that is precisely what makes working on it as an engineer such a rewarding experience. Thank you for reading, and we hope you continue to follow the story of Holoearth’s development!

Date

24.5.17

Category

  • Engineering
Placing Windows Freely on Walls

Placing Windows Freely on Walls

Author introduction "Shoichiro Inoue" Position: Engineering Dept. Client Team Date joined: February, 2021 Industry experience: Three years Getting Started Hi everyone, my name is Shoichiro Inoue from Holoearth's engineering client team. I'm mainly responsible for implementing the building mechanics in Holoearth. Many games in recent years have included building and housing mechanics, and windows are an integral part of this kind of mechanic. However, in many games windows can only be placed in specific places, such as on a wall with a hole specifically made for window placement - but we want to place windows wherever! I'll introduce the solution we worked out for this problem in this development blog. But first, here's a short video demonstrating the end result. https://holoearth.com/wp-content/uploads/2024/04/mado_setti.mp4 As you can see in the video, it is possible to freely place a window wherever you want! The part of the wall where a window is placed disappears, revealing the outside. But in addition, it is also possible to cut a hole in the wall's collider as well. This allows for the possibility in the future to have battles where, say, arrows can be shot through windows that were installed. Here, I explain the process of how we approached the problem. Solving the Problem Requirements The wall has to be in place first to install a window, the window must be installed such that it's flush with the wall, and the window's rotation must adjust automatically to the proper orientation with respect to the wall. I won't go into detail about this part. The window "prefab" must include the following information: Collider (to use collisions to detect which wall it is being placed on) Window width and height Workflow 1. The window contains a collider and retrieves which wall it is to be placed on. 2. When colliding with a wall, the window passes its position and size data to the wall and requests to make a hole there. 3. The wall in question executes scripts to change its shader and collider values to create the hole. And if the window is destroyed it asks the wall to restore those values. I'll talk about the shader that creates the appearance of a hole and the script that makes a hole in the collider later on. So far the scope of this mechanic is limited as follows: It doesn't take into account how the window's edge protrudes from the wall, so we use raycasts to make sure all four window corners are on the same wall. It can't allow for multiple windows on a single wall, so if a second window is added it will destroy the first window. Using Shaders to Make the Window's Appearance In essence, the wall's shader will not render where the window's coordinates overlap the part of the wall being rendered. This means the sides of the model will be empty, revealing the reverse side of the wall's mesh, but this is covered by the 3D model of the window frame on the sides of the window. (Left: Wall being overlapped by a window is removed by the shader. Right: Placing a window frame over the removed portion.) A surface shader is created to grab the coordinates of what is being drawn. The window's center coordinate and size (width, height) are obtained from its script. Making Calculations We split the problem into the two parts below. 1. Whether the coordinates being drawn are in the window on the horizontal plane, and 2. Whether the coordinates being drawn vertically are in the window. 1. Horizontal plane We make a line on the x-z plane using the formula: z = kx + b. Let k be the slope of the line perpendicular to the window when viewed from directly above. Then there are two lines, b, which are the lines passing through the front and back edges of the window, respectively. Let us denote them as b1 and b2. There's no need to draw within the yellow area bounded by lines z = kx + b1 and z = kx + b2. That is, if the coordinates we are drawing now are x1, y1, and z1: kx1+b1 < z1 < kx1+b2 Then the coordinate is in the window on the horizontal. *k can be obtained from the window's y-axis rotation = rotY. *Since the tan of 0 is undefined, we need to set up a branch process to avoid specifying 0 as the argument of the tan function. k = tan(rotY/180f * π + 0.5π) *b1, b2 can be obtained from the coordinates of both ends of the window b = z / kx 2. Vertical Direction Now, the Y axis: In Holoearth, the window rotates only on the Y-axis, so the equation is simple. _windowBottomY < position.y < _windowTopY We know that we are in a window in the vertical direction if the above is true *The _windowBottomY and _windowTopY can be obtained by adding the window width to the window center point Y coordinate. Taking all the above into account the code looks like this: bool isInsideWindow(Vector3 pos) // pos: world coords of point to be drawn {   // Is in window on x-z plane   var isInsideXZ = _k * pos.x + _b1 < pos.z && pos.z < _k * pos.x + _b2;   // Height is within window   var isInsideY = _windowBottomY < pos.y && pos.y < _windowTopY;   return isInsideXZ && isInsideY; } *The actual shader was created by the same team. They are modified and shown here for clarity. *To reduce processing loads, _k, _b1, _b2, _windowTopY, and _windowBottomY are calculated when the window is placed. Future Endeavors Right now this can't support shapes other than rectangles. To accommodate other shapes, the area of that shape needs to be calculated. For example, a circular window can be implemented by projecting the drawing coordinates onto the x-y plane and then making sure the distance between the point being rendered and the center point is less than the radius of that circle. Making Openings in Colliders Now I'll explain more about creating an actual hole, rather than just in appearance. The wall collider consists of a single box collider. The original collider is replaced by four box colliders to avoid the window part, each of which is divided to avoid the window section to represent a hole in the wall. The way to do it is pretty simple: we attach a new four-box collider after deleting the original collider, which requires computing the center coordinates and size of each collider. This will result in the following variables: A 3-dimensional vector (vector3) for the size of the wall, wallSize Relative coordinates of the window to the wall in another vector3, windowCenter Length of one side of the window in a vector2, windowSize The actual calculation is as follows: *The collider is a local coordinate system, so rotation doesn't need to be considered. *The origin of the wall is at the center of the bottom surface, and the origin of the window is at the center of the length and width ▼Upper collider var sizeX = wallSize.x; var sizeY = wallSize.y - (windowCenter.y + windowSize.y); var colSize = new Vector3(sizeX, sizeY, windowSize.z); var posX = 0f; var posY = wallSize.y - sizeY/2f; var colCenter = new Vector3(posX , posY, windowSize.z/2f); ▼Lower collider var sizeX = wallSize.x; var sizeY = windowCenter.y - windowSize.y/2f; var colSize = new Vector3(sizeX, sizeY, windowSize.z); var posX = 0f; var posY = sizeY /2f; var colCenter = new Vector3(posX , posY, windowSize.z/2f); ▼Left collider (The x-axis is zero at the center of the wall, so the coordinate of the left end of the wall is -wallSize.x / 2f) var sizeX = - wallSize.x/2f + windowCenter.x - windowSize.x/2f; var sizeY = windowSize.y; var colSize = new Vector3(sizeX, sizeY, windowSize.z); var posX = -windowSize.x/2f + sizeX/2f; var posY = windowCenter.y; var colCenter = new Vector3(posX , posY, windowSize.z/2f); ▼Right Collider var sizeX = wallSize.x/2f - (wallCenter.x + wallSize.x/2f); var sizeY = windowSize.y; var colSize = new Vector3(sizeX, sizeY, windowSize.z); var posX = wallSize.x/2f - sizeX/2f; var posY = windowCenter.y; var colCenter = new Vector3(posX , posY, windowSize.z/2f); Set these values to position the collider so that it doesn't cover the window area. Future Endeavors With the process described here, it is difficult to make holes in the collider with non-rectangular shapes. At the moment windows of different shapes can't be made, but there are possible ways to accomplish this: Increasing the number of box colliders and arranging them like an integral, which could make shapes really close to circles and triangles. But this drastically increases the number of box colliders as accuracy increases. Preparing colliders with triangular or circular holes in advance. After making holes in a rectangle, place these prepared colliders inside the holes. It takes time and effort to prepare colliders with special shapes, but it might reduce the number of colliders necessary. Final Thoughts The combination of shaders and collider management allows us to create an experience where windows can be placed freely on walls! We hope to create more and more awesome building features! If you're interested, definitely give it a try in Holoearth!

Date

24.4.26

Category

  • Engineering