TEMPLATE: Tumbleweed Verbs 1.4

Started by abstauber, Sat 29/04/2017 15:41:50

Previous topic - Next topic

Flugeldufel

First of all: Thank you, abstauber for this nice template! Gefällt mir! ;)

I'm currently working on my first game and I changed some GUIs and sprites to match my taste. Among others I replaced the verbs with the ones shown in the screenshot.
Now I'm not sure, if (when I release this game sometime) I might get problems because it looks too similar to the original Thimbleweed-verbs. (although I drew them totally new for that low resolution, 320x180)

Should I change it? What do you all think?  ???



Here's a comparison of both:

mine:




Thimbleweed Park:


abstauber

Wow, those graphics look really nice!

Well the button font is quite close to the one of Thimbleweed Park - I'd say if you go commercial, you might want to go for a more independet route.

But if it's freeware I don't see any issues at all - the font (also the color) fits your game perfectly (as far as I can tell from your background)

Flugeldufel

Thank you very much for your feedback! And you confirmed what I already thought.
I don't know, if it's going to be freeware or commercial - it will depend on how complex the game will finally be, full length or not... We'll see. It's still at an early stage.
So I think I'll keep the sprites for now and maybe make some new ones later.

By the way, I would give the actual sprites to anyone who's interested in using them. Just let me know...


abstauber

Yes, out of the box, you are stuck with nine games. But you can of course extend the save/load gui to your liking: you just need to add more save/load buttons and tell the optiongui script about it.

abstauber

Maybe it's time to finally declare 1.2 to be stable.  (nod)

This is mainly a refactoring release, no new functions have been added so far. But internally the template has changed a lot.

- cleaned up the global script (moved the remaining GUI actions to the options menu module)
- Localisation of the GUI elements is handled a bit different internally
- It's possible to change the GUIs being used by the template
- Some more refactoring, the template throws errors if a module is missing.
- Bugfix: Option GUI wasn't translated if English is not set as default language


Crimson Wizard

#86
Hello, I'd like to report a bug.

Preferably performed in larger rooms for convenience:
* Have room 1 and room2;
* In room 2 script cutscene where player's character is walking non-blocking in After Fade-in event
Code: ags

player.Walk(x,y,eNoBlock);
while (player.Moving) Wait(1);

* Run the game, and when in room 1 start running with double-click;
* Immediately press Ctrl+X and change to room 2.

The player character will continue running during cutscene in another room.

Thinking about it, maybe it's enough to just run a cutscene in the same room. Guess the mistake is that character keeps running even when another Walk is called by a script command, even though it may not be required.

abstauber

Hi and thanks for the bugreport.

I think, that this is because I check the running in repexec and not repexec always. An easy thing to mitigate this for room changes would be to stop running, everytime you change a room. Also by using CTRL-X you're cheating a bit, as I'm checking for 'regular' room changes at line VerbGui.asc:2519 ;)

Running is also cancelled by every new mouseclick, so for this to happen you need to trigger a cutscene while the player is running without any other interaction or event. And the game designer would not stop the player from moving. The question is: how to detect such a cutscene.
I could use Game.InSkippableCutscene, but this would leave out unskipable cutscenes. Maybe a solution would be simply to add a StopRunning command which you would call in a cutscene

I'd love to get some more input on this.

Anyway to stop running also via CTRL-X room changes, this should do the trick
VerbGui.asc:2181
Code: ags

function on_event(EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein) {
    Verbs.CheckDefaultAction();
    Verbs.UpdateActionBar();
    
    verbsData.player_is_running = false;
    player.StopMoving();
    player.SetWalkSpeed(verbsData.player_walk_x_speed,  verbsData.player_walk_y_speed);
    player.AnimationSpeed = verbsData.player_ani_speed; 
  }
  
  else if (event==eEventRestoreGame) {
    //Verbs.AdjustLanguage();
    Verbs.InitGuiLanguage();
  }
}

StickGrinder

#88
Hello abstauber.

After lurking here for some time now I discovered this new template and decided to register to the forum just to say THANK YOU!.
I was trying to deconstruct the included 9-Verb MI interface this afternoon, not realizing it was maintained out of AGS itself and here we are with this successor that at a first glance is a big leap forward.
Can't wait to deep dive into it tomorrow.

EDIT: I read through the documentation and tested the template and I have two questions:

1. Is there any documentation about the inner working of the translations (i.e. contributors guidelines or such) that explains how and why they are addressed in that way?

2. Given TWP and pretty all modern game are built for widescreens, isn't it better to provide a 356x200 resolution out of the box instead of sticking with good old 320x200?

Thanks for your effort (all the contributors) and I hope I'll have something to show based on your work soon!
Cheers

abstauber

