[TOTPP] Lua Scenario Template

Well, in Napoleon for exemple, the improvements are looked after by a function findImprovementByName(string), which then look each time in all 40 improvements for such a named improvement to return it.
Didn't put my head in recent codes howether, like OTR.

I wondered if this system using strings as reference had an advantage I may miss (nooby with lua after all) in compare with an early allocation like made with units, tribes and cities ?

You would have to ask @Knighttime or @tootall_2012 why they chose to use string comparisons to get objects. It may just be that everything was new, and the only example we had was a conversion of the Fantasy scenario by TNO. If the only 'known' options were either civ.getImprovement(id) or findImprovementByName(string), then the latter is certainly easier to use and read. I use that method in the Legacy Event Engine, but only because of the way the data is provided in a legacy events.txt file.

I would recommend the "object table" method of referencing things for a couple reasons:
1. It is more human readable than direct integer references.
2. It allows you to change the name of the object (unit type/city/improvement etc.) in the rules or game without breaking anything in your code.
3. If you want to change the 'slot' for the unit/improvement/tech/etc., you can make the change in one place, and have the rest of your code work.
4. You can "merge" unit types or improvement types by having 2 keys in the table reference the same value, and many events will still work properly. (I could probably come up with a counterexample with a bit of time, so you'll still have to test relevant events.)
 
I would recommend the "object table" method of referencing things for a couple reasons:
1. It is more human readable than direct integer references.

That's what I meant when I said the "integer" method - not that one wouldn't define them somewhere in an object file, just that at the end of the day the code searches for the integer rather than a name in a rules file, but thanks for clarifying.

Just from a design standpoint, if you're building a large multi-rules file scenario as I am in Hinge of Fate, going with strings would make things much more difficult. There's probably a way to use an and statement tying into turns or using flags for triggers that don't allow turn checks, but it seems like a lot more work/trouble.
 
I prefer too using an objects table like you launched the path.
Yet didn't see improvements in your template proposition, thus wondered if I was missing something :)
 
I prefer too using an objects table like you launched the path.
Yet didn't see improvements in your template proposition, thus wondered if I was missing something :)

No I just forgot to write them. We have i for improvements as you do.
 
Well, in Napoleon for exemple, the improvements are looked after by a function findImprovementByName(string), which then look each time in all 40 improvements for such a named improvement to return it.
You would have to ask @Knighttime or @tootall_2012 why they chose to use string comparisons to get objects. It may just be that everything was new, and the only example we had was a conversion of the Fantasy scenario by TNO. If the only 'known' options were either civ.getImprovement(id) or findImprovementByName(string), then the latter is certainly easier to use and read.
@Dadais Prof. Garfield is essentially correct. The event code in Napoleon works, but it was my first project using Lua and I was figuring out a lot of best practices as I went along, so please don't view it as the ideal way to tackle a given problem. I basically wrote the events for the first version of Napoleon while tootall_2012 finished working on the Rules.txt file simultaneously. The event specifications he sent me naturally referred to objects by their names, so I defaulted into writing the code the same way. But in retrospect, it's not really the best approach.

In my more recent project, Medieval Millennium, I switched over to using object keys. Most of them are defined in mmAliases.lua if you want to take a look (I actually used a separate table for each type of object, though, instead of a single "object" table with every type). Even though the code in Medieval Millennium contains many improved approaches, I have to make the same comment about it: I won't claim it represents the "best" way to tackle any given problem. I'm still figuring out more best practices and better ways to do things as I go along! :)
 
Last edited:
The event code in Napoleon works, but it was my first project using Lua and I was figuring out a lot of best practices as I went along, so please don't view it as the ideal way to tackle a given problem.
Truth, what you did is already so great one would easily forget it's finally already "old" :)
 
Does anyone of you guys know, if there are a LUA code which can restrict unit movings only on roads or railroads? For example a heavy Artillery unit could only move if it is on a road.
 
The city owner thing is easy and done in Napoleon and @Dadais WW2 scenario. I'm not sure about the road thing. I cant think of a way it would work, but maybe the better coders can.
 
