How do I add the same code to every room? (SOLVED)

Started by EnterTheStory (aka tolworthy), Wed 12/12/2007 00:23:53

Previous topic - Next topic

EnterTheStory (aka tolworthy)

My game has 140 rooms. I often want to call identical code from each room. Each time I have to open each room and press several buttons to get to the interaction I want, then add the code, press more buttons, save the room again... It takes ages.

Is there any "master room" that I can change that will automatically change all the others? Or some way to treat the rooms as text files so I can add an interaction using global search and replace? Or some other way to avoid the mind-numbing tedium of repeating the same actions 140 times?

monkey0506

#1
I think you're looking for the global script. You can set up a function there like this:

Code: ags
function my_func() {
  do_something();
  do_other_stuff();
  }


Then in your global header put:

Code: ags
import function my_func();


Then you can call my_func() from any script (except module scripts (if you need it in a module script for any reason, simply put the function in a module higher than the one you need it for)). So instead of duplicating the code you can call this function. Of course you would still have to put a function call everywhere you want the code, but it's a lot easier than duplicating the code all over the place, and then if you need to change anything, you only have to change it once.

The process is even simpler if you're wanting to execute this code as soon as the player enters/leaves the room in which case you can use the on_event function in the global script:

Code: ags
function on_event(EventType event, int data) {
  if (event == eEventEnterRoomBeforeFadein) {
    // put 'player enters room' code here
  }
  else if (event == eEventLeaveRoom) {
    // put 'player leaves room' code here
  }
}

EnterTheStory (aka tolworthy)

#2
Quote from: monkey_05_06 on Wed 12/12/2007 04:48:21
Of course you would still have to put a function call everywhere you want the code

That's my whole problem! I have to add the exact same function call into the exact same place in 140 rooms.

Quote from: monkey_05_06 on Wed 12/12/2007 04:48:21The process is even simpler if you're wanting to execute this code as soon as the player enters/leaves the room.

EDIT:

Thanks for the suggestion, but it seems my initial guess was right. AGS 2.7 is very limited in what it will let you script - most things have to be tediously added by clicking the same buttons in every room, again and again and again. Man, this is depressing.

To clarify, if I understand the manual, on-event only allows for code being run before the "before fade in" event. It does not allow for code being run immediately after the "before fade in" event. It does not allow code immediately before the "after fade in" event. It does not allow code immediately after the "after fade in" event. The list goes on and on. Every day I need to make a change like this it's "here we go again, time to do the exact same thing one hundred and forty times."

I am a great fan of AGS, even allowing for this, but this limitation appears to suck. In a script-based engine I would simply open a folder full of rooms and do a global search and replace. Or if there was a "master room" I would simply edit that. The whole process should take about thirty seconds. But instead it takes about an hour to add or modify a single function call - open each room, click on interactions, click on the interaction I want, click on the list of choices, click on "run script," paste the function call, click on OK, click on OK again, do CTRL_R to save the room, click on the list of rooms, select the next room, and repeat, one hundred and forty times. That takes about forty minutes, then another twenty minutes to rub my sore wrist and work up the enthusiasm for the next mind-numbing task.

I know I have no right to complain. Nobody is forcing me to use AGS, and nobody is asking for money, and everyone is so generous in offering help. But AGS is so wonderful in other areas that this is like driving a fast car into quicksand.

Ashen

You might be able to fake it if you disable the 'Fade In/Out' transition and script it in on_event using the FadeIn/Out fuctions (as in this thread). You can then call things before and after the fade in. Anything that's Room specific can probably be handled using CallRoomScript, and placed in the Room script using on_call instead of the default before/after fadein' interactions. (Or, use the data parameter of on_event to get the current room, and have a bunch of conditions in the Global script.)

Quote
Every day I need to make a change like this it's "here we go again, time to do the exact same thing one hundred and forty times."

Why do you need to change the function call each time? Once the call is in place (my_func();), changing the body of the function will change what happens every time it's called ... Am I missing something?
I know what you're thinking ... Don't think that.

EnterTheStory (aka tolworthy)