Thanks a lot, I hope you'll have fun with AGS and the template.
I'm afraid I'm still a sucker for the old resolutions, besides there are a lot of devices out there with a non 16:9 aspect ratio out there (Macbooks, Surface devices, Phones etc). So I'd like to keep the retro standard for now :)

As for the translations:
(bottom of the page)
https://github.com/dkrey/ags_tumbleweed/blob/master/doc/9verb_intro.rst

https://github.com/dkrey/ags_tumbleweed/blob/master/doc/9verb_translation.rst

StickGrinder

I see your point about resolution.

What's your position about derivative works? I mean, what if I commit to maintain a forked version of your Tumbleweed which defaults to widescreen devices?
Or possibly a sort of "add-on" package with pre-made WS assets?

I understand it's FOSS but I don't want to offend any unwritten rule of AGS community, nor you personally in any way.

abstauber

I think nobody has a problem with keeping or maintaining forks of the template.
Yet I can't imagine that 320x200 puts anybody off because of it's aspect ratio. Changing the resolution of a gameproject should be matter of minutes and art assets have to be created anyway.

Do you intend to maintain templates for 200p, 720p and 1080p? I could image that all this work wouldn't be worth it..

StickGrinder

#92
First of all, my apologies for the confusion: I was actually thinking about aspect ratio, not resolution, as you correctly pointed out.

That said, my opinion is that starting widescreen right out should add to the perception of something that can fit a modern production, not just emulating the golden era. Going 16:9 was also a choice that Terrible Toybox did for the referenced game, so that it kinda feels like a game from the 90s but it leverages what devices can do now.

The very good example by Fluegeldufel some post above shows that there should be interest in widescreen games after all :)
But of course I don't think anybody will put off by this template to be 4:3! It was just to help newcomers like me hit the ground running.

But most of all: I'm totally aware that those are my speculations and perceptions, probably not even worth the proverbial 2 cents.
If you or someone else in the community see any value in contributing this, I'm happy to help. If not, I'm happy to help anyway (stopping bothering you with my blurb)!  :grin:

Thanks again for your work and kind help, this template is so much cleaner and easy to grasp than the former one to someone like me!

Crimson Wizard

#93
Quote from: StickGrinder on Wed 14/08/2019 18:23:42
But of course I don't think anybody will put off by this template to be 4:3! It was just to help newcomers like me hit the ground running.

To be fair, this template is not 4:3, 320x200 is actually 16:10.

Of course it may be worth to stress out (in the manual or template's documentation) that user does not have to stick to template's resolution or aspect ratio; a well made template is resolution independent (and I believe this one is).

PS. With the upcoming AGS 3.5.0 release it's even possible to change game resolution while keeping all original demo assets, because it now allows to have rooms smaller than game res and, for example, center them on wider game screen.

StickGrinder

Quote from: Crimson Wizard on Wed 14/08/2019 18:55:31
To be fair, this template is not 4:3, 320x200 is actually 16:10.

One more reason to stop jabbering and leave things as they are :)
Thanks

abstauber

*bump*
Just released a new version with added compatibility for AGS 3.5

Oh, and I just noticed that I am maintaining these templates for over 10 years  :shocked:

Monsieur OUXX

Quote from: abstauber on Fri 27/12/2019 19:43:15
I just noticed that I am maintaining these templates for over 10 years  :shocked:

And you're doing a great job. You've saved me tens of hours of coding, for a sexy result.

I want to report that in font "tumbletext" (and TumbleTextOutline I imagine), special character "ç" is misaligned vertically. The "c" should be aligned like a normal c, and the thingie should dangle underneath it, lower than the line. A bit like a "j".
 

Khris

Small bug report:

import InventoryItem*ItemGiven; in GlobalScript.asc should probably be removed, and the documentation PDF about using the Give verb should use  Verbs.GetItemGiven()  instead of  ItemGiven.

Details in this thread: https://www.adventuregamestudio.co.uk/forums/index.php?topic=57962.0

Monsieur OUXX

A minor bug in the custom dialogs : There's no "scroll to top" after selecting a dialog option. Which means that if you click on, let's say, option 5, then the next time some options are displayed they will still be scrolled down. It's a bit awkward.

I fixed it like this (by the way, somehow the RunActiveOption was filtered out for the mouse wheel scrolling but not the plain old mouse click scrolling. I changed that too)

Code: ags

function dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
{

  CDG_Arrow uparrow;
  CDG_Arrow downarrow;
  int i;

  // Up-Arrow coordinates
  uparrow.x1 = info.X + CDG_options.uparrow_xpos;
  uparrow.y1 = info.Y + CDG_options.uparrow_ypos ;
  uparrow.x2 = uparrow.x1 + Game.SpriteWidth[CDG_options.uparrow_img];
  uparrow.y2 = uparrow.y1 + Game.SpriteHeight[CDG_options.uparrow_img];

  // Down-Arrow coordinates
  downarrow.x1 = info.X + CDG_options.downarrow_xpos;
  downarrow.y1 = info.Y + CDG_options.downarrow_ypos ;
  downarrow.x2 = downarrow.x1 + Game.SpriteWidth[CDG_options.downarrow_img];
  downarrow.y2 = downarrow.y1 + Game.SpriteHeight[CDG_options.downarrow_img];
  
//MODIFIED BY SEVEN CITIES - START
  bool isClickScrollUp = ((mouse.x >= uparrow.x1 && mouse.y >= uparrow.y1) &&
                         (mouse.x <= uparrow.x2 && mouse.y <= uparrow.y2))||
                         (button == eMouseWheelNorth && CDG_options.mousewheel);
       
  bool isClickScrollDown = ((mouse.x >= downarrow.x1 && mouse.y >= downarrow.y1) &&
                          (mouse.x <= downarrow.x2 && mouse.y <= downarrow.y2)) ||
                          (button == eMouseWheelSouth && CDG_options.mousewheel);
//MODIFIED BY SEVEN CITIES - END

  // scroll up
  if (isClickScrollUp) {
        i=0;
        
        while (i<CDG_options.scroll_rows)
        {
          if (CDG_options.scroll_from >1) CDG_options.scroll_from --;
          dialog_options_render(info);          
          i++;
        }
  } 
  // scroll down
  else if (isClickScrollDown) {
      
      i=0; 
      while (i<CDG_options.scroll_rows)
      {      
        if (CDG_options.scroll_to != CDG_options.active_options_count-1) {
          dialog_options_render(info); 
          CDG_options.scroll_from ++;
        }
        i++;
      }
  }

  info.Update();
  
  
//MODIFIED BY SEVEN CITIES - START
  //if (button != eMouseWheelSouth && button != eMouseWheelNorth) info.RunActiveOption();
  
  if (!isClickScrollDown && !isClickScrollUp){
    CDG_options.scroll_from = 0; // Scroll to top
    info.Update();
    info.RunActiveOption();
  }
  
//MODIFIED BY SEVEN CITIES - END
}

 

Monsieur OUXX

A small improvement but very convenient :

VerbsGui.ash

Code: ags

enum eObjectType {
  eGizmo, //use this type for regular-sized objects. Usually, objects that the player could physically pick up but doesn't need.
  eHeavy,  //use this type for objects that are too heavy to pickup/push/pull
  eCharacter, //appropriate responses to silly attempts like "opening" a human being.
  eDoor //similar to eHeavy but slightly more specific in regards to open/close/use
};

  // START MODIFICATION
  //import static void Unhandled(int door_script=0);
  import static void Unhandled(eObjectType objType = eGizmo,  int door_script=0); //I've put the new parameter first because you use it much more often
  // END



VerbsGui.asc
Code: ags

