Author Topic: MODULE: Linear Story Progression 0.1.0  (Read 557 times)

MODULE: Linear Story Progression 0.1.0
« on: 16 Apr 2021, 14:19 »
Demo game
Module v0.1.2

I have created a simple module to make it easier when creating a story flow for your game.
It is still work in progress and more features will be added, but I thought I'd share it here anyway.

It is written in AGS
  - Name: Story Progression module
  - AGS Version:
  - Author: Tarnos
  - This module let's you specify which object/hotspot/character is required next step in progressing the story(Click door, talk to character, use item on the door > wouldn't allow you to do that in any other order)
  - No dependencies, except the fact that all objects/characters/hotspots used with this module CAN'T have any Interaction/Use item events. + unhandled_events function in GlobalScript can't/shouldn't be used either as that will interfere with this system.
Static functions to use
Code: Adventure Game Studio
  1. void StoryProgression.Add(LocationType, typeId, storyId, dialogId, emptyString(not used yet), roomId, interactionType(enum, not used currently), InventoryItem);
  2. void StoryProgression.AddDefaultDialogs(Character *characterRef, Dialog *dialogRef);
  3. void StoryProgression.InitializeQuestSystem(GUIControl *label);
  4. int StoryProgression.GetCurrentStoryId();//not really needed, since you have the function below, but you might have your own case.
  5. bool StoryProgression.IsStoryInRange(int min, int max);

All you have to do is use this static function to Add story parts:(probably in your game_start)
Code: Adventure Game Studio
  1. //Example: game_start:
  2. //Add quest gui label to display quest status.(tells you what to click or what item to use and where)
  3. StoryProgression.InitializeQuestSystem(gDebug);
  4. //Init default dialogs per character
  5. StoryProgression.AddDefaultDialogs(cEgo, cEgoDefault);
  6. StoryProgression.AddDefaultDialogs(cRoger, cRogerDefault);
  7. //Story progression
  8. StoryProgression.Add(eLocationCharacter, CHARACTER_EGO, 1000, DIALOG_01, "", ROOM_MAIN, eInteract, null);
  9. StoryProgression.Add(eLocationObject, OBJECT_DOOR, 1001, DIALOG_NULL, "", ROOM_MAIN, eInteract, iKey);
  10. StoryProgression.Add(eLocationObject, OBJECT_DOOR, 1002, DIALOG_02, "", ROOM_MAIN, eInteract, null);
  11. StoryProgression.Add(eLocationCharacter, CHARACTER_EGO, 1003, DIALOG_03, "", ROOM_MAIN, eInteract, iCup);

