Sabbatical Log: November 2ndPosted: 2018/11/10 Filed under: code 2 Comments
This blog series is running about a week behind my actual work, giving me time to clean things up. The date the actual work was done is in the title, horizontal lines indicate when I stopped writing and started coding.
Starting my second day of sabbatical, I’ve got a moving rectangle.
While there’s a lot going on behind the scenes, exciting this is not.
So my goal for now is to get some actual graphics going.
I’ve written up an AssetManager class that handles loading images (BMP and PNG) and mapping them to MonoGame’s Texture2D instances.
I’m not using the MonoGame content pipeline for a couple reasons:
- I want to learn about this sort of thing
- I want to maximize productivity, and allowing resources to be loaded dynamically helps that
Which means that now, not only am I rendering an actual sprite but I can edit the sprite and have it immediately update.
Now I wanna focus on getting a background and a of sorts camera working.
While preparing for camera work, I ended up spending some time optimizing asset loading. Once I was loading in a large map (Kakariko village, 4096×4096 pixels) to use for the background I discovered a few pointless O(n^2) loops where I was converting between pixel formats.
Nothing a little bit of Bitmap.LockBits and Marshal.Copy couldn’t cope with, but it burnt an hour or so of time. But now startup times are snappy again.
I’ve now got a pretty basic camera working. It’s modeled as an entity with position and dimension components, but it isn’t rendered (nor does it accept input). This is the first real chance to see the Entity-Component-System divide work, and I will say it feels elegant. N=2 isn’t exactly enough for me to be confident in it, but so far so good.
One thing that has felt weird is the way I’ve structured the System interface.
And here’s an implementer, CameraSystem.
Structuring the system such that they’re always working on enumerations of entities is conceptually nice, but I’m finding myself with lots of pretty janky foreach loops. In fact, I’ve added a helper to the base class (GetComponentFor in the previous picture) that does the really common “get the only one of these there is out of the enumeration”-task.
Since I haven’t gotten to any systems that operate on multiple entities, I’m not going to refactor just yet – but I’ve noticed the pain point.
Now I’m going to go work on testing the CameraSystem.
I’ve now got all the tests working for the camera system – I found a couple of bugs related to room sizes that were smaller than the “window” into the game. I added another test room to illustrate that the same systems are capable of handling either kind.
At this point it feels like it’s time to start implementing some other entities, probably static obstacles. But to do so I’ve got to implement the first part of a physics system, collision detection. Time to get reading.
Great work so far! I’ll follow along for sure.
How often does the `DesiredEntities` is called? I’m assuming it’s called only once right now but wouldn’t the use of events that systems can subscribed to when things happen like spawning entities, be better for the future? So that the systems list can grow and shrink dynamically as the game progresses.
DesiredEntities is called once per game update (so 60-ish times a second). In keeping with standard .NET enumerables, execution is deferred.
At the moment there’s a fixed number of systems (they’re all spun up at startup), but you’re probably correct that I’ll need a way to disable/enable systems in the future. Today (9 days after this post was written) I’m only up to 7 systems, so I haven’t crossed that bridge yet.