S K Ä R V A

Root Cause Dev Log 3

A Long Break

I know, I know. I have been gone for over a year. It has been quite a year at that! I wanted to move in with my boyfriend and was very tired of renting and having a rough streak with bad landlords so I ended up buying a house. That is quite the process that was very disctracting and involved a lot of travel as the city I was looking to move to was 7 hours away from where I had been, so any time I saw a some houses that I liked I had to act quick and take a trip all the way over to take a tour. The entire purchase process was very distracting and time consuming as well, then moving, then lots of adjusting to the environment and house work. The house work kind of never ends I have learned.

But without even being here a year I have learned plenty about the structural makeup of a house, the ins and outs of replacing a roof, how to handle a tree limb falling and hitting a house, that my house has two layers of siding, basic plumbing and electrical stuff, and much more small things.

I did try to keep getting work done, and I did, but not anywhere as much I wanted. That has improved in the last month or so, as has my contributions to elementaryOS, and skyrocketed when I went to GodotCon in Boston. I am going to go over what I worked on but I am going to keep it somewhat brief as it is a lot of updates but also some were made some time ago so I may not totally remember my rationale or the smaller issues I was working past at the time.

Fixing the Mouse Control and Lobby

One thing that bothered me with the controls was that there was occasionally this barely persceptable stutter with the mouse movement. I figured I am just in the prototyping phase so I wouldn’t worry about it just yet and moved on. Over time I started to lose patience for it, and when I had people who haven’t been testing the game over and over to try it out, they immediately noticed, so I knew it wasn’t just me. Loading the game up at the LAN party my friends put on turned out to be a really good idea as it made me realize I should revisit the controls even if it is a prototype; it is the core of the gameplay so I should put as much work into making it feel good as possible. After much toiling and complaining to a friend that was also jamming on his own personal game project, I got it sorted out, as well make a bunch of updates to the lobby. Originally I used the mouse movement as a way to apply action strength, much like a stick on a controller would do, with the thinking that this would have the same inertia feeling as any other input method to rotate the ship. This was causing a lot of micro changes in the direction, even in the same mouse motion, which seemed to compound and cause the stutters. The code looked like this:

    if mouse_velocity.length() > 0:
		direction = Vector3(mouse_velocity.x, mouse_velocity.y, 0)
		mouse_velocity = Vector2.ZERO
	else:
		direction = Vector3(
			Input.get_action_strength("pitch_up") - Input.get_action_strength("pitch_down"),
			Input.get_action_strength("yaw_left") - Input.get_action_strength("yaw_right"),
			Input.get_action_strength("roll_left") - Input.get_action_strength("roll_right"),
		)

I spent a lot of time wondering if somehow the reset to 0 for the mouse velocity was the cause, and maybe it was, but it was better to just not use the mouse for determining direction and just add it directly to the angular velocity:

    if mouse_velocity.length() > 0:
		entity.angular_velocity += entity.transform.basis.x * mouse_velocity.x * delta + entity.transform.basis.y * mouse_velocity.y * delta
		mouse_velocity = Vector2.ZERO

I originally was setting the angular_velocity to mouse_velocity and that was causing worse control oddities. After like an hour of fighting it I realized I needed to be adding to the angular velocity. That small change did the trick and afterward the mouse controls felt exquisite and kept the feeling of inertia but also, allowing me to move on to updating the lobby since talking about the game with friends made the issues forefront in my mind. This was pretty basic updates to handle edge cases, and adding logic to handle changing between game modes such as team indicators and being able to swap teams.

Rewriting the Composition System

One thing that I know is important for this game to work is to have a good system to automatically build out levels and entities based on parameters. To me this means making use of a composition system to add what is needed as individual building blocks, and intelligently linking together any components that need it. This led to me doing a fairly substantial rewrite that took quite some time. I had already made a sort of component class but there were inconsistencies about how they worked, and what kinds of things would be a component vs built-in to an object. Bringing things to be more consistent and pulled out to be components was a big part of the work, followed by figuring out how to make it work over network and connect components together that needed it. All of this culminated in a set of concepts that I built:

- Entities, like a ship or crate or door
- Components that can be applied to any of these entities
- Blueprints that define default component types and an entity to attach them to
- An Architect class to act as a globla interface to request entities by their blueprints

I am not going to go into too much detail here because it was a lot of code changes over a long time so I cannot speak to issues and rationale fully, but I will say that I tried to ensure that components remained as independent and self-contained as possible. I made use of signals for communication between components, having the architect and blueprints connecting them as necessary when the entity is being built at runtime.

The architect class is kind of the cornerstone; it is an extended class of MultiplayerSynchronizer so that way I can manually call its spawn function and pass in data overriding the blueprint default data on how a player’s ship, and later enemies, should be put together. This kind of data can be starting health, weapon, team, etc. The call will automatically pass the same data to all other peers ensuring the same setup on all clients. The blueprint itself will then put together the data into a ship entity based on the client’s relation to the entity; for example, your ship will get put together with a controller and camera but on everyone else’s client those will be skipped.

Where Things Are Now

After fixing up what existed with controls, composition, and the lobby, I moved on adding the start of the player HUD, a little more menu work, and adding a projectile based weapon called the Hexadecimator. The current form of the projectile is fairly hard coded for the one weapon instead of being more generic but I will refactor it when I figure out and start implementing new weapons. But the projectile did give me a good excuse to learn some of the built-in VFX of Godot; the particle system and glow maps.

Hexadecimator particles effects. The glow illuminating binary on the screen

And obviously the binary translates into ASCII. To what? The first sentence of the classic Lorem Ipsum of course!

Next for me is building out a full test map and getting the win-lose condition, destroying the opposing team’s base, built so the full core loop is complete and playable in singleplayer or multiplayer. This will let me know how it feels and give me a better idea of what of my many concepts have the best chance of working well. I am hoping to have the core loop finished in time for the LAN party I am going to in December so I can get a group of friends to help test the very basic network code and the feel of flying.

GodotCon

It turns out that my coworker at Skymap Games helps put together the Boston-based GodotCon, which had its second event this past July. He convinced me to go with him, and it was well worth it. I met really rad people, some of whom I still keep in touch with on Discord (although I am so sorry I have now forgotten your real names!) and I hope to see at the next GodotCon, got to see talks from two Godot-related creators I have followed for a few years, and see some really cool games being made in the community.