[003] All Our CSGs

Third post! Let's see what happened this week...


Started a few more songs this week. Always fun to make new music. Here's a preview of one song:



I finished a few cutscenes/NPC interactions. Doing this required working on some coroutine/interpolation stuff which I mentioned below.

Here's a nice result of one.

Level Design

I've been texturing a bunch of stuff and making areas. Getting the hang of it now and how to structure workflow. Working in 3D is really fulfilling!

  • RealtimeCSG

    • I switched from SabreCSG to RealtimeCSG this week. They're both level design tools using Constructive Solid Geometry, which is sort of like building with legos, if you could also design your own legos, and legos could 'subtract' from each other. It's a super good way of making architecture in games. SabreCSG is okay at first, but it is not very good at handling complex scenes or intersections (subtracting cylinders from things results in missing faces... etc.) RealtimeCSG looks like an improvement of SabreCSG, with many useful features like being able to make your own brushes (or "Legos"), better support for viewing and editing level geometry, easier management of texturing.
    • Here's a few places I made this week. Could always look better, but I'm happy enough (first pic is missing some details, doorways, NPCs.


  • Save Points
    • As mentioned last week, I made more progress on save points - game now pauses, you can select a file to save... I mean, save points are not really that interesting or worth talking about... autosaves are becoming more popular, but I enjoy the use of a save point as a stylistic  element, a way to frame the action of the game. I kind of like to frame games as this object you're observing, not as much as this 'immersive experience' where you never see the game as a piece of software interacting with your hard drive and creating save files. I believe the term for elements like UI and title screens is called "paratext" - that's a nice link to an intro about the idea.
      • Anyways I'm not 100% done yet - I still need to write a little boring code to check things like playtime and saved area from each save file, so the save menu displays metadata about each file. 
      • AOA has 3 save files. Why? Well... it's nice to have more than 1, though people don't really complain about only 1 (Anodyne has only 1 save file! Have had very few complaints). (...Also, 3 fits nicely into the UI I have in the game...)
    • But if you're curious how I structure things, saving is made of three parts: an Activator, Menu, and Backend. 
      • Activator is like a trigger the player interacts with - something to open up the menu and pause the game action. So a "save point", basically. Or, clicking "Load Game" from the title screen. 
      • Menu is the UI stuff you interact with - choosing a file, confirming whether to save or load, etc. This contains code that asks the backend to load or save parts of the game state. Usually the menu is just a script controlling a group of UI elements. This way I can pop in the menu at anywhere in the game (Title Screen, Credits, in-game, etc.). I usually call this a "Save Module" for that reason.
      • Backend, or "Save Manager". This is code that checks all the various parts of the game state you need to save (player position.... event flags... secret variables...) and collects them into however your engine saves things, then writes that out as a file to your hard drive. Usually pretty boilerplate code. If you're really paranoid, you can put error handling here to deal with files that don't finish saving, but those sorts of issues rarely happen. Good to be aware of, though.
    • ... At this point I could talk a little about dialogue management but I've been typing too much. maybe next week.
  • MyInput 

    • My Input Manager code. Many games let you directly do things like (in unity for example) "Input.GetKeyDown(KeyCode.A)" to check if someone just pressed "A".  But you quickly run into a problem if you want someone to press a different key to do that action - and you SHOULD allow this because there are many different keyboards.  But then you need a way to allow someone to set an action to any key they want. That's why it's better to make a global variable like "justPressedJump" and "jumpKeyCode". You can let the player set the jumpKeyCode to whatever they want. Then your Input Manager will do something like "justPressedJump = Input.GetKeyDown(jumpKeyCode)". And so you can write code in your game for jumping that doesn't worry about the particular key. 
      • (overall... this is another boring boilerplate thing. I also don't like making people use a default launcher's control rebinding stuff - it's really ugly and a horrible paratext. Luckily people make lots of plugins and scripts for dealing with this stuff, but if you have a simple game (like I do!) it's easy to write your own. It's also just good Practice.)
  • CoRoutines for cutscenes

    • Unity and C# lets you use Coroutines. I haven't used them heavily, but they seem easy to abuse and sketchy in stability, so I'm staying cautious. You can look up what they do - what I used them for is cases in which I need to avoid single-use timer variables. For example, in cutscenes, I want to be able to interpolate values like fog color, fog density, lighting intensities... you would usually need 4-5 class variables for each thing (a timer float, max-time float, current value, end value, and sometimes, initial value). Really annoying when you want to interpolate something new and have to deal with adding 4 more variables. A coroutine lets me just write a single function that changes the variable each frame, but it's in its own function and is much easier to manage, and doesn't create extra class variables!

Leave a comment

Log in with your itch.io account to leave a comment.