Quote from: Ashen on Wed 12/12/2007 11:40:14
You might be able to fake it if you disable the 'Fade In/Out' transition and script it in

Eureka! That's what I wanted. At least, that will solve my immediate problem, involving walking into the room. Thanks!

Quote from: Ashen on Wed 12/12/2007 11:40:14Why do you need to change the function call each time?

I'm probably not using the right terminology. But it seems that whenever I make a change to the game I get an error message, and solving it means adding another 140 calls.

To illustrate, this is my current task. Please note that this is for historical interst only. I've now added all the code heer so have no wish to go back and change it (unless there's a dramatically simpler solution). I'm making making ego walk in and out of exits using three XY coordinates for each journey (ie. ego walks off the floor, through a gate, then turns and walk out of sight). In my previous game I had various coordinates for each exit, so I copied these into the ""before fade in" interaction for each room. That was fair enough - the numbers were different for each room, so it made sense to put them in that place. After that I realised that I would need to call a function from each room, to add ego and read those exit numbers. That was the first time I added the identical function call to every room.

Foolishly I added it BEFORE setting the exit points, so that didn't work. So once again I had to add another function call to every room - this time after the exit points were set. But that didin't work either, because AGS won't let ego walk anywhere before the fade in.  So again, for the third time, I added another function call to the "after fade in" interaction for each room.

Add the fact that I often have to make minor changes to all the background images (e.g. to add extra space to walk below the level of the screen), or change all the floors (to remove secondary floors - these were causing problems if ego accidentally jumped to the wrong floor), or change all the hotspots, etc., etc., and I seem to spend all my time opening ten or twenty or a hundred rooms at a time to do stuff that previously I would have changed asll at once in a text file using search and replace.

Eventually I will just get used to thinking in a different way. Sorry to keep making the comparison with Sludge, but with Sludge there is no built-in "room" and no pre-compiled graphics, so changing anything is as simple as doing a global search and replace in a script. It's a real culture shock to find that the final script is not directly accessible as a text file.

I must emphasize that although this is a big complaint, I still prefer the AGS room based metaphor. The fact that Sludge has no built in rooms caused huge headaches when something complicated was supposed to end when a room ended. In AGS the rooms are cleanly separated. I guess that some restriction on cross-room coding is inevitable.

Still, if there is a "wish list" section this is mine: ideally, being able to export or import all the rooms as a big text files (or at least many small text files), and allowing interaction events to be added from the script. Failing that, it would be extremely helpful to have all the interaction events accessible to "on_event" and not just a select few as now.

Ashen

OK, I see. No, there's no way around that kind of trial and error testing, sometimes. However, if I'm understanding right, you're trying something across 140 rooms, it doesn't work so you have to make a change across 140 rooms, still doesn't work so make ANOTHER change across 140 rooms, etc. That would get pretty mind-numbing, yeah. But surely the sensible thing would be to try it in one or two rooms until you're sure it works, THEN add it to the other 138?

It kind of seems like your problem here isn't so much the way AGS handles Room functioning (although an eEventAfterFadein would be a decent addition), but just being too ambitious - not in the overall scope of the project, but in trying to do everthing at once. Pick a room, work on it, figure out what functions will be needed in other rooms and make them global, finish the room, move on to the next. There might not be any way around having to add function calls to each individual room, but by minimising the number of rooms you're working on at any one time, you minimise the number of changes you have to make until the bugs are worked out. This is another reason people usually recommend working on a small, one or two room, test game to start with, instead of leaping right into a 140+ room masterwork. Also why I have a couple dozen 'games' with just a single piece of functionality in them - to get it working without having to mess up a larger project along the way. (Not that I have any larger projects :))
I know what you're thinking ... Don't think that.

EnterTheStory (aka tolworthy)

Quote from: Ashen on Wed 12/12/2007 13:22:05
surely the sensible thing would be to try it in one or two rooms until you're sure it works, THEN add it to the other 138?

Sensible? That's a technical word I'm not familiar with. :)

Quote from: Ashen on Wed 12/12/2007 13:22:05
being too ambitious - not in the overall scope of the project, but in trying to do everthing at once. Pick a room, work on it...

