
NoGo - A Scriptable Game Framework - v1.5
Moderator: OpenTTD Developers
Re: NoGo - A Scriptable Game Framework - v1.5
Is there a bit left in the server list protocol to let servers indicate if they have a GameScript running or not? It would be nice if there is also a way to see the name of the script in the server info dialog but that would require more than just a single bit. 

My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Re: NoGo - A Scriptable Game Framework - v1.5
Make sure to include the genericTrueBrain wrote:If you can come up with other useful texts, we can have up to 32 buttons. So we have a few to go. Let me know what you think about this, and enjoy
BUTTON_1
BUTTON_2
BUTTON_3
so choices can be made that are described in the text. This would, for instance, enable random events like in Civilization IV, where a company gets to react to an event in one way or another, each way having particular advantages, disadvantages and/or risks.
The gouvernment of SomeTown asked you to provide transportation for their next annual work outing, free of charge.
1) Who do they think they are? (Offer might be extended to your competition)
2) Always glad to help! (Pay money, gain rating with SomeTown)
3) Agree, but forget to actually send the buses. (Lose rating with SomeTown)
Re: NoGo - A Scriptable Game Framework - v1.5
I remember in civilization 1 you had to answer random questions to get a free 'step' in your scientific advancement.
A trivia quiz like implementation seems possible with this buttons feature (and others) if i'm not mistaken (?)
But i'm struggling with ideas what this reward could be in ottd, respecting the scope of this framework,
just throwing out money seems dull...
A trivia quiz like implementation seems possible with this buttons feature (and others) if i'm not mistaken (?)
But i'm struggling with ideas what this reward could be in ottd, respecting the scope of this framework,
just throwing out money seems dull...
Last edited by lugo on 07 Jan 2012 03:03, edited 1 time in total.
-
- Tycoon
- Posts: 1660
- Joined: 16 Dec 2007 22:24
- Location: Idaho, USA
Re: NoGo - A Scriptable Game Framework - v1.5
Increase in town/station ratings perhaps?lugo wrote:I remember in civilization 1 you had to answer random questions to get a free 'step' in your scientific advancement.
A trivia quiz like impentation seems possible with this buttons feature (and others) if i'm not mistaken (?)
But i'm struggling with ideas what this reward could be in ottd, respecting the scope of this framework,
just throwing out money seems dull...
Eyecandy Road Vehicles | Fake Subways | Supercheese's NewObjects
"Fashions and cultures change, but steam trains shall always be majestic."
-Professor Hershel Layton
"Fashions and cultures change, but steam trains shall always be majestic."
-Professor Hershel Layton
Re: NoGo - A Scriptable Game Framework - v1.5
Unlocking vehicles? Changing industry production? New industry/town?
Correct me If I am wrong - PM me if my English is bad
AIAI - AI for OpenTTD
AIAI - AI for OpenTTD
Re: NoGo - A Scriptable Game Framework - v1.5
I wonder... would it be possible to implement an invest/research functionality with this which gradually unlocks new vehicles and buildings? As an extreme example, you could start the game with knowledge of basic road vehicles only. A predefined tech tree lets you choose what to research so your company can specialize in different transportation methods. This means you can focus for instance on trains by researching railways and different kinds of engines, or you focus on planes. If the Api allows un/locking of basic features, this mechanic could provide a very interesting gameplay aspect, especially in multiplayer games.
Re: NoGo - A Scriptable Game Framework - v1.5
You spend money on reasearch that reduces the random element of how long it takes to become avaliable? Sort of realistic i guessSimn wrote:I wonder... would it be possible to implement an invest/research functionality with this which gradually unlocks new vehicles and buildings? As an extreme example, you could start the game with knowledge of basic road vehicles only. A predefined tech tree lets you choose what to research so your company can specialize in different transportation methods. This means you can focus for instance on trains by researching railways and different kinds of engines, or you focus on planes. If the Api allows un/locking of basic features, this mechanic could provide a very interesting gameplay aspect, especially in multiplayer games.
The TT forums trivia tournament! Come along and join in the fun
http://www.funtrivia.com/private/main.cfm?tid=90722
http://www.funtrivia.com/private/main.cfm?tid=90722
Re: NoGo - A Scriptable Game Framework - v1.5
It seems like there are some odd things going on when using GSCompanyMode and GSNews.Create:
I thought Test 3 failed due to the script trying to create news as a company and figured this might be a "feature", but I really don't understand why Test 5 is failing, given that company should be out of scope again. Am I misunderstanding now GSCompanyMode works?
Code: Select all
function MyGS::Start()
{
this.Sleep(200);
for (local company_id_t = GSCompany.COMPANY_FIRST; company_id_t <= GSCompany.COMPANY_LAST; company_id_t++)
{
local company_id = GSCompany.ResolveCompanyID(company_id_t);
if (company_id == GSCompany.COMPANY_INVALID) continue;
// Normal mode
GSNews.Create(GSNews.NT_GENERAL, "Test 1", GSCompany.COMPANY_INVALID);
GSLog.Info(GSError.GetLastErrorString()); // ERR_NONE
// Unbound company
GSCompanyMode(company_id);
GSNews.Create(GSNews.NT_GENERAL, "Test 2", GSCompany.COMPANY_INVALID);
GSLog.Info(GSError.GetLastErrorString()); // ERR_NONE
// Bound company
local company = GSCompanyMode(company_id);
GSNews.Create(GSNews.NT_GENERAL, "Test 3", GSCompany.COMPANY_INVALID);
GSLog.Info(GSError.GetLastErrorString()); // ERR_UNKNOWN
// Company bound to invalid
company = GSCompanyMode(GSCompany.COMPANY_INVALID);
GSNews.Create(GSNews.NT_GENERAL, "Test 4", GSCompany.COMPANY_INVALID);
GSLog.Info(GSError.GetLastErrorString()); // ERR_NONE
}
// Normal mode?
GSNews.Create(GSNews.NT_GENERAL, "Test 5", GSCompany.COMPANY_INVALID);
GSLog.Info(GSError.GetLastErrorString()); // ERR_UNKNOWN
}
Re: NoGo - A Scriptable Game Framework - v1.5
Why do you use the company mode with News?
I think it is intended to be used along with functions that would normally be used by an AI when playing as a specific company. The GSCompanyMode enables a GS to execute API calls as if they were executing them as an AI for that company. The Create function of GSNews have a parameter for company and is probably intended to be used at the global GS "company". Thus you are probably violating a pre condition that GSNews. Create has to be executed as the GS "company" and not as a specific company. After all the News API is not available for AIs to use.
That said, as my hypothesis of a pre-condition of which company you need to execute the command as is not documented, it is a bug that should be reported.
For reference you can find the AI APIs here: http://noai.openttd.org/api/ So if a class is listed as GSXYZ but not AIXYZ or a method in that class only exist in the GS context, then the function is something new intended for Game Script usage only and not for AIs. Your best bet is probably that these functions are not intended to be used in the company mode. Instead I think the company mode is intended to execute so called DoCommands (actions that modify the game state in some way) as a specific company.
I think it is intended to be used along with functions that would normally be used by an AI when playing as a specific company. The GSCompanyMode enables a GS to execute API calls as if they were executing them as an AI for that company. The Create function of GSNews have a parameter for company and is probably intended to be used at the global GS "company". Thus you are probably violating a pre condition that GSNews. Create has to be executed as the GS "company" and not as a specific company. After all the News API is not available for AIs to use.
That said, as my hypothesis of a pre-condition of which company you need to execute the command as is not documented, it is a bug that should be reported.
For reference you can find the AI APIs here: http://noai.openttd.org/api/ So if a class is listed as GSXYZ but not AIXYZ or a method in that class only exist in the GS context, then the function is something new intended for Game Script usage only and not for AIs. Your best bet is probably that these functions are not intended to be used in the company mode. Instead I think the company mode is intended to execute so called DoCommands (actions that modify the game state in some way) as a specific company.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Re: NoGo - A Scriptable Game Framework - v1.5
Well I sort of figured it out. Have a look at this:
This works, but uncommenting the line after the Disaster comment makes the precondition fail. It seems Squirrel has a pretty funky way of resolving assignment scope. I don't know in which scope the company variable actually ends up, but it surely ain't the block scope of the for loop. What a pitfall...
Code: Select all
function MyTownGS::Start()
{
this.Sleep(200);
for (local company_id_t = GSCompany.COMPANY_FIRST; company_id_t <= GSCompany.COMPANY_LAST; company_id_t++)
{
local company_id = GSCompany.ResolveCompanyID(company_id_t);
if (company_id == GSCompany.COMPANY_INVALID) continue;
local company = GSCompanyMode(company_id);
// Disaster
//company = GSCompanyMode(company_id);
}
GSGoal.Question(0, GSCompany.COMPANY_INVALID, "Test", GSGoal.BUTTON_OK);
GSLog.Info(GSError.GetLastErrorString());
}
Re: NoGo - A Scriptable Game Framework - v1.5
When a GSCompanyMode object is created it saves the old value of current company so it can restore that when the object is removed. Your disaster line first creates a new GSCompanyMode object and assigns it to the variable "company". That means that after creating your new GSCompanyMode the old value from the original GSCompanyMode is restored.
You can probably avoid this by doing "company = null;" right before your disaster line. A better way would be to never re-assign something to a variable holding a GSCompanyMode object and never use GSCompanyMode twice in the same scope (in sub-scopes it would be ok, but only in a different variable).
You can probably avoid this by doing "company = null;" right before your disaster line. A better way would be to never re-assign something to a variable holding a GSCompanyMode object and never use GSCompanyMode twice in the same scope (in sub-scopes it would be ok, but only in a different variable).
Re: NoGo - A Scriptable Game Framework - v1.5
Thank you for the explanation. It's still not entirely clear why this happens though. I finally understand that the whole GSCompanyMode thing is related to instance lifetime, not instance scope (as I thought it was all the time).Yexo wrote:When a GSCompanyMode object is created it saves the old value of current company so it can restore that when the object is removed. Your disaster line first creates a new GSCompanyMode object and assigns it to the variable "company". That means that after creating your new GSCompanyMode the old value from the original GSCompanyMode is restored.
This doesn't explain why a double assignment causes issues though, because the first assigned instance loses all references the moment the second assignment occurs, and should thus be destroyed and restore the previous state (push pop push pop). This is either a Squirrel memory leak where the first instance is never destroyed, or a bug in your state handling code that causes it to miss the instance destruction.
Re: NoGo - A Scriptable Game Framework - v1.5
First the second instance is constructed (= assignment to some global of new company value). After that the new instance is assigned to the existing variable. When this happens the old instance is removed, which assigned the value it backed up when it was created to that global. That is why assigning null to the variable before assigning it a new instance might help.Simn wrote:Thank you for the explanation. It's still not entirely clear why this happens though. I finally understand that the whole GSCompanyMode thing is related to instance lifetime, not instance scope (as I thought it was all the time).Yexo wrote:When a GSCompanyMode object is created it saves the old value of current company so it can restore that when the object is removed. Your disaster line first creates a new GSCompanyMode object and assigns it to the variable "company". That means that after creating your new GSCompanyMode the old value from the original GSCompanyMode is restored.
This doesn't explain why a double assignment causes issues though, because the first assigned instance loses all references the moment the second assignment occurs, and should thus be destroyed and restore the previous state (push pop push pop). This is either a Squirrel memory leak where the first instance is never destroyed, or a bug in your state handling code that causes it to miss the instance destruction.
Re: NoGo - A Scriptable Game Framework - v1.5
I see, thank you again for the explanation. It's really obvious that the second construction happens before the first destruction, so I don't know why it took me so long to figure this out. Still, this whole concept is very prone to introducing subtle bugs, so it should at the very least be well documented.Yexo wrote:First the second instance is constructed (= assignment to some global of new company value). After that the new instance is assigned to the existing variable. When this happens the old instance is removed, which assigned the value it backed up when it was created to that global. That is why assigning null to the variable before assigning it a new instance might help.
Re: NoGo - A Scriptable Game Framework - v1.5
Technically it is documented (apart from the fact that when you assign a new instance to an existing variable the new instance is created before the old one is destroyed), but I completely agree it would be good to mention this pitfall better. Could you write an example of text we could include in the documentation for GSCompanyMode (so http://nogo.openttd.org/docs/trunk/clas ... yMode.html under the detailed description)?
Re: NoGo - A Scriptable Game Framework - v1.5
It just occured to me while writing this that there should be another problem: The backup company of the first instance should be the active company after the second line, right? The first destructor gets executed after the second constructor, so it will recover the company which was active when the first instance is constructed.Be very careful when assigning several instances of GSCompanyMode to the same variable within the same scope:Due to execution order, the second instance is created before the first one gets destroyed. This is almost never what you want to do as company_1 will be the active company once the second instance got destructed, because it was the active company when the second instance got constructed and is consequentially recovered. If you want to use the same variable again, you can null it before making a new assignment, which will cause its destructor to be executed.Code: Select all
local company = GSCompanyMode(company_1); company = GSCompanyMode(company_2);
Re: NoGo - A Scriptable Game Framework - v1.5
In programming languages that support variable sub scopes within named functions, I tend to put in extra scopes when I have temporary instances that I want to make sure get destroyed at some point. Eg. when you have a temporary variable that holds user input that has not yet been safe guarded. This also works good for the ***Mode classes in the AI/NoGo API in OpenTTD as squirrel is good at deleting variables when they run out of scope.
But you can also just null the mode variable and the reference counting should kick in and destroy the instance.
But you can also just null the mode variable and the reference counting should kick in and destroy the instance.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Re: NoGo - A Scriptable Game Framework - v1.5
Little correction: OpenTTD's version of squirrel is good at that.Zuu wrote:as squirrel is good at deleting variables when they run out of scope.
Re: NoGo - A Scriptable Game Framework - v1.5
Could you elaborate? I'm quite interested in these internals as it always helps to write scripts with a good performance.Yexo wrote:Little correction: OpenTTD's version of squirrel is good at that.Zuu wrote:as squirrel is good at deleting variables when they run out of scope.
Re: NoGo - A Scriptable Game Framework - v1.5
Not sure how much I can say about it. The official squirrel docs are here: http://squirrel-lang.org/doc/squirrel2.htmlSimn wrote:Could you elaborate? I'm quite interested in these internals as it always helps to write scripts with a good performance.
OpenTTD's code contains a few changes to the original squirrel code. IIRC one of these changes it to make sure the stack is cleaned when a scope ends (so objects are destroyed at the end of scope). In original squirrel this didn't always happen, objects might live a bit longer which (in combination with some of the api objects) could lead to unwanted behavior.
Who is online
Users browsing this forum: Ahrefs [Bot] and 5 guests