Author Topic: TEMPLATE: 9-verb MI-style 1.6.3 - Last update: 21th June 2018  (Read 72367 times)

Hey, I hope it`s ok to bump this thread so I can ask something :D
I have been using this awesome template for a while to create my game, and only now have I stumbled across a little problem:
So far I could not find a way to make an on-screen object usable in the same way as an inventory item. So when you choose "Use" on that object,
the GUI will Show "Use Object with...", so I can use that object with another on-screen object.
I really have no idea how to achieve something like this. D:
It would be awesome if someone here could please help me out with this! :D

Khris

    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
    • Khris worked on a game that was nominated for an AGS Award!
The template doesn't support this; you'll have to script it yourself.

A "simple" way (or rather workaround) would be to allow the player to take the object, but when they walk away too far, remove it from their inventory again with an appropriate message (using a region to trigger that).

It`s me again :grin: Thanks for your answer Khris, however I totally forgot to look around in here again as I was experimenting around with the problem I mentioned above.

I am having a new question here...
It seems to be the case that the player character automatically moves towards another character when "Talk To" is selected.
Is there a way to remove that? I am having a few situations in the game where to player is supposed to stand on his spot when he greets another character from the distance.

Edit:
I managed to accomplish what I envisioned by removing this in the GuiScript:


...and thus, turning it into this:


Did the same for the "GiveTo" command and the TalkTo-function that is called via right click.
Works fine so far, now that I can manually set the WalkTo-points in my scripts, however it feels kinda wrong to edit the template this way.
I hope there are no problems arising from this (wtf)
« Last Edit: 27 Jan 2018, 13:03 by WatchDaToast »

Khris

    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
    • Khris worked on a game that was nominated for an AGS Award!
If you look at the start of the if block, right above the line you changed, you'll see that switching off the automatic approach is already available by setting approachCharInteract = false; at the top of guiscript.asc (together with a few other settings, like for instance the action bar's text color).

This also means that the change you made shouldn't have any unforeseen negative consequences since it has the exact same effect :)

Aah, so I could have just changed that instead. Good to know, thanks! ;-D

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on a game that was nominated for an AGS Award!
      abstauber worked on a game that won an AGS Award!
Here's a small bugfix release. I actually fixed this in the repo months ago, but forgot to compile a new template. So here it is :)

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
I'm trying to branch and/or create a pull request but it seems disabled in github. Have you disabled it for that project?

I don't think pulls are disabled, how do you do branching? Have you forked your own repository?

Monsieur OUXX

  • Cavefish
  • Mittens Vassal
  • Mittens Half Initiate
    • I can help with proof reading
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
Issue I had with git:
Add spoiler tag for Hidden:
1) cloned repo locally
2) using Git's local client interface, created a branch called "objectified"
3) Made changes
4) Commited changes (to local)
5) Tried to push changes --> it prompts me for my git credentials --> OK --> then it prompts me for some "git.com" credentials
   --> KO : It says "remote: Permission to dkrey/ags_9verb-template.git denied to jeancallisti. fatal: unable to access 'https://github.com/dkrey/ags_9verb-template.git/': The requested URL returned error: 403"

Note : 'jeancallisti' is my git account name.

EDIT: here is how I solved it :
Add spoiler tag for Hidden:


- when I cloned abstauber's remote repo, I wasn't logged into git, I just took the URL as it appeared on the screen.
- because of that, the URL did not contain my username, but instead Abstauber's user name : https://github.com/dkrey/ags_9verb-template.git
- The clone and the first commit went perfect so I didn't even notice, but that url was still stored in .git/config
- I had to edit that file manually with the proper URL : https://github.com/jeancallisti/ags_9verb-template.git
- Now the push went fine and my fork is in my own remote repo.
- Off to the pull request!

https://stackoverflow.com/questions/7438313/pushing-to-git-returning-error-code-403-fatal-http-request-failed

(phew, git is the only software I've ever encountered that's at the same time very straightforward and yet causing neverending confusion and human mistakes)
« Last Edit: 06 Jul 2018, 23:49 by Monsieur OUXX »
 

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Repositories are of course protected against direct pushes by default, otherwise anyone could modify anyone's repository at will without asking.
You need to create your own remote to be able to push there, and then create pull requests for abstauber's.