Inside your default dialogs per character mentioned above:(This default dialog plays ONLY if that interaction is not progressing the story, hence the default dialog

Click to watch the Video Sample which uses the default dialog below
Code: Adventure Game Studio
  1. @S  // Dialog startup entry point
  2.     if(StoryProgression.IsStoryInRange(1000,1000)){
  3.         cEgo.Say("Give me the key to progress the story");
  4.         player.Say("Ok, let me open my inventory");
  5.     }
  6.     if(StoryProgression.IsStoryInRange(1001,1002)){
  7.         cEgo.Say("Hey, did you click on that boot?");
  8.         if(StoryProgression.GetCurrentStoryId() == 1001){
  9.             player.Say("No...");
  10.             cEgo.Say("What are you waiting for then?");
  11.             player.Say("Sigh...");
  12.         }else{
  13.             player.Say("Yes, I did...");
  14.             cEgo.Say("Then bring me a Cup of coffee and we can finish this presentation");
  15.             player.Say("Where do I find the cup of cofee?");
  16.             cEgo.Say("Don't you have it in your pocket? Just throw it at me!");
  17.             player.Say("k");
  18.         }
  19.     }
  20.     if(StoryProgression.IsStoryInRange(1003,1005)){
  21.         cEgo.Say("Ugh...I will remember that");
  22.         player.Say("I don't know what to say");
  23.     }
  24. stop

Use this to assign gui label to the "quest" system included in this, it will track your current task i.e. "Use Key on Door1" or "Click on Ego", "Click on Window", "Use hammer on Window" etc
Code: Adventure Game Studio
  1. InitializeQuestSystem(GUIControl *label);//pass label used with this basic quest system

Customize what happens during different parts of the story, move characters, objects, make them disappear, play fireworks etc
Code: Adventure Game Studio
  1. //Unfortunately, since I can't figure out how to do custom event system, you will have to edit the function inside the module itself.
  2. function UpdateGameState(){
  3.     int storyId = Story[currentStoryProgression].ID;
  4.     int objectId = Story[currentStoryProgression].objectId;
  5.     int hotspotId = Story[currentStoryProgression].hotspotId;
  6.     int characterId = Story[currentStoryProgression].characterId;
  7.     int roomId = Story[currentStoryProgression].roomId;
  8.     int dialogId = Story[currentStoryProgression].dialogId;
  9.     String cutAwayName = Story[currentStoryProgression].cutAwayName;
  11.    //Default setup for all objects/hotspots
  12.     if(isInRange(1000, 1000, storyId)){
  13.         //set objects default text
  14.         storyObjectDefaultText.Set("oBoots", "Why is this floating boot doing here?!!");
  15.         //set hotspots default text
  16.         storyHotspotDefaultText.Set("Couch hotspot", "I should not touch this couch");
  17.     }
  18.     if(isInRange(1002, 1002, storyId)){
  19.         String bootObj = storyObjects.Get("oBoots");
  20.         int bootId = bootObj.AsInt;
  21.         object[bootId].Move(200, 100, 10, eNoBlock, eAnywhere);
  22.         storyObjectDefaultText.Set("oBoots", "Weird...");
  23.     }
  24.     if(isInRange(1003, 1003, storyId)){
  25.         cEgo.Walk(50, cEgo.y, eBlock, eWalkableAreas);
  26.     }
  27. }
  28. //This function is played each time a room is changed or story is executed(successful story progression)
  29. //Nothing is currently preventing it from repeating same task, so it's up to you for now, or don't do actions that would repeat itself(i.e dont play sound or SFX)
  30. //It assumes that object/hotspot you are interacting with is in the same room as the player during that story part(or rather after it since the function is called after successful story progression)

There are 2 interaction types: Interaction, Use item.(More might be added later, like walk on a hotspot etc)
This example uses #define values which you can see in the header
Location Object/Hotspot are REQUIRED to have room id specified, Characters don't because those are global.(objects/hotspots are per room) so just pass -1 or use ROOM_NULL
Pass -1 if not used and null for item if item interaction not required.
All objects/hotspots/items/characters can't have interaction/use item events attached to them.(The one you set with yellow lightning bolt icon in properties window)
Above applies ONLY if you plan on using any of them for this story, if not then feel free to use usual interaction event.
Soon when I update this module, you will be able to specify further what message is displayed when interacting with an object currently not used in the story(i.e. default text/dialog to be played if that object/character is not currently needed to progress the story)

#define in header + enum(no use right now, but will be later when more enum types are added)
Code: Adventure Game Studio
  1. //Hotspots
  2. #define HOTSPOT_ROOM_COUCH 6
  4. //Objects
  5. #define OBJECT_BOOTS 0
  7. //Characters
  8. #define CHARACTER_ROGER 0
  9. #define CHARACTER_EGO 1
  11. //Rooms
  12. #define ROOM_NONE -1
  13. #define ROOM_MAIN 1
  15. //Dialogs
  16. #define DIALOG_NULL -1
  17. #define DIALOG_01 0
  18. #define DIALOG_02 1
  21. enum InteractionType {
  22.     eInteract,
  23.     eUseItem
  24. };

Extra: the sample map and module itself come with "quest system", basically displaying your next step on gui label(module has it commented out due to not having GUI imported, but you can look up UpdateQuest function and figure out how to use it)

- Default dialog will be played when interaction is not progressing the story(if you setup the character + default dialog using static functions below)
- Until I figure out how to use custom event system, you will have to write your special interactions inside the module itself(function UpdateGameState)
- Added few static function to the module:
Code: [Select]
InitializeQuestSystem(GUIControl *label);
AddDefaultDialogs(Character *characterRef, Dialog *dialogRef);
int GetCurrentStoryId();
bool IsStoryInRange(int min, int max);
- Commented out some of the code with default story setup, now the module is "clean" and ready to use.
- Initial release
« Last Edit: 18 Apr 2021, 04:40 by Tarnos12 »