If you haven’t already, you can play my entry – Gems of Power right now!
The good parts
The not-so-good parts
I was not planning on participating in this ludum dare, but I’m very glad I did. Currently I’m looking for work and need to spend most of my time building up a resume, but what better resume builder is there than the most well-known game jam?!
Over the 48-hour weekend I unfortunately overworked myself. The pressure of only having 48 hours to do everything is so daunting and I did not practice a good work-life balance. This kind of jam expects you to work hard, but it’s never a good decision to work yourself that hard.
Overall I’m very happy to say I completed 78% (25/32) of the Trello cards I created during the jam. The game was so close to feature complete and it has a start, middle, and end!
Some really interesting pieces of code came out of this jam that I’m excited to share! The gem shader and unique surface shaders will be discussed in tomorrow’s post of 100-days of Graphics Development.
Non graphics-development wise, I created some neat scripts to translate a screen position into the pointed-at location in the world and a script to convert a 3D vector to Euler angles for rotation.
The following code will take the mouse position on a camera and produce a position in the world that the mouse is pointing at. This particular code only returns positions where y=0 because in this game the ground is located at the plane where y=0.
Vector3 cameraPosition = camera.transform.position; Ray ray = camera.GetComponent<Camera>().ScreenPointToRay(Input.mousePosition); Vector3 pointingDirection = ray.direction; // Now that we have the direction the mouse is pointing, we can use it to // see if it collides with any physics objects, or cast it until it points at the ground, // or anything else we want! // Since this game forces buildings to have a y-value of 0, // we simply cast the point to the location where y=0. // We want to scale the pointingDirection such that if the vector started // from the camera's position, it would end at a point where y=0. // The scale gives us the factor to scale the pointingDirection by // so that when added to the cameraPosition the resulting vector // has a y-value of zero, and the x and z components are the location // our mouse is pointing at! float scale = Mathf.Abs(cameraPosition.y / pointingDirection.y); Vector3 position = pointingDirection * scale + cameraPosition; return position;
This next bit of code will transform a 3D vector into Euler angles that represent a rotation such that the forward direction will now point towards that vector! This code was exceptionally tricky to solve and I’m happy to share it here!
// Get a vector for the object we want to point at. Vector3 difference = ObjToRotate.transform.position - Target.transform.position; difference = Vector3.Normalize(diff); // We can break the problem down into two parts: // 1) How much to rotate around the up axis to face our target. // 2) How much to rotate up-and-down to look at our target in 3D. // The first problem uses the same solution for 2D problems to convert a unit vector // into a rotation. float rotationY = 180 + Mathf.Atan2(diff.z, diff.x) * 180 / Mathf.PI; // The second problem is much easier, just converting the y-value to degrees. float rotZ = Mathf.Asin(diff.y) * 180 / Mathf.PI; // We don't need to rotate along the x axis, two Euler rotations are enough for our purposes. // And as long as we're not modifying these rotations further to achieve new rotations, // we'll be fine using Euler angles over Quaternions. rotationVector.Set(0, -rotY, -rotZ); // Unity only uses Quaternions, so we have to convert. rotQuat = Quaternion.Euler(rotVector); ObjToRotate.transform.rotation = rotQuat;
I wish I had spent more time working on the gameplay and less on interesting visual effects. The game resulted in being poorly balanced, so users will rarely be challenged and won’t get to experience the game I had in mind.
You gain power too quickly and can build far more towers than enemies that attack you. This means you’re never threatened or challenged by the enemies. Without that challenge there is no game at all honestly. It’s just a building simulator. How would I balance this? I’d make the following changes:
Next issue – there needs to be a decision to search for gems to mind and then defend the miners versus spending more on defenses. This should be one of the deeper parts of the game. How would I create this feature? If energy were more scarce and generated more slowly, it would be imperative to go search for gems to mine otherwise your base would be overrun in time.
There’s also a lack of game state being communicated to the player. This doesn’t mean just a lack of UI. When is the player in the “building a tower/miner” state? How do they exit that state? Why can’t they place a building? Is there an enemy hurting a tower? How much life does a tower have remaining?
The most important game design issue is the one missing feature. A means to deactivate and activate towers. Towers can be toggled on or off. Towers that are on occupy some amount of energy, and towers that are off free up some energy. This would let the player build more towers than they can supply at the same time and then strategically toggle towers as needed, creating a player-skill attribute to the game. The better they are at micromanaging the towers, the more they can build and expand.
My biggest thought coming out of this Jam and looking forward to the next one is that it is really important to leverage as much time as you can. Two days is such a crunch for making everything in a game. The more reusable code, graphics, and all-around assets will enable you to focus the time on the game design, art, music, sound effects, and engagement!
That’s why I’m creating a new GitHub repository for Unity code that I can quickly insert and reuse for development later on. Plus more code visible to potential job employers the better.