Generic Character Interactions
December 6, 2019
Ok. I’m almost really, truly ready to start on a serious testing round of Sleuthhounds: Cruise. I’ve been finishing up a last few technical scripting items before launching into said testing. Most of it is under the hood work that affects how things work across the game (hence my wanting to get them done before doing a big testing round). While they’re important tasks to get working, there’s not a lot to show for them in a blog. One, such task that does allow me to eke out a few words this week is handling how the two principle characters, Ampson and Homes, interact with each other.
Throughout the game there are a good many inventory items that the characters can pick up. In some cases a given character can pick up an item but then has to give it to the other character at some later point for the other character to use it. As well, the characters need to be able to talk to one another on occasion to offer bits of advice.
In previous Sleuthhounds games I took the brute force approach to handling the interactions between Ampson and Homes. Each room would individually be scripted to cover those various actions. Given the relatively few number of rooms in those earlier games this method worked for completing the games but it wasn’t exactly elegant. If any of the interaction code needed to be changed it needed to be changed for each room.
Cruise is a different story. It has so many more rooms than the earlier games that to script the same interactions in each would be very time consuming. Plus, if any of the interactions had to change then it would be even more work to update those changes across all the rooms. Clearly some generic, reusable way to handle these interactions was called for. However, even with that there were several special cases that needed to be considered:
1) Stuck Characters
In a couple of scenarios in the game, one or the other Sleuthhound gets stuck and is unable to move or accept items offered in trade until the player figures out how to unstick them again. The Sleuthhounds handling system had to be one that, while providing basic generic handling for the characters, could be overridden to allow specific scenarios in specific rooms to restrict when it would be used.
2) Separated Characters
In some rooms there are several disparate regions that characters can move around in. For example, there are a couple of screens with different balconies on them. If one character is on one balcony and the other character is on another then again they’re not in a position where they can trade items.
However, as well there are some rooms where the characters are in different regions but those regions are connected. For example, one room has a stairway separating an upper and lower floor. This room was previously scripted so that a character on one floor would first walk to the stairway, then run a cutscene of them using the stairway, then walk from the other end of the stairway to the final destination (as opposed to most rooms where characters can just walk directly to their destination). The handling system needed a way to tie into any specific character walking routines that individual rooms had.
3) Counter Puzzles
In some scenarios a counter is placed on the screen indicating that the player has a limited number of actions available to them to solve the particular challenge. Every action they take, such as talking to another character or trading an item with them, needs to decrement the counter by one. However, not all rooms have counters in them. The handling system needed to be configured in such a way that if a room had a counter in it, then it would properly adjust the counter as actions were taken and run the necessary cutscene result, in the event that all actions were used up.
4) Exchange Points
When the Sleuthhounds trade items they need to be standing in spots where animations can be run showing their hands coming up and meeting to indicate an item has been traded. The location and number of these spots varies by room. For example, a small, cramped cabin might only have one spot where the Sleuthhounds can trade items, while a large dining room might have half a dozen or more. Complicating this, the actual X,Y coordinates per spot that the characters need to move to has to be set on a per room basis. So again, the handling system needed to have a way to tie back into data from a specific room.
Conditional Compilation
Going way, way back, back even before the first Sleuthhounds: The Unlocked Room game, I had created my own scripting language to help with game development. Fortunately, past me did several things that has made development of my games much easier and has solved problems I didn’t even know I was going to have. Such was the case with the generic handling system.
The solution was to use conditional compilation when including the script for the generic handling system with each room. In most rooms the script can just plop into place with only a little bit of data setup for the exchange point coordinates, indicating how many such points exist.
For rooms that have specific requirements on the way that characters move a couple of conditional defines at the top of the room script cause parts of the generic character handling script to be included that aren’t needed for basic rooms. This allows, for example, the walk routines that the character handling script uses to be redirected from the regular walk routines to special ones that the room script already uses for when it needs to limit interactions when characters are stuck or separated or so on.
A similar principle works for the counter puzzles. By moving the counter code from the room script to a separate script that both the room script and the generic character handler can use, it then becomes possible to have the room script define a flag that tells the generic handler script that the counter script exists and to make use of it in the appropriate places.
Conclusion
It took a bit of doing to work out all the special cases that the generic character handler needed to accommodate. Since completing that I’ve been going through the rooms defining the exchange points for the basic rooms and putting in the needed conditional compilation flags for the more complex rooms. I’ve just about got that finished and once it’s done then that removes the last item from my To Do list before doing a big batch of testing.