Deleting the active unit: Move Pieces mode vs. View Pieces mode

Knighttime

Prince
Joined
Sep 20, 2002
Messages
379
I'm frustrated by a gameplay issue resulting from Lua events, and wondering if someone out there knows a better way to handle this.

I have some code that is called when a unit is activated -- meaning, it is run from the onActivateUnit() trigger -- which evaluates the newly-activated unit and, in some conditions, determines that it should actually be deleted immediately, rather than be allowed to have its turn and take any action. But when I do this, using civ.deleteUnit(), the game seems to flip from "Move Pieces" mode into "View Pieces" mode so that no unit is really active at all, until I press "v".

Furthermore this situation can happen to multiple units in a row, so it leads to a lot of "v" being pressed until I end up with a unit that is actually allowed to take its turn -- enough that it gets annoying.

I experimented with finding the next unit that I want to activate, rather than relying on the game to determine this, and calling nextUnit:activate() first, before I call civ.deleteUnit(). But that doesn't seem to make any difference -- I'm still stuck in the wrong mode and have to press "v" to actually make nextUnit activate and ready to move.

I'm not aware of any TOTPP function that can switch the UI mode programmatically either.

My "last resort" solution would be to call nextUnit:activate(), but not call civ.deleteUnit() at that time, and instead populate a table or variable with the ID of the unit to be deleted. Then within onActivateUnit(), I could add code to see if that table or variable contains any IDs, and if so, delete the unit(s) at that point -- in other words, never deleting a unit while within the onActivateUnit() trigger for that unit, but always waiting until I'm within that trigger for another unit. This seems like such a hackish workaround that I thought I would post the problem here first, before I try going down that road.

Can anyone point me to a scenario or bit of code that provides a way to delete the active unit and immediately and seamlessly activate another one, without the mode toggle problem?
 
My first recommendation would be to rethink your mechanic. Can you maybe check at the start of the player's turn rather than when a unit is activated? If you can't, then that would suggest that whether the unit is to be deleted or not depends on how the player plays his turn, which might be imposing a large micromanagement burden, if moving units in the wrong order could cause some of them to be deleted. You can always have an on activation check as a backstop just in case.

We do 'after production' events in Over the Reich. The template I uploaded in this thread https://forums.civfanatics.com/threads/build-restrictions-module-preview.653711/ also has afterProduction (though that isn't the focus of the thread).

After production is a onActivateUnit event. Basically, have a flag in state for each tribe, when a unit is activated, check the flag. If 'after production' hasn't been done, then do it, otherwise ignore the code.

In my General Library, I have code for 'smart' choosing of the next active unit (all other units are given the wait command). You could modify that code to delete the unit that would be the next active unit.

I experimented with finding the next unit that I want to activate, rather than relying on the game to determine this, and calling nextUnit:activate() first, before I call civ.deleteUnit(). But that doesn't seem to make any difference -- I'm still stuck in the wrong mode and have to press "v" to actually make nextUnit activate and ready to move.

Have you tried putting in a civ.sleep command? This can sometimes give the game a chance to 'catch up' (I think I did it for a key press command, to check what the new home city is after pressing 'h').

My "last resort" solution would be to call nextUnit:activate(), but not call civ.deleteUnit() at that time, and instead populate a table or variable with the ID of the unit to be deleted. Then within onActivateUnit(), I could add code to see if that table or variable contains any IDs, and if so, delete the unit(s) at that point -- in other words, never deleting a unit while within the onActivateUnit() trigger for that unit, but always waiting until I'm within that trigger for another unit. This seems like such a hackish workaround that I thought I would post the problem here first, before I try going down that road.

I've done this sort of thing in Over the Reich, mostly to compensate for the fact that the city founded trigger happens before you choose to build the city or not, so stuff sometimes has to be deleted or put to the previous state.

Remember, nextUnit:activate() doesn't run the unit activation trigger automatically -- you have to tell the game to run the code. This might thwart (or make more difficult) your plans in this context.
 
Thanks for your reply.

We do 'after production' events in Over the Reich. The template I uploaded in this thread https://forums.civfanatics.com/threads/build-restrictions-module-preview.653711/ also has afterProduction (though that isn't the focus of the thread).

After production is a onActivateUnit event. Basically, have a flag in state for each tribe, when a unit is activated, check the flag. If 'after production' hasn't been done, then do it, otherwise ignore the code.
I wasn't aware that you had built something like this for OTR... I actually worked out a pretty similar system on my own to do the same thing.

In my General Library, I have code for 'smart' choosing of the next active unit (all other units are given the wait command). You could modify that code to delete the unit that would be the next active unit.
I didn't realize this was part of the latest General Library used in OTR, either... thanks for letting me know about it. This is kind of the flip side of my "last resort" solution -- instead of deleting the previously activated unit, delete the upcoming one. That's an interesting idea, and perhaps more seamless than what I was considering, although it also could be more complex to implement well. I'll take a look though.