Does anyone of you guys know, if there are a LUA code which can restrict unit movings only on roads or railroads? For example a heavy Artillery unit could only move if it is on a road.
The issues I see are :
-Make the AI not try to go with said unit on unroaded tiles.
-Control movement restriction for mouse-controled and goto ordered human player units.
 
Does anyone of you guys know, if there are a LUA code which can restrict unit movings only on roads or railroads? For example a heavy Artillery unit could only move if it is on a road.

I can't think of an 'elegant' way to do it, but here are some possible options:

1. Have duplicate terrain, a regular version and an impassible version. Periodically check for new roads and change the terrain from the impassible version to the regular version when they are detected. If the unit is AI controlled, perhaps check each adjacent square onActivation. I'm not sure how well the AI can handle a situation where most tiles are impassible, but otherwise, this seems the best solution if you don't mind losing some terrain variety.

2. Make all terrain impassible, and use key press events to move the unit via teleportation. This would allow you to check if the destination square can 'accept' the unit, and if so, you can teleport the unit to the square. This would probably prevent attacking. Perhaps make the unit a sea unit, and make the ocean impassible (you'd still get shore bombardment/ship in port combat changes). The AI would be unable to use this, and mouse movement and goto orders wouldn't work.

3. On activation, change the unit's movement and the movement multipliers to make it impractical for the unit to leave the road or rail. I'm thinking high movement multiplier, and deplete the units movement allowance so that only a few fractional movement points can be moved, and it would be difficult to move off the road. The AI would probably have difficulty using this, and it could be circumvented by activating a unit from within a city.

4. When a unit is activated, store that unit, its current moveSpent, and its location. When the next unit is activated, check if the previous unit is 'allowed' to be on its current square. If not, teleport it back to where it was before it moved, and restore its movement. This could cause problems for the AI, and might be exploitable for scouting, or by avoiding the unit activation event by selecting the unit from within a city.

5. Let the unit move off road, but apply some other penalty to it when it is not on a road. Maybe the heavy artillery automatically loses combat if it is not on a road. That wouldn't prevent the unit from going off road to reach combat, but it might be good enough. Again, you'd have to consider the AI (I'd probably make this sort of thing a human only restriction anyway).
 
6. On unit activation, create allied units on all nearby non road squares. The standard city activation evasion and difficulty of ai use still applies.
 
The city owner thing is easy and done in Napoleon and @Dadais WW2 scenario. I'm not sure about the road thing. I cant think of a way it would work, but maybe the better coders can.

Great to hear that it is easy to change the owner of one or more cities. I've some ideas in mind which should represent all these marriage things during the Renaissance period, where whole countries changed their ownership.
 
The issues I see are :
-Make the AI not try to go with said unit on unroaded tiles.
-Control movement restriction for mouse-controled and goto ordered human player units.

I can't think of an 'elegant' way to do it, but here are some possible options:

1. Have duplicate terrain, a regular version and an impassible version. Periodically check for new roads and change the terrain from the impassible version to the regular version when they are detected. If the unit is AI controlled, perhaps check each adjacent square onActivation. I'm not sure how well the AI can handle a situation where most tiles are impassible, but otherwise, this seems the best solution if you don't mind losing some terrain variety.

2. Make all terrain impassible, and use key press events to move the unit via teleportation. This would allow you to check if the destination square can 'accept' the unit, and if so, you can teleport the unit to the square. This would probably prevent attacking. Perhaps make the unit a sea unit, and make the ocean impassible (you'd still get shore bombardment/ship in port combat changes). The AI would be unable to use this, and mouse movement and goto orders wouldn't work.

3. On activation, change the unit's movement and the movement multipliers to make it impractical for the unit to leave the road or rail. I'm thinking high movement multiplier, and deplete the units movement allowance so that only a few fractional movement points can be moved, and it would be difficult to move off the road. The AI would probably have difficulty using this, and it could be circumvented by activating a unit from within a city.

4. When a unit is activated, store that unit, its current moveSpent, and its location. When the next unit is activated, check if the previous unit is 'allowed' to be on its current square. If not, teleport it back to where it was before it moved, and restore its movement. This could cause problems for the AI, and might be exploitable for scouting, or by avoiding the unit activation event by selecting the unit from within a city.

5. Let the unit move off road, but apply some other penalty to it when it is not on a road. Maybe the heavy artillery automatically loses combat if it is not on a road. That wouldn't prevent the unit from going off road to reach combat, but it might be good enough. Again, you'd have to consider the AI (I'd probably make this sort of thing a human only restriction anyway).

Hm, sounds very difficult for me. I think I don't use this idea.
 
Does it mean, if there are units in the city, they don't change the ownership together with the city?

There's different ways to deal with this, but changing ownership of the city does not change ownership of the units. Interestingly, it also doesn't delete them, or change their home city.
 
Here is the existing template. I realised that at this point, further developments/changes to Boudicca were probably going to be stripped out to make the template anyway. Documentation will come eventually. For the moment, know that the files in LuaCore and events.lua shouldn't be changed. These files might be updated/fixed, so you don't want to lose any changes you've made to them when they are replaced with an update (or, have to manually merge the changes).

Instructions:
1. Download the template files attached.
2. In the folder for your scenario, rename events.txt to legacyEvents.txt. (You don't want to overwrite all your events with an empty events.txt file in the next step.)
3. Copy the contents of the template (5 folders, 2 files) to your scenario's folder.
4. Move the file legacyEvents.txt into the LuaTriggerEvents folder, replacing the existing file (it is basically empty).

Note: If you haven't written any events in the old macro system, you can ignore steps 2 and 4.

When you load a game, you'll probably get a message about how the Legacy Event Engine has been updated. Choose to clear the saved data and save the game. You won't get the message again (unless you change your legacyEvents.txt file, or update the Legacy Event Engine).

I'm pretty sure there will be some bugs and errors to fix, so please report them. It is unfortunately rather difficult to find such bugs without actually using the code. I did make some very brief tests with Boudicca and @gapetit 's conversion of @Patient English 's Colonies IV.

@JPetroski, please replace Boudicca's LuaCore with the LuaCore in this template. It has some fixes/updates.
 

Attachments

Awesome news. I fully encourage every designer out there to take a look at this thread. In addition to Boudicca, I've ported over another scenario I had been building privately to this and I can tell you that this makes the process extremely easy. I'm at the point where I might just convert Midway to use it before releasing it as it makes it so simple (and Midway as it stands is a hot mess!) Cold War will be the last scenario I release that doesn't use it.

The flag system in particular is a hundred times easier than the state system earlier. There is no need to double check where you have everything. You can organize a scenario right in your object file by defining a series of flags and then reference them elsewhere with ease.

I'd invite you all to try this with a work in progress - what Prof. Garfield has built here really reduces the learning curve tremendously, and you can use Boudicca as an example of how to get started.

Speaking of which, Prof. Garfield, what are your thoughts about releasing that scenario? It is functioning as I want it to and it's purpose is simply to allow people to see the template in action. I don't know if there's a specific type of event it is missing that you think it should include, but I've used much of what I'd want in a scenario (indeed, a couple of the things I threw into Boudicca were to help me figure out how to throw them into my other project)!
 
Speaking of which, Prof. Garfield, what are your thoughts about releasing that scenario? It is functioning as I want it to and it's purpose is simply to allow people to see the template in action. I don't know if there's a specific type of event it is missing that you think it should include, but I've used much of what I'd want in a scenario (indeed, a couple of the things I threw into Boudicca were to help me figure out how to throw them into my other project)!

I think we're fine to release, since you made the fixes I suggested in the other thread. We don't have to do everything, and if we do too much, it will become more confusing than helpful anyway. Unlike OTR, fixing Boudicca doesn't mean interrupting months long PBEMs.
 
Back
Top Bottom