Press "Fork" button at abstrauber's page: that will create your remote copy, under your github account. Then either clone your remote to your local machine and redo your changes there (and push).
or, if you know how to configure remotes in local github repository, you could just switch path and tell it to sync with your remote instead of abstauber's.

« Last Edit: 03 Jul 2018, 23:07 by Crimson Wizard »

Monsieur OUXX

  • Cavefish
  • Mittens Vassal
  • Mittens Half Initiate
    • I can help with proof reading
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
Is the github repo up to date? 1.6.3 is from June 2018 but the repo shows last changes from 9 months ago.
« Last Edit: 04 Jul 2018, 22:28 by Monsieur OUXX »
 

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on a game that was nominated for an AGS Award!
      abstauber worked on a game that won an AGS Award!
Yes, the repo is up to date, I just added the tag for 1.6.3 belatedly.
I am still pondering about your pull request though. I agree that it's not very elegant to define all the settings in one giant init function and your code clean up sure is nice. On the other hand it doesn't seem very user friendly or at least I'm a bit concerned that it's so complicated that it might put users off

So instead of this
Code: Adventure Game Studio
  1.     CDG.uparrow_img     = 124;
  2.     CDG.uparrow_xpos    = 137;
  3.     CDG.init();
  4.  

you have to do that
Code: Adventure Game Studio
  1.  
  2.   int spriteSettings[] = CustomDialogGui.GetDefaultSettings_Sprites();
  3.   spriteSettings[eCustomDialog_uparrow_img] = 124; //custom sprite for up arrow
  4.   spriteSettings[eCustomDialog_uparrow_hi_img] = 137; //custom sprite for highlighted up arrow
  5.   CDG.ApplySettings_Sprites(spriteSettings); //apply the changes
  6.   CDG.init();
  7.  

And for every other settings group you need to create a new array. So what's the benefit apart from coding zen ;)
Anyone else has an opinion on this?


Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
I am still pondering about your pull request though. I agree that it's not very elegant to define all the settings in one giant init function and your code clean up sure is nice. On the other hand it doesn't seem very user friendly or at least I'm a bit concerned that it's so complicated that it might put users off
<...>
And for every other settings group you need to create a new array. So what's the benefit apart from coding zen ;)
Anyone else has an opinion on this?

I mentioned mine here: http://www.adventuregamestudio.co.uk/forums/index.php?topic=56226.msg636589682#msg636589682
Monsieur OUXX also explained why he needs it there; idk if that's rational for everyone though.

My impression was that there must be a way to expose these variables as "property array" without having them as arrays internally. But I did not have spare time to try that idea out and make an actual example.

EDIT: What I mean by "property array", you could declare an attribute of array type like this (random example):
Code: Adventure Game Studio
  1. struct CustomDialog
  2. {
  3.     import attribute int IndexedOptions[];
  4. }
  5.  
And then implement like
Code: Adventure Game Studio
  1. int CustomDialog::geti_IndexedOptions(int index)
  2. {
  3.     if (index == 0) return dlg.background_color;
  4.     if (index == 1) return dlg.foreground_color;
  5. }
  6. void CustomDialog::seti_IndexedOptions(int index, int value)
  7. {
  8.     if (index == 0) dlg.background_color = value;
  9.     if (index == 1) dlg.foreground_color = value;
  10. }
  11.  
« Last Edit: 27 Jul 2018, 13:50 by Crimson Wizard »

Monsieur OUXX

  • Cavefish
  • Mittens Vassal
  • Mittens Half Initiate
    • I can help with proof reading
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
Yes, the core reason was to expose stuff. The thing in abstauber's module that's most likely to be changed immediately after importing are the sprites and other settings. Thzrefore I exposed that part.
Ultimately that allows to set up your game around the module without having to modify the module's code (that would not be a problem with other languages, but with AGS it's a nightmare to have to re-import and re-modify an imported third-party module every time it's modified by its creator).

for every other settings group you need to create a new array.
Well you need to do that only if you want to change the default settings. Otherwise that's zero extra code.
 

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Yes, the core reason was to expose stuff. The thing in abstauber's module that's most likely to be changed immediately after importing are the sprites and other settings. Thzrefore I exposed that part.
Ultimately that allows to set up your game around the module without having to modify the module's code (that would not be a problem with other languages, but with AGS it's a nightmare to have to re-import and re-modify an imported third-party module every time it's modified by its creator).