Yes, I've been thinking about the ambition thing a lot lately, though not in that exact way. But first, in my whining defense, I did have the code working perfectly in two rooms first, or so I thought. But the problems only become apparent when I combine rooms, because every room will add something new and unexpected. Also, the "everything at once" method worked fine in Sludge, because it isn't room based. You could easily begin with hundreds of  rooms in a simple state, then globally add more and more features. With Sludge uit's easy to get the big structures right before focusing on individual rooms, in AGS it's the other way around.

But I'm rambling. If you'll forgive me navel gazing for a while, ambition is the key. My strength (I think) is ambition, in that I have a clear idea of a very large, achievable, unique, and interesting final product. But my weakness is in trying to create the greatest code, the greatest art, and the greatest puzzles. I'm not superman! To achieve the core objective (a very large game packed with seriously interesting stuff) I need to spend more time on what I'm good at, and less time on what other people do better.

I am starting to think that instead of "polishing" the AGS code to get the exact look I want, I should instead just use the default code and methods, add my own graphics, and spend more time on the story. So I may well rip out many of the troublesome code, remove the redundant scenes and redesign the game in a way that it might actually be finished on schedule.

This is all one big learning curve! Thanks for your timely advice. I don't know how you do it and still have a regular life.

RickJ

#7
Perhaps this tid-bit may be of interest  here, although you may have passed the point where it could have been  useful...

If you knew before hand that you had to have 140 rooms with some of the script being exactly the same of signicantly so, then you could create a template room and save it as _blank.crm.  Then whenever you create a new room it will be created with all the interactions, code, etc that is in the template.

If I understand you correctly the main problem is creating the interaction events and then having to enter the same script into them that occur in other rooms.    May I suggest that you edit one room to you liking and collect all of those things that are to be repeated into a contigous region of the file and then copy that section into the clipboard.  Now, open the next room, click on the events button, then go into the script select the newly added events, and then paste over them with the code in your clipboard.  Of course this requires that the names of any involved objects, hotspots, etc are named the same across rooms.  This applies to AGS 3.0 only.

Since there has been a huge change interaction events are created./handled in AGS 3.0  it may be possible that the event button only creates the appropriately named function and that just having a function with the right name is the only think needed to create the event?  I'm not at all sure about this, the odds are probably against it, but in your case it would be worth giving it a try.




Pumaman

Also, you could look into the Custom Properties. You can set Properties on a room, so you could create a Property for the X,Y co-ordinates that you want the player to enter from, and set this up in each room.

Then, just put some code in the global script on_event function to read the current room properties and move the character from that location.

monkey0506

Quote from: Ashen on Wed 12/12/2007 13:22:05(although an eEventAfterFadein would be a decent addition)

It always seemed odd to me that we would have eEventEnterBeforeFadein but not eEventEnterAfterFadein. :-\

EnterTheStory (aka tolworthy)

Quote from: RickJ on Wed 12/12/2007 16:30:43If you knew before hand that you had to have 140 rooms with some of the script being exactly the same of signicantly so, then you could create a template room and save it as _blank.crm.  Then whenever you create a new room it will be created with all the interactions, code, etc that is in the template.

Hindsight is a wonderful thing. :) Thanks - that looks like the elusive "master room" idea I was looking for, or close enough. And thanks to all the others who made suggestions.

Just to tie up the loose ends, I've been reviewing the situation (cue Fagin music) and have decided to cut the Gordian knot. I'm recreating the 140 room game with only the most essential 80 rooms, and I'm removing all non-essential code in favor of using the tried and tested default AGS methods. I figure that for me, a very amateur programmer, the time I spend on customizing code (then bugfixing it later) would be better spent on the game story itself.

SSH

You can dump the entire game scripts to a file, edit the file and re-import them. You musn't change anything about the game between export and import, though.

Also, I think you can check for After Fadein globally by:

In the on_event before fadein code:
Code: ags

    somevar=1;


In global repeatedly_execute:
Code: ags

  if (somevar) {
     somevar=0;

     // After fadein code
  }


Since rep_ex doesn't run during fades


12

SMF spam blocked by CleanTalk