// START MODIFICATION
//static void Verbs::Unhandled(int door_script) 
static void Verbs::Unhandled(eObjectType objType, int door_script) 
// END
{


Then of course don't forget to update any call to Verbs.Unhandled in the template. When in doubt use eGizmo.
And of course don't forget to add all the new strings to verbsData.unhandled_strings. To sort them easily, you may get inspiration from these values :

Your own module
Code: ags

bool moduleInitialized = false;


String defaultSentence_Pull     ;
String defaultSentence_Push     ;
String defaultSentence_Give     ;
String defaultSentence_Interact ;
String defaultSentence_Look     ;
String defaultSentence_PickUp   ;
String defaultSentence_Talk     ;
String defaultSentence_UseInv   ;
String defaultSentence_Open     ;
String defaultSentence_Close    ;


function InitializeModule() {

  //unfortunately AGS script does not allow to initialize a default
  //String's value at declaration. We are forced to do it here
  
  //universal sentences for any object in the entire game
  defaultSentence_Pull     = "I can't pull that.";
  defaultSentence_Push     = "I can't push that.";
  defaultSentence_Give     = "That just won't work.";
  defaultSentence_Interact = "I don't know what to do.";
  defaultSentence_Look     = "I see nothing special about it.";
  defaultSentence_PickUp   = "Why would I want to pick that up?";
  defaultSentence_Talk     = "I shouldn't start talking to things.";
  defaultSentence_UseInv   = "That won't work.";
  defaultSentence_Open     = "I can't open that.";
  defaultSentence_Close    = "I can't close that."; 
    
  moduleInitialized = true; //make sure we don't call it again
}


//makes sure that all the relevant module stuff is initialized
function checkInitialized() {
   //at first call
  if (!moduleInitialized) 
    InitializeModule();
  
}

String FindWontWorkSentence() {
  String wontWork[10];
  wontWork[0] = "That won't work.";
  wontWork[1] = "I don't think that will work.";
  wontWork[2] = "Nu-uh.";
  wontWork[3] = "No.";
  wontWork[4] = "Nope.";
  wontWork[5] = "That's silly.";
  wontWork[6] = "Why would I try that?";
  wontWork[7] = "I'll have to think of something more useful.";
  wontWork[8] = "No way.";
  wontWork[9] = "I can't figure it out.";  
  
  return wontWork[Random(9)];
}


String FindWontGiveSentence() {
  String wontGive[4];
  wontGive[0] = "I'd rather keep that to myself.";
  wontGive[1] = "I won't give that away.";
  wontGive[2] = "Bad idea.";
  wontGive[3] = "Let's keep that to myself.";
  
  return wontGive[Random(3)];
}

String Sentence(Action_7CoG mode, eObjectType objectType) {
  checkInitialized();
  
  String sentence = "ERROR : no sentence returned.";
  
  if (objectType == eGizmo) { //See the definition of "eGizmo" in the Enum declaration
    if (mode == eGA_7CoG_Pull) sentence = defaultSentence_Pull;               //Pull
    else if (mode == eGA_7CoG_Push) sentence = defaultSentence_Push;          //Push
    else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();          // Give
    else if (mode == eGA_7CoG_Use) sentence = FindWontWorkSentence();  // Interact
    else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;        // Look
    else if (mode == eGA_7CoG_PickUp) sentence = "I don't need that.";        // Pickup
    else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;        // Talk
    else if (mode == eGA_7CoG_UseInv) sentence = FindWontWorkSentence();      // Useinv   
    else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;          // Useinv   
    else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;        // Useinv  
    else sentence = String.Format("Unknown mode : %d",mode);
  } else if   (objectType == eHeavy) { //See the definition of "eHeavy" in the Enum declaration
    if (mode == eGA_7CoG_Pull) sentence = "It's too heavy to pull it";                  //Pull
    else if (mode == eGA_7CoG_Push) sentence = "It's too heavy to push it";             //Push
    else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                    // Give
    else if (mode == eGA_7CoG_Use) sentence = "Let it be.";                        // Interact
    else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                  // Look
    else if (mode == eGA_7CoG_PickUp) sentence = "I can't pick up something that big!"; // Pickup
    else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                  // Talk
    else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                // Useinv   
    else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;                    // Useinv   
    else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;                  // Useinv   
    else sentence = String.Format("Unknown mode : %d",mode); 
  } else if   (objectType == eCharacter) { //See the definition of "eHeavy" in the Enum declaration
    if (mode == eGA_7CoG_Pull) sentence = "Violence is not a solution here.";               //Pull
    else if (mode == eGA_7CoG_Push) sentence = "I don't just push people around.";          //Push
    else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                      // Give
    else if (mode == eGA_7CoG_Use) sentence = "I don't randomly touch people.";        // Interact
    else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                      // Look
    else if (mode == eGA_7CoG_PickUp) sentence = "Yes, why don't I just carry everybody around on my back?";      // Pickup
    else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                      // Talk
    else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                    // Useinv   
    else if (mode == eGA_7CoG_Open) sentence = "You mean, open that person with a knife or something?";      // Useinv   
    else if (mode == eGA_7CoG_Close) sentence = "That doesn't make sense.";                 // Useinv   
    else sentence = String.Format("Unknown mode : %d",mode);
  } else if   (objectType == eDoor) { //See the definition of "eDoor" in the Enum declaration
    if (mode == eGA_7CoG_Pull) sentence = "It's too heavy to pull it";                  //Pull
    else if (mode == eGA_7CoG_Push) sentence = "It's too heavy to push it";             //Push
    else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                    // Give
    else if (mode == eGA_7CoG_Use) sentence = "Let it be.";                        // Interact
    else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                  // Look
    else if (mode == eGA_7CoG_PickUp) sentence = "I can't pick up something that big!"; // Pickup
    else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                  // Talk
    else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                // Useinv   
    else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;                    // Useinv   
    else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;                  // Useinv   
    else sentence = String.Format("Unknown mode : %d",mode); 
  } else { //the most possible generic sentences
    if (mode == eGA_7CoG_Pull) sentence = defaultSentence_Pull;               //Pull
    else if (mode == eGA_7CoG_Push) sentence = defaultSentence_Push;          //Push
    else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();          // Give
    else if (mode == eGA_7CoG_Use) sentence = defaultSentence_Interact;  // Interact
    else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;        // Look
    else if (mode == eGA_7CoG_PickUp) sentence = FindWontWorkSentence();      // Pickup
    else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;        // Talk
    else if (mode == eGA_7CoG_UseInv) sentence = FindWontWorkSentence();      // Useinv   
    else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;          // Useinv   
    else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;        // Useinv   
    else sentence = String.Format("Unknown mode : %d",mode);
  }
  
  return sentence;
}




 

SMF spam blocked by CleanTalk