Over the Reich - Creation Thread

@Prof. Garfield is the error below the same one you ran into, or is the nil value call at 'replaceInfo' indicative that there is another rogue cloud left out there at the start of the scenario?

Code:
57, 5, 1, 61665
D:\Test of Time\Scenario\OTR3\clouds.lua:153: attempt to index a nil value (local 'replaceInfo')
stack traceback:
    D:\Test of Time\Scenario\OTR3\clouds.lua:153: in upvalue 'clearCloud'
    D:\Test of Time\Scenario\OTR3\clouds.lua:173: in upvalue 'clearAllClouds'
    D:\Test of Time\Scenario\OTR3\clouds.lua:388: in function 'clouds.updateAllWeather'
    D:\Test of Time\Scenario\OTR3\events.lua:4782: in function <D:\Test of Time\Scenario\OTR3\events.lua:4780>
57, 5, 1, 61665
 
If it happened the first time you pressed 6, then there is a rogue cloud at (57,5,1). Otherwise, it is the error that I have had.

I'm thinking that in addition to storing the squares replaced by clouds, I'll also store all squares in a backup table, so the game doesn't break over this error, even if the wrong square is put back.
 
Yes it must be the strange bug then. I haven't been able to reproduce it. The next time it happens to either of us I'd like to see if saving the game, reloading, and going back to pressing 6 will cure the problem or not. If it does, annoying as the bug may be, it's not really game breaking. Hopefully your solution resolves it entirely, however.

I've gone through and put together 7 storms with 5 categories each. I do notice that when several get on the screen it can take about a second per hit of '6' for them to populate. I'm going to add in another 1 or 2 for variety and am hoping I won't crash the game doing so.
 
I'm pretty pleased with the cloud coverage with 8 storm types at 5 intensities each but might throw in some smaller ones just to mix it up a bit. There seems to be a pretty good balance where it is possible to have good weather for several turns but also very possible for a huge storm to form, covering most targets. From what I've read, European weather scrapped more than a few Allied bombing raids.



I've also made a short film showing off the latest edition of @Prof. Garfield Is A Genius :)

 
Would it be possible to render the clouds as one of those terrain overlay? Or is that what's already being done? Or maybe as resource sprites or rivers?
 
I'm not sure what you mean by terrain overlays, but it's not possible to use rives as far as I know and special resources wouldn't look any better than the border issue due to lack of variety.
 
I'm not sure what you mean by terrain overlays,
I was referring to the forest/mountains/hills kind
but it's not possible to use rives as far as I know and special resources wouldn't look any better than the border issue due to lack of variety.
Fair enough.
 
Changelog 7 december

Entries in the map storage table are not deleted anymore, so after a cloud is placed on a tile, there should always be something to revert back to. Hopefully, this will solve the bugs.

Clouds will not be placed on terrain 4 (urban) on the night map, nor on any ocean square adjacent to land (on a no cloud map) unless that square has a military port unit in the file I used to make the table. Clouds cannot form adjacent to a military port, in the same way they can't on ocean next to land.

Since Map 0 doesn't get clouds anyway, my program to generate the table didn't include the coastal ocean on map 0 in the table.

The function that sets the urban defense value is called 'setUrbanDefenseValue' At the moment the default value of defence is 24, and it is reduced by 2 if the player has tech 17 (advanced Radar I) or 19 (advanced radar II). The default and the drops can be set in the special numbers.

The urban defences are adjusted after production for each player (so the increased defences may not be obvious when opening the game).

console.afterProduction() runs the afterProduction routine for the current turn and tribe. This will, among other things, update the urbanDefense civlopedia entry.

If units are killed in the reaction sequence, they now modify the player scores.

Have introduced modifiers for the damage roll for the target reaction, the area damage to reacting units, and the area damage to bystanders. Have not introduced a modifier to the actual damage output, since there are various places where that value is 'returned', but the damage roll is only done once in a function. If modifying damage (and not chance of damage) is desired, that can be accomplished.

