-
Notifications
You must be signed in to change notification settings - Fork 2
Saturday Sessions: 20240728 Screen & Room Info
Joshua Wierenga edited this page Jul 28, 2024
·
3 revisions
Room Creation Tutorial Draft
This is a rough tutorial for creating new rooms in the project with unique functionality.
- Head to the “types.in.h” file in the backend folder of the project. Navigate to the
InputOutcomeenum and add a name for your custom room’s action (e.g. GameLookAroundOutcome with ID 11 in the following example).InputOutcomeis used by the backend to run custom code when the user makes an input.
// InputOutcome is a uint16_t with (0, 65535]
JSON_ENUM_START(InputOutcome)
JSON_ENUM_ITEM(InvalidInputOutcome, 0)
...
JSON_ENUM_ITEM(GameOpenChestOutcome, 10)
// <--- Your room outcome with following ID here (would be 11 in this case)
JSON_ENUM_END- Also in “types.in.h”, add a room type that your room can be identified by in the
RoomTypeenum following the same rules.RoomTypeis used by the backend to run custom code when displaying a game room.
// RoomType is a uint8_t with [0, 255)
JSON_ENUM_START(RoomType)
JSON_ENUM_ITEM(EmptyRoomType, 0)
...
// <--- Your room type name with ID here
JSON_ENUM_ITEM(InvalidRoomType, 255)
JSON_ENUM_END- Head to “GameData.in.json” and look for the
GameCustomScreenCodesection of the file. Add your new option players that will be able to select in your room here. Thetitlefield is the option players will see while theoutcomeis the function that will be run when it is selected. Some buttons have more fields containing extra information that the backend needs to handle that outcome as well.``
"screens": [
...
{
// ID: 1
...
"buttons": [
...
{
"title": "Open Chest",
"outcome": GameOpenChestOutcome
},
// <--- Your game button with title, outcome and possibly extra data here
...
}
},
...
]- Below that, look for the
roomssection of the json where information about rooms is stored. Add your room here, giving it the room type variable you created earlier, the position in which you want it to appear (x,y coords) and any extra data you want to include below.
"rooms": {
...
"roomsArray": [
...
{
"type": HealthChangeRoomType,
"position": [1, 2],
"description": "You have come across a trap",
"percentageChance": 50,
"healthChange": -10
},
{
"type": CustomChestRoomType,
"position": [1, 3],
"description": "A room with a chest lays before you",
"itemContainedID": 11
}, // <--- Add comma
// <--- Your game room with type, position and possibly extra data here
]
...
},- Move to “specialscreens.c” and look for the
CreateGameScreenfunction and find the room type for loop. This will define the conditions in which your option appears (e.g. being in the correct room type being obvious but other conditions such as stats or other features too).
static bool CreateGameScreen(const struct GameInfo *info, struct GameState *state) {
...
for (uint_fast8_t i = 0; i < state->inputCount; ++i) {
switch (state->inputs[i].outcome) {
...
case GameHealthChangeOutcome:
state->inputs[i].visible = state->roomInfo->type == HealthChangeRoomType;
break;
case GameOpenChestOutcome:
state->inputs[i].visible = *pOpenedChest == 0 && state->roomInfo->type == CustomChestRoomType;
break;
// <--- Your button visibility check here
default:
break;
}
}
return true;
}- Go to “game.c” and look for the
button.outcomeswitch statement in theHandleGameInputfunction. This is where the functionality of every selectable game option is defined. Create a case for your option following the structure of the others.
enum InputOutcome HandleGameInput(const struct GameInfo *info, struct GameState *state,
uint_fast8_t buttonInputIndex, const char *textInput) {
...
if (ButtonScreenInputType == state->inputType && UINT_FAST8_MAX != buttonInputIndex) {
...
switch (button.outcome) {
case GotoScreenOutcome:
state->screenID = button.newScreenID;
return GetNextOutputOutcome;
...
case GameOpenChestOutcome:
size_t openedChestVarOffset = GetGameStateOffset(state->screenID, 1);
if (openedChestVarOffset == SIZE_MAX) {
return InvalidInputOutcome;
}
uint8_t *pOpenedChest = (uint8_t *)(state->stateData + openedChestVarOffset);
*pOpenedChest = 1;
return GetNextOutputOutcome;
// <--- Your button outcome code here
...
}
...
return InvalidInputOutcome;
}