Well, one thing is exposing options which is a right way to do, but another is exposing them as arrays, and that was what I found unusual and potentially inconvenient.

I have a feeling that there might be other ways to enumerate these options on your own without changing them to arrays in the standard template.
« Last Edit: 27 Jul 2018, 14:12 by Crimson Wizard »

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on a game that was nominated for an AGS Award!
      abstauber worked on a game that won an AGS Award!
Ultimately that allows to set up your game around the module without having to modify the module's code (that would not be a problem with other languages, but with AGS it's a nightmare to have to re-import and re-modify an imported third-party module every time it's modified by its creator)

Manually editing the CDG.init() function was the never the intended way of using the module. All variables inside the CDG struct are accessible from everywhere, so you can modify the dialog GUI from every script below the dialog script. So if you do the setup in game_start inside the globalscript (like you do now), you still will be fine, even if the module code changes.

To be honest, the best way of handling / designing custom dialogs would be inside the AGS Editor :P

Monsieur OUXX

  • Cavefish
  • Mittens Vassal
  • Mittens Half Initiate
    • I can help with proof reading
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
All variables inside the CDG struct are accessible from everywhere, so you can modify the dialog GUI from every script below the dialog script.

Yes, but I don't want to change the global variables anywhere in the code. I want to pass the global variables to that module only once, and then change the variables defined in that module, only in my one custom script that initializes that module.
Moreover, that's only 1/4 of what my changes do :
Add spoiler tag for Hidden:
1) they make the things accessible from outside (your answer addresses this, and I accept it)
2) they group the settings by category
3) they make them reflexive (accessible by index or name in the array of settings, allowing to tie them to an in-game console system)
4) they clarify the initialization sequence and keep the object in a consistent state (by letting you change a few settings and then calling the corresponding function in the module to apply them, instead of changing some variables values directly and then not being sure of what should be done for the change to be taken in account, or if something was broken).

More generally, I'd say that you guys have no mercy ;-D for people who build huge huge systems around your modules, because you don't perceive how much the smallest hesitations on the scripter's side ends adding up to lots of time wasted ("wait -- Did I change this setting myself or was it always like that? Should this module come before or after that other module? Damn there's an update. Is this new value meant to be overwritten by the custom value I used 2 years ago? I don't remember." etc.)
So anyways, at this stage I've explained why I went for those changes, that was my attempt at making your module more sealed from the rest of the code. So it's only my ego that keeps talking, there's no point in trying to convince you.
Thanks for taking the time of answering! See you around guys.
« Last Edit: 30 Jul 2018, 18:54 by Monsieur OUXX »
 

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
@Monsieur OUXX, These are valid points, actually, I don't know why you think that there is no point in trying to convince... I've automatically agreed to most of what you've said before, but I am not the template's author. Can't say for abstauber, but as I kept repeating my only confusion was about arrays part.

3) they make them reflexive (accessible by index or name in the array of settings, allowing to tie them to an in-game console system)
But could not this be also done without modifying the template itself (or rather - without having arrays inside abstauber's module itself, since there could be improvements of other sort)? I've shown an example of indexer property above, you could do this as a wrapper around abstauber's module, and even have these properties accessed by a string if you prefer. This way there will be two optional ways to access these settings: via strongly typed variables/attributes, and via custom indexer attribute(s).

Furthermore, with such approach you will have greater control, because if module changes with new update, you may still keep old order of variables in the indexer if you need one (e.g. in case you were saving these to the ordered list in file).

4) they clarify the initialization sequence and keep the object in a consistent state (by letting you change a few settings and then calling the corresponding function in the module to apply them, instead of changing some variables values directly and then not being sure of what should be done for the change to be taken in account, or if something was broken).
This problem is because majority of the classic modules and templates are written in "C-style" (which is actually not real "C-style", but rather "bad C-style"), where many variables are just left public. Normally they should be hidden behind Set/Get functions or properties (attributes in AGS), which are get/set functions too internally. And when SetX function is called, it should've taken the setting change into account (or at least user could presume it does).
« Last Edit: 30 Jul 2018, 22:14 by Crimson Wizard »

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
What I mean by "property array", you could declare an attribute of array type like this (random example):
Code: Adventure Game Studio
  1. struct CustomDialog
  2. {
  3.     import attribute int IndexedOptions[];
  4. }
  5.  
And then implement like
Code: Adventure Game Studio
  1. int CustomDialog::geti_IndexedOptions(int index)
  2. {
  3.     if (index == 0) return dlg.background_color;
  4.     if (index == 1) return dlg.foreground_color;
  5. }
  6. void CustomDialog::seti_IndexedOptions(int index, int value)
  7. {
  8.     if (index == 0) dlg.background_color = value;
  9.     if (index == 1) dlg.foreground_color = value;
  10. }
  11.  

Wait, can you actually do this in AGS script, or is this just something that ought to be possible? I never knew about this, if it's possible! Way cool!

This problem is because majority of the classic modules and templates are written in "C-style" (which is actually not real "C-style", but rather "bad C-style"), where many variables are just left public. Normally they should be hidden behind Set/Get functions or properties (attributes in AGS), which are get/set functions too internally. And when SetX function is called, it should've taken the setting change into account (or at least user could presume it does).

Yeah, but on the other hand, in the SpeechBubble module, more than half the code is just getters and setters for the various attributes. 8-0

If you're not actually doing any logic in them (I'm doing this whole inheritance system, which is part of the reason it takes up so many lines), just setting and returning an underlying variable, there's really no benefit: it just takes up space in the module, makes the code harder to skim, is a potential source of bugs (if, for example, you copy-paste the getters and setters and miss one of the variables that need to be changed), and adds a little bit of execution overhead.

You can replace a variable with an identically named attribute later on without changing any of the code that calls it (one of the great benefits of properties/attributes over getter/setter functions), so you might as well leave them as plain public member variables until you actually have any need for special handling.

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on a game that was nominated for an AGS Award!
      abstauber worked on a game that won an AGS Award!
@Monsieur OUXX:
First of all, I really appreciate that you share your hard work with us/me and it's quite educational how you did things.
That said, I do not understand why you haven't refactored the fully fledged dialog module instead (http://www.adventuregamestudio.co.uk/forums/index.php?topic=36313.0) :confused:
If I accept your pull request now I'm in the delicate position that I have to apply all your changes to the parent module at some point.

Btw. because of this problem I usually do not integrate 3rd party modules in my templates. For the dialog GUI I made an exception because the default dialog in AGS is very very basic.
Also if I accept the pull request, it would make sense to apply these changes to the GUI script itself. This would as well be a major task and the new settings array doesn't help code-readability either.

Another thing is the refactored module still has around 13 options left which are not covered by the settings array - correct me if I'm wrong.
Edit: The function dropdown in the AGSEditor is also broken in your version of the customdialoggui.asc.

But enough of that... my main point is: if we change the way how variables are assigned, let's do it for the whole template.
I agree with Snarky: adding dozens of setters and getters (I know this from some if my modules too) blows up the code a lot. I like CW's approach, just with an enum instead of plain index numbers. But what difference makes " import attribute int " instead of a regular import?
« Last Edit: 31 Jul 2018, 13:42 by abstauber »

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
I agree with Snarky: adding dozens of setters and getters (I know this from some if my modules too) blows up the code a lot. I like CW's approach, just with an enum instead of plain index numbers. But what difference makes " import attribute int " instead of a regular import?

Regular imports are just for functions: You don't import a member variable into a struct, you just declare it, and it gets added to that struct's data schema (so for every instance of the struct, you have to allocate that amount of memory to store it). Attributes, on the other hand, create properties that look like variables from the outside.

Declaring something as an attribute import means that it's "not a real variable": it's a function or functions called accessors (the getters and setters) pretending to be a variable. Functions aren't stored with the struct data, so they take up no additional space for each instance. Normally the important thing is that you can perform processing when you set the value, such as validation or updating other dependent data, and that you can store the data in a single, canonical representation but access it in alternative forms that are simply generated on demand (for example getting the right-edge coordinate of an object by adding the left-edge coordinate and the width, rather than storing it redundantly).

For properties that are regular variable types this is fairly routine, but I didn't know you could (in AGS) also write accessors that pretend to be not just a variable but an array of variables.

Sorry if this seems patronizing, you probably knew most of it already, but I wasn't sure exactly what part of it had you confused.