I'm sure there are plenty of goodies in all of the OTR Lua code you've written, but I honestly haven't tried to absorb all of it because it seems to be changing so frequently yet -- I just can't keep up! I've been looking forward to more of an official final release and waiting until then to really spend time with the code.

Have you tried putting in a civ.sleep command? This can sometimes give the game a chance to 'catch up' (I think I did it for a key press command, to check what the new home city is after pressing 'h').
This was a good idea, but unfortunately it didn't help. I tried using civ.sleep() as you suggested, and then also tried a "non-civ" approach I found here (the first idea, labeled "busy wait"). In both cases the mode problem was the same.

My first recommendation would be to rethink your mechanic. Can you maybe check at the start of the player's turn rather than when a unit is activated? If you can't, then that would suggest that whether the unit is to be deleted or not depends on how the player plays his turn, which might be imposing a large micromanagement burden, if moving units in the wrong order could cause some of them to be deleted. You can always have an on activation check as a backstop just in case.
...
I've done this sort of thing in Over the Reich, mostly to compensate for the fact that the city founded trigger happens before you choose to build the city or not, so stuff sometimes has to be deleted or put to the previous state.
...
Remember, nextUnit:activate() doesn't run the unit activation trigger automatically -- you have to tell the game to run the code. This might thwart (or make more difficult) your plans in this context.
Yep, I too have had to compensate for the timing of the city founded trigger. And I did look at OTR to see how you handled that issue with :activate(), which was helpful, thank you. I was also trying to compensate for the fact that the activation trigger doesn't fire for units that are activated from within the city screen. All of the compensations and workarounds like this were a big part of the reason why I designed the mechanics and flow of each turn the way I did. So far the micromanagement issue isn't a major concern, but I'll admit I haven't tried to test with the quantity of units that you have in OTR. I'm sure there are other valid approaches out there to reach my goals, but I'm a little hesitant to make a major paradigm shift at this point since really it's mostly working well.

Thanks again for your suggestions, and I really do look forward to spending more time with the OTR code eventually!
 
Last edited:
Well, the OTR code is a poorly organized mess, mixed with a healthy dose of 'if I just put in one more feature, I'll be done.' I wouldn't advise perusing the code unless you already know what you're looking for (and even then, it may not be advisable), and certainly wouldn't fault anyone for not knowing what's in there. I intend to re-implement most of the interesting features at some point (I plan to do reactions very soon (within weeks)).

The General Library is meant to be of general use, and isn't meant to be specific OTR stuff (though, I do think that OTR is where you're likely to find the most recent copy at the moment, or you can look at the General library I included with my canBuild preview, which should also be current).

I totally understand not wanting to change a system that you've got working. Unfortunately, the best I can suggest is your last resort solution, if you don't want to delete the units ahead of time. Maybe what you could do is, if you find you have to delete the active unit, then check all the units in the game for others to be deleted. You might get put into view mode once, but you shouldn't have the very annoying situation of having several units in a row deleted, since they'll all get deleted before you have a chance to select them.
 
Well, the OTR code is a poorly organized mess, mixed with a healthy dose of 'if I just put in one more feature, I'll be done.' I wouldn't advise perusing the code unless you already know what you're looking for (and even then, it may not be advisable), and certainly wouldn't fault anyone for not knowing what's in there. I intend to re-implement most of the interesting features at some point (I plan to do reactions very soon (within weeks)).
I understand (and can appreciate) that you wrote it "to get the job done" and not with the idea of it being analyzed and borrowed from in its current form. I'm not intending to copy from it directly, mostly I'm just curious if you've found solutions to some of the same problems that I've encountered, which might give me new ideas -- or reveal additional "gotchas" in the game engine that I hadn't even noticed yet.

The General Library is meant to be of general use, and isn't meant to be specific OTR stuff (though, I do think that OTR is where you're likely to find the most recent copy at the moment, or you can look at the General library I included with my canBuild preview, which should also be current).
I had an older version of it from 2019-07-20... I think I missed your post in the General Library thread that the current version was going to be on GitHub going forward. I recently downloaded OTR from GitHub, though, and then updated it with JPetroski's files posted to the OTR creation thread on 2019-12-18, and this conversation made me realize you'd added things into the General Library which I hadn't seen before.

I totally understand not wanting to change a system that you've got working. Unfortunately, the best I can suggest is your last resort solution, if you don't want to delete the units ahead of time. Maybe what you could do is, if you find you have to delete the active unit, then check all the units in the game for others to be deleted. You might get put into view mode once, but you shouldn't have the very annoying situation of having several units in a row deleted, since they'll all get deleted before you have a chance to select them.
OK, I guess I'll try my last resort solution and see what issues that leads me into next. :hammer2: There's always "one more thing and I'll be done" as you said!
 
Last edited:
Well, the OTR code is a poorly organized mess, mixed with a healthy dose of 'if I just put in one more feature, I'll be done.'

We "may" have had a "bit" of "kid in the candy shop with wealthy grandma who has never heard of cavities" syndrome going on, yes :D
 
Top Bottom