Search for 'damage roll modifier' to be brought to the top of the tables governing this. There are 3 such tables, indexed by unitType.id. The details are stated in the file. There are 3 tables where you can set default behaviours. The tables are filled in with references to the default tables (I switched to VIM, and discovered macros, so it wasn't actually all that much work), but there are unit entries that can be deleted, especially in the area damage tables.

More functionality can be included if there is a need for it.

Almost no testing was done on the reaction modifiers.

At this point, I think that the only 'necessary' coding left is to fill in the aforementioned tables (which I'll let you do) and to do the historic targets. Improving combat reporting or the newspaper or something is nice but not essential.

The events are available.
 

Attachments

Ok so just so I have a productive evening digging into this let me make sure I understand completely because I'm not sure I follow you:

First of all, let's make sure I understand where to look:

targetDRM = {} is a table of the unit that is actually being targeted by the reactive defense, correct? In other words, the unit that calls up ammo to start the reaction?
areaReactDRM = {} is a table of the units that might be near the targeted unit (so "splash damage" where flak can damage a few B-17s for example when one calls up ammo. Correct?
areaBystanderDRM = {} is a table of friendly units that might be hit by friendly fire "splash damage"? Correct? I don't think we ever implemented this so I'd probably just leave this table blank.

Then as I understand it you've provided me with a default standard:

Code:
dTM = {clouds = 1.5, cloudsTech1=nil, cloudsTech1Mod = 1, cloudsTech2=nil, cloudsTech2Mod=1, tech1=nil, tech1Mod=nil, tech2=nil, tech2Mod=1, enemyTech1=nil, enemyTech1Mod=1, enemyTech2=nil,enemyTech2Mod=1,counterToEnemyTech1=nil, counterToEnemyTech1Mod=1,counterToEnemyTech2 = nil, counterToEnemyTech2Mod=1,}

But, if I wanted to have, say, Lancasters take less damage in clouds then directly underneath the above, I'd write:

lancasterTM = {clouds = 3, cloudsTech1=nil, cloudsTech1Mod = 1, cloudsTech2=nil, cloudsTech2Mod=1, tech1=nil, tech1Mod=nil, tech2=nil, tech2Mod=1, enemyTech1=nil, enemyTech1Mod=1, enemyTech2=nil,enemyTech2Mod=1,counterToEnemyTech1=nil, counterToEnemyTech1Mod=1,counterToEnemyTech2 = nil, counterToEnemyTech2Mod=1,}

And then in the lancaster line in the table, I'd change to:


targetDRM[unitAliases.Lancaster.id]={clouds =lancasterTM.clouds, cloudsTech1=dTM.cloudsTech1, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=dTM.cloudsTech2, cloudsTech2Mod=dTM.cloudsTech2Mod, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}


Edit -- Or would I need to change ALL of the dTM in the lancaster colum to lancasterTM at this point?

And so on and so forth for any one of the entries I desire to change? (In this example I'm only trying to make it harder to directly shoot down a lancaster in the clouds, but it's my understanding that I could also change the other fields as well)?

Do I have this correct? I'd like to confirm my understanding before I go on a crazy table spree!
 
Suppose a B17 calls up ammo, an ME109 and a Flak react to it, and there is a nearby B24 and FW190 that don't react (say the 190 already expended its reactions)

targetDRM = {} is a table of the unit that is actually being targeted by the reactive defense, correct? In other words, the unit that calls up ammo to start the reaction?

targetDRM[unitAliases.Flak.id]
Gives how the damage roll for flak attacking the B17 is modified. So, if the result is 3, then the flak is 1/3 as likely to do damage as default. The table can't vary this per 'victim' type (in this case the B17), but that functionality can be included if you want it.

areaReactDRM = {} is a table of the units that might be near the targeted unit (so "splash damage" where flak can damage a few B-17s for example when one calls up ammo. Correct?

areaReactDRM[unitAliases.Flak.id]
Gives how the damage roll against the ME109 is modified. (i.e. both the Flak and the ME109 are trying to attack the same B17, so the flak might hit the 109 by mistake) Clouds applies if the ME109 is in the clouds, not the B17.

areaBystanderDRM = {} is a table of friendly units that might be hit by friendly fire "splash damage"? Correct? I don't think we ever implemented this so I'd probably just leave this table blank.

areaBystanderDRM[unitAliases.Flak.id]
Gives how the damage roll against the B24 and FW190 is modified (these units are nearby, and so are at risk, but aren't in the direct line of fire). Clouds applies if the B24 or FW190 is in clouds. I didn't split this in such a way as to separate the effect for friendly bystanders and enemy bystanders, but that could be done if we really want to. The flak units do deal with this. I should have checked that we only have 3 flak units that do area damage, and so could handle these directly in a function without a table. Maybe you have a tech that increases accuracy agains the primary target, and as a consequence reduces the general risk to bystanders (or even other reacting units).

Then as I understand it you've provided me with a default standard:

Code:
dTM = {clouds = 1.5, cloudsTech1=nil, cloudsTech1Mod = 1, cloudsTech2=nil, cloudsTech2Mod=1, tech1=nil, tech1Mod=nil, tech2=nil, tech2Mod=1, enemyTech1=nil, enemyTech1Mod=1, enemyTech2=nil,enemyTech2Mod=1,counterToEnemyTech1=nil, counterToEnemyTech1Mod=1,counterToEnemyTech2 = nil, counterToEnemyTech2Mod=1,}
But, if I wanted to have, say, Lancasters take less damage in clouds then directly underneath the above, I'd write:

lancasterTM = {clouds = 3, cloudsTech1=nil, cloudsTech1Mod = 1, cloudsTech2=nil, cloudsTech2Mod=1, tech1=nil, tech1Mod=nil, tech2=nil, tech2Mod=1, enemyTech1=nil, enemyTech1Mod=1, enemyTech2=nil,enemyTech2Mod=1,counterToEnemyTech1=nil, counterToEnemyTech1Mod=1,counterToEnemyTech2 = nil, counterToEnemyTech2Mod=1,}

And then in the lancaster line in the table, I'd change to:

No, these are tables for the unit dealing the damage. So Flak can be good or bad at attacking units in clouds, but Lancasters can't be good or bad at evading fire while in a cloud. If you want that kind of functionality, I can do it, but the way it is set up depends on the reactingUnit (the one 'attacking' the munition generating unit), not the 'victim' (the munition generating unit, or some other nearby unit).

If targetDRM[unitAliases.lancaster.id]={clouds = 3 ...}
That means the lancaster is bad at damaging units calling up munitions from a cloud.

If you want that, then, given lancasterTM that you defined, you would put

targetDRM[unitAliases.lancaster.id]=lancasterTM

Or, just change clouds = 3 in the table I provided for the lancaster. In that case, it would rely on defaults for other entries.

Changing dTM.something (or dARTM or dABTM) changes the value for all units where something=dTM.something. If
targetDRM[unitAliases.lancaster.id]={something =12, somethingElse=dTM.somethingElse}, then 12 is used instead of dTM.something for the lancaster, but the lancaster still uses the dTM entry for somethingElse.

And then in the lancaster line in the table, I'd change to:


targetDRM[unitAliases.Lancaster.id]={clouds =lancasterTM.clouds, cloudsTech1=dTM.cloudsTech1, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=dTM.cloudsTech2, cloudsTech2Mod=dTM.cloudsTech2Mod, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}

This is correct. You can have clouds=lancasterTM.clouds, but there really wasn't much point to writing the entire lancasterTM table.

You might have nightBomberTM = {clouds=3,...}, and then for the lancaster set clouds=nightBomberTM.clouds, so the lancaster uses the night bomber default for some things, and the regular default for others.

I didn't provide too much functionality here. Basically, units become better or worse at shooting depending on whether the unit they're shooting is in the clouds or not, and on the availability of certain technology. If you want other functionality (like having some units become more 'invisible' than other units in clouds) or to check something other than technologies, please say so, and I'll make the change before you spend time doing the tables.

Also, if you want the tables pre filled in some way, let me know, since I might be able to do it quickly (as I mentioned before, I changed text editors to Vim, which can do some automation). Unfortunately, I'm not familiar enough with the WWII airplanes to know what are the diffrent kinds (especially on the German side), so I can't easily differentiate fighters/bombers/bomber destroyers from their name.
 
No, I'm fine with the functionality you wrote I just wanted to make sure I understood it.

I'm thinking there are pretty much three categories I'll need to build out:

-Flak guns
-Aircraft with on-board radar (maybe even tier this I and II with the last night fighter being best)
-All other aircraft

The first two can get bonuses with technology to reacting in clouds, the last will always have a disadvantage.
 
@Prof. Garfield I don't know if you'll see this or not but one more question:

cloudsTech1=nil,

is the nil to be replaced by a value in technologyAliases={} ?

So right now the tables have no technologies assigned that actually modify something, they're just waiting to be filled in?
 
I'm not positive this is working. I tried a really large value after clouds (4) to see if it would prevent the bomber from being attacked however the bomber still takes 5 hit points of damage. Perhaps I'm missing something or placing it in the wrong area?

targetDRM[unitAliases.GermanFlak.id]={clouds =4, cloudsTech1=techAliases.ProximityFuses, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=techAliases.AdvancedRadarIII, cloudsTech2Mod=.5, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}
 
@Prof. Garfield I don't know if you'll see this or not but one more question:

cloudsTech1=nil,

is the nil to be replaced by a value in technologyAliases={} ?

So right now the tables have no technologies assigned that actually modify something, they're just waiting to be filled in?

That's correct. You can leave it at nil if you don't need it.

I don't believe that we actually made a technologyAliases table, however.

I'm not positive this is working. I tried a really large value after clouds (4) to see if it would prevent the bomber from being attacked however the bomber still takes 5 hit points of damage. Perhaps I'm missing something or placing it in the wrong area?

targetDRM[unitAliases.GermanFlak.id]={clouds =4, cloudsTech1=techAliases.ProximityFuses, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=techAliases.AdvancedRadarIII, cloudsTech2Mod=.5, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}

There is still a chance to receive any amount of damage. Consider this damage schedule
ds.P47D11interceptionBomb1 = {{.9, 3},{.7,5},{.3,7}}

Ordinarily, we 'roll' a number between 0 and 1. If the number is less than an entry in the damage schedule, add the corresponding damage to the enemy.

The modifier changes the 'roll'. If the modifier is 4, then the number generated is between 0 and 4, so all the values are 1/4 of what they were before.

Original:
roll 0-.3 15 damage
roll 0.3-0.7 8 damage
roll 0.7-0.9 3 damage
roll 0.9-1 0 damage

If 'roll' multiplied by 4
roll 0-0.075 --> modified roll 0-0.3 --> 15 damage
roll 0.075-0.175 --> modified roll 0.3-0.7 --> 8 damage
roll 0.175-0.225 --> modified roll 0.7-0.9 --> 3 damage
roll 0.225-1 --> modified roll 0.9-4 --> 0 damage

Try it a couple times (and make sure to test with the bomber on clouds) and see that the percentages are lower than you would expect. Or put in a number like 100 or something, to make any hit very unlikely.

Remember, all the modifications are multiplied together to produce the end result.

EDIT: A quick test using clouds=200 allowed a spitfire to escape unharmed from 7 ME109G6 twice. So, I think it is working.
 
OK that makes sense. We didn't to a technologyAliases table but we did do a techAliases table

Anyway, here is what I came up with (just for clouds so far) - clouds normally grant a 50% detriment to flak abilities per the 1.5 in your default table. Researching proximity fuses removes this (value = 1). Researching Advanced Radar III makes flak 50% more likely to hit (value = .5). I believe that this is accurate if I'm following everything.

targetDRM[unitAliases.GermanFlak.id]={clouds =dTM.clouds, cloudsTech1=techAliases.ProximityFuses, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=techAliases.AdvancedRadarIII, cloudsTech2Mod=.5, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}
targetDRM[unitAliases.AlliedFlak.id]={clouds =dTM.clouds, cloudsTech1=techAliases.ProximityFuses, cloudsTech1Mod =dTM.cloudsTech1Mod, cloudsTech2=techAliases.AdvancedRadarIII, cloudsTech2Mod=.5, tech1=dTM.tech1, tech1Mod=dTM.tech1Mod, tech2=dTM.tech2, tech2Mod=dTM.tech2Mod, enemyTech1=dTM.enemyTech1, enemyTech1Mod=dTM.enemyTech1Mod, enemyTech2=dTM.enemyTech2,enemyTech2Mod=dTM.enemyTech2Mod,counterToEnemyTech1=dTM.counterToEnemyTech1, counterToEnemyTech1Mod=dTM.counterToEnemyTech1Mod, counterToEnemyTech2Mod=dTM.counterToEnemyTech2Mod,}
 
I forgot about the techAliases. I recently did some stuff where I used the number of the tech, rather than putting the tech into the techAliases table. Since we don't plan on changing the technologies around, it doesn't really matter.

Anyway, here is what I came up with (just for clouds so far) - clouds normally grant a 50% detriment to flak abilities per the 1.5 in your default table. Researching proximity fuses removes this (value = 1). Researching Advanced Radar III makes flak 50% more likely to hit (value = .5). I believe that this is accurate if I'm following everything.

Every applied value is multiplied together. So, if proximity fuses completely eliminates the cloud bonus, the value should be 1/1.5 == 2/3, (or use a variable cloudChange and 1/cloudChange, so you can change both in one place).

1.5 means the flak is about 2/3 as likely to score a hit as before. Not sure if that is what you meant by a 50% detriment to flak ability, so I thought I'd mention it, just in case. (It is kind of like a 50% bonus to 'evasion' for the aircraft in clouds). Similarly, value=.5 doubles the chance of a hit.

Take 1/value to get the new chance of a hit in terms of the old. Now that I put it this way, it looks like I should have done it so that value was the new chance of a hit relative to the old. I can make the change if you would find it easier.

Your tables look correct, though perhaps if you're using defaults for aircraft, you might want to change dTM.something to nil, so that bonuses/penalties meant for aircraft aren't applied to flak. For example, the 'tactics' technologies might make for good tech/enemyTech/counterTech for most planes, but probably not for flak.
 
Back
Top Bottom