miniMAXIme: Character scaler and selector

by Pi-C

The player stands like a giant near the vehicles. Now you can adjust the size of your character -- and you can change your appearance at any time if you've other mods that provide extra characters!

Tweaks
11 days ago
0.16 - 2.0
26.4K

b [Partly implemented] Character duplication when loading SE game while in Nav-view

1 year, 9 months ago
(updated 1 year, 9 months ago)

Hi—we had a bug report in the SE Discord about the player's character sometimes being duplicated when the game is loaded after mod updates. The bug only manifests when this mod is active, and then only if the player had saved their game while in "Nav-view". [Nav view is an SE mode that uses the god-controller without an attached character.]

To reproduce the issue:
1. Start a test world with just Space Exploration + its dependencies as well as miniMAXIme.
2. Enable cheat mode.
3. Type the following command in the console: /se-launch-satellite 4
4. Press "N" to activate Nav-view.
5. Move your camera a bit just so that you're not centered on the (previously attached) character.
6. Save your game while in Nav view.
7. Enable any other unrelated mod, so that on_configuration_changed is triggered on game load.
8. Load the savefile you made earlier.
9. The player will have a character attached even though they're not supposed to. Some of their previous inventory items will also be on the ground—I'm not exactly sure where those are coming from.

If this is something you're interested in addressing, then it's worth pointing out that SE has a remote interface function that you'd probably find useful. The function is called remote_view_is_active. It just takes a player argument—sample usage: remote.call("space-exploration", "remote_view_is_active", {player=game.player}). It returns true if the given player is in remote view.

1 year, 9 months ago
(updated 1 year, 9 months ago)

Hi! Thank you for the report.

To reproduce the issue:
1. Start a test world with just Space Exploration + its dependencies as well as miniMAXIme.
2. Enable cheat mode.
3. Type the following command in the console: /se-launch-satellite 4
4. Press "N" to activate Nav-view.
5. Move your camera a bit just so that you're not centered on the (previously attached) character.
6. Save your game while in Nav view.
7. Enable any other unrelated mod, so that on_configuration_changed is triggered on game load.
8. Load the savefile you made earlier.

I'll try that.

  1. The player will have a character attached even though they're not supposed to. Some of their previous inventory items will also be on the ground—I'm not exactly sure where those are coming from.

Apparently I don't notice that the player is supposed to be in god mode. I'll have to look at the code again to see in response to what events I register changed controllers. If I remember correctly, this was split over 2 events … Anyway, when characters are changed, the mod backs up the inventories and properties from the old character, and tries to restore them when the new character is created. I could imagine that your old character had a bigger inventory than the new one, so when the new character on loading, the items that don't fit into the inventory are dropped on the ground. But I'll have to test that and check the log file.

If this is something you're interested in addressing, then it's worth pointing out that SE has a remote interface function that you'd probably find useful. The function is called remote_view_is_active. It just takes a player argument—sample usage: remote.call("space-exploration", "remote_view_is_active", {player=game.player}). It returns true if the given player is in remote view.

Thanks for the hint! This may be useful to check in on_configuration_changed. Do you know whether SE will raise an event (either for real or by checking all remote interfaces for a certain function) when a player toggles god mode? It would be better if I could react immediately to a mode change, not just on loading the game.

1 year, 9 months ago
(updated 1 year, 9 months ago)

Apparently I don't notice that the player is supposed to be in god mode. I'll have to look at the code again to see in response to what events I register changed controllers. If I remember correctly, this was split over 2 events … Anyway, when characters are changed, the mod backs up the inventories and properties from the old character, and tries to restore them when the new character is created. I could imagine that your old character had a bigger inventory than the new one, so when the new character on loading, the items that don't fit into the inventory are dropped on the ground. But I'll have to test that and check the log file.

I could see how that could get complicated. Will be curious to know your findings either way!

Thanks for the hint! This may be useful to check in on_configuration_changed. Do you know whether SE will raise an event (either for real or by checking all remote interfaces for a certain function) when a player toggles god mode? It would be better if I could react immediately to a mode change, not just on loading the game.

SE does not currently raise any events (using either technique) on toggling nav-view. I'm thinking you could potentially get away with ignoring when such toggles actually happen, since all we really do is detach the character, leaving any character changes made by other mods intact. Do let me know if that's not the case though—I can bring it up with Earendel if there's a genuine use case for such an event.

Oh and one more remote interface you might find useful: remote.call("space-exploration", "get_player_character", {player = game.player}). This would allow you to get the character entity reference even when nav-view is active, if that's something you need.

1 year, 9 months ago
(updated 1 year, 9 months ago)

SE does not currently raise any events (using either technique) on toggling nav-view. I'm thinking you could potentially get away with ignoring when such toggles actually happen, since all we really do is detach the character, leaving any character changes made by other mods intact. Do let me know if that's not the case though—I can bring it up with Earendel if there's a genuine use case for such an event.

Actually, I've already a remote function that handles character swapping by "Jetpack" (according to the specs made by Earendel) and "Bob's Character classes". Bob's mod already calls it when one character is swapped for another and when a player enters/leaves god mode or editor mode. You can find it in scripts/remote_interface.lua, starting at line 190:

-- Jetpack expects this function on other mods' remote interfaces. We can use that
-- for other mods as well.
--
-- Event data used by Jetpack:
-- {new_unit_number = uint, old_unit_number = uint,
--  new_character = LuaEntity, old_character = LuaEntity}
--
-- Additional (optional) event data used by Bob's classes:
-- player_index = uint,
-- editor_mode = boolean, god_mode = boolean
interface_functions.on_character_swapped = function(event)

It should be called with

 remote.call("minime", "on_character_swapped", args)

where "args" is a table with the data shown above.

I think the problem would be solved if you could convince Earendel to call that function before entering/leaving god mode. I'd do that myself, but I'm not on Discord and while we already did communicate via PM on the forum, it may take weeks or months before he replies there. :-)

Oh and one more remote interface you might find useful: remote.call("space-exploration", "get_player_character", {player = game.player}). This would allow you to get the character entity reference even when nav-view is active, if that's something you need.

Thanks, I'll look into it.

1 year, 9 months ago
(updated 1 year, 9 months ago)

SE does not currently raise any events (using either technique) on toggling nav-view. I'm thinking you could potentially get away with ignoring when such toggles actually happen, since all we really do is detach the character, leaving any character changes made by other mods intact. Do let me know if that's not the case though—I can bring it up with Earendel if there's a genuine use case for such an event.

Oh and one more remote interface you might find useful: remote.call("space-exploration", "get_player_character", {player = game.player}). This would allow you to get the character entity reference even when nav-view is active, if that's something you need.

OK, I've added a check to my init_player function. If the player has no character but remote_view_is_active returns true, I adjust the player's data so that from my mod's perspective the player is in legit god mode. However, that's not enough: If the player was in SE's remote view mode and uses my GUI to exit god mode, I must call the remote_view_stop function from SE's interface or SE will crash next time the player tries to close its GUI.

It's still necessary that SE informs my mod when a player enters or leaves the remote view mode. This is necessary so that the state of my GUI buttons is in sync with the actual player.controller_type. For example, if a player was in remote-view mode when saving the game, I'll put him in god mode when on_configuration_changed runs. If the player then closes SE's GUI, SE will attach the old character again, but the player will still be in god mode from my mod's perspective, and when the player uses my GUI to exit god mode by switching to another character, my mod will create the new character without removing the old one.

Also, if SE would tell me when a player's state is updated, I could cache the current state and wouldn't have to call SE's remote functions each time a player wants to use my GUI.

1 year, 9 months ago

Actually, I've already a remote function that handles character swapping by "Jetpack" (according to the specs made by Earendel) and "Bob's Character classes". Bob's mod already calls it when one character is swapped for another and when a player enters/leaves god mode or editor mode. You can find it in scripts/remote_interface.lua, starting at line 190:

I don't think on_character_swapped is the best choice here, since it's not strictly what's happening, even if another mod is using it that way. Right now I'm leaning towards triggering standard game events rather than calling remotes, but I'll discuss it with Earendel either way.

OK, I've added a check to my init_player function. If the player has no character but remote_view_is_active returns true, I adjust the player's data so that from my mod's perspective the player is in legit god mode. However, that's not enough: If the player was in SE's remote view mode and uses my GUI to exit god mode, I must call the remote_view_stop function from SE's interface or SE will crash next time the player tries to close its GUI.

Great. Will keep you posted on the event discussion.

1 year, 9 months ago

Actually, I've already a remote function that handles character swapping by "Jetpack" (according to the specs made by Earendel) and "Bob's Character classes". Bob's mod already calls it when one character is swapped for another and when a player enters/leaves god mode or editor mode. You can find it in scripts/remote_interface.lua, starting at line 190:

I don't think on_character_swapped is the best choice here, since it's not strictly what's happening, even if another mod is using it that way. Right now I'm leaning towards triggering standard game events rather than calling remotes, but I'll discuss it with Earendel either way.

I could make alias functions like "entered_godmode"/"left_godmode" that act like a wrapper and call the original function from there with either old or new character set to nil.

OK, I've added a check to my init_player function. If the player has no character but remote_view_is_active returns true, I adjust the player's data so that from my mod's perspective the player is in legit god mode. However, that's not enough: If the player was in SE's remote view mode and uses my GUI to exit god mode, I must call the remote_view_stop function from SE's interface or SE will crash next time the player tries to close its GUI.

Great. Will keep you posted on the event discussion.

Thanks! I've thought about a variation for handling editor mode: If remote view is on when the player wants to switch to editor mode, call remote_view_stop and set a flag; on leaving editor mode again, call remote_view_start if the flag is set. However, remote_view_start requires additional arguments which I don't know. If there was a way to get a player's current remote_view settings, I could apply those again. But I'm not sure whether that really makes sense. Perhaps it's sufficient to say that using the character selector GUI will always stop remote view.

Another thing we should consider: My mod has a setting that allows to toggle between "player follows character" and "character follows player" when leaving god or editor mode (i.e., either the player will be teleported to the surface+position of the character, or the character to the player surface+position). Should that setting also take effect when remote view is stopped?

1 year, 9 months ago
(updated 1 year, 9 months ago)

Earendel has okayed raising remote-view toggle events. Here's how the provisional implementation works. Note that it uses standard game events, and you can get the event ids using the remote interface functions listed below.

  • remote.call("space-exploration", "get_on_remote_view_started"): Triggered when remote view is started, right before the controller is changed to god-mode. This includes the player accessing the star/interstellar maps. Is not triggered if the player is already in remote-view and is simply switching to a different zone. Provides player_index to the caller.
  • remote.call("space-exploration", "get_on_remote_view_stopped"): Triggered when remote view is stopped, after the controller has been changed from god-mode. Provides player_index to the caller.

The specific timing of each event is such that the likelihood of the character being attached to the player is maximized. It is however not guaranteed, since the player may activate remote-view while they're anchoring a spaceship or aboard a launching cargo rocket/space capsule, both of which use the ghost-controller. Similarly for the remote-view-stopped event, the player will usually have their character attached, but it is not guaranteed.

Thanks! I've thought about a variation for handling editor mode: If remote view is on when the player wants to switch to editor mode, call remote_view_stop and set a flag; on leaving editor mode again, call remote_view_start if the flag is set. However, remote_view_start requires additional arguments which I don't know. If there was a way to get a player's current remote_view settings, I could apply those again. But I'm not sure whether that really makes sense.

SE already disallows activating the editor while in remote-view as well as activating remote-view while in the editor, since mixing the two ends up being a mess. I'm not sure if any special handling is necessary on your end, but if you want to open editor using your mod, force-stopping remote view is perfectly fine. You need not bother with reactivating remote-view afterwards.

Perhaps it's sufficient to say that using the character selector GUI will always stop remote view.

That sounds reasonable.

Another thing we should consider: My mod has a setting that allows to toggle between "player follows character" and "character follows player" when leaving god or editor mode (i.e., either the player will be teleported to the surface+position of the character, or the character to the player surface+position). Should that setting also take effect when remote view is stopped?

I'm inclined to say it shouldn't, since the purpose of remote-view is quite different from editor or proper god-mode, but that's ultimately up to you.

1 year, 9 months ago

Earendel has okayed raising remote-view toggle events. Here's how the provisional implementation works. Note that it uses standard game events, and you can get the event ids using the remote interface functions listed below.

That's great news! For now, I'll check that my GUI is in sync with SE's remote view state whenever I catch a GUI click. I've already prepared handlers for the new custom events, but of course I couldn't test them yet.

SE already disallows activating the editor while in remote-view as well as activating remote-view while in the editor, since mixing the two ends up being a mess. I'm not sure if any special handling is necessary on your end, but if you want to open editor using your mod, force-stopping remote view is perfectly fine. You need not bother with reactivating remote-view afterwards.

Perhaps it's sufficient to say that using the character selector GUI will always stop remote view.

That sounds reasonable.

So the easy way it is then: I'll just stop remove view if necessary, without trying to restore it.

Another thing we should consider: My mod has a setting that allows to toggle between "player follows character" and "character follows player" when leaving god or editor mode (i.e., either the player will be teleported to the surface+position of the character, or the character to the player surface+position). Should that setting also take effect when remote view is stopped?

I'm inclined to say it shouldn't, since the purpose of remote-view is quite different from editor or proper god-mode, but that's ultimately up to you.

When returning from remote view, the player will now always be moved back to the surface and position of the detached character, no matter what that setting says.

Could you try out version 1.1.20 and make sure that things work as you'd expect them to?

1 year, 9 months ago

I briefly tested v1.1.20 with the branch containing the new events and it works fine as far as I can tell. Most importantly, I couldn't make it crash, so I think it should be good :)

1 year, 9 months ago

Thanks! So I'll leave this alone until Earendel releases an update where the new custom events are used. (The continuous remote calls to SE make my fix rather expensive, so I consider this just a compromise.)

1 year, 9 months ago

Earendel has okayed raising remote-view toggle events. Here's how the provisional implementation works. Note that it uses standard game events, and you can get the event ids using the remote interface functions listed below.

  • remote.call("space-exploration", "get_on_remote_view_started")
  • remote.call("space-exploration", "get_on_remote_view_stopped")

For the benefit of anybody else reading this thread: The function names are not quite correct. This will work:

  • remote.call("space-exploration", "get_on_remote_view_started_event")
  • remote.call("space-exploration", "get_on_remote_view_stopped_event")
1 year, 9 months ago

Ah, good point. Sorry, I think I changed the function names for consistency after I had written that blurb and forgot to change it there.

1 year, 9 months ago

No problem. This way, the event handlers I prepared were not exposed to the public yet, which gives me a chance to fix bugs before they do any real damage. :-D

1 year, 8 months ago

It seems that the events have been added to SE now.

1 year, 8 months ago

It seems that the events have been added to SE now.

Thanks that's correct! I've already removed my temporary code in version 1.1.21. However, I'll keep the "Partly implemented" tag for now because there still is an unresolved issue (I've sent InappropriatePenguin a PM on the forums about this).

1 year, 8 months ago

(FYI, I tried yesterday and it still duped my items whenever I went into satellite mode, and I'm not sure if that's the expected behavior currently, bc I am not familiar with the technical context of the latest changes. But I thought you should know, at least, just in case it's unexpected.)

1 year, 8 months ago

FYI, I tried yesterday and it still duped my items whenever I went into satellite mode

Please excuse my ignorance, but is that really the same thing? You're talking about "satellite mode", the thing I've tried to fix was "Nav view". Are these just different names for the same mode, or are there some real differences (e.g. player.controller_type is ghost or spectator instead of god)?

It would help immensely if you could provide a saved game with detailed instructions how to reproduce the bug. By the way, with "detailed" I mean just that: I've never played with SE, so I wouldn't know what to do if you said "Enter satellite mode", but I could follow "Press X to enter satellite mode". :-)

1 year, 8 months ago

Sorry, yeah, nav view. It's the exact same steps as OP, though I'd add that you should wear something that increases your max inventory size, fill your inventory, and then go into nav view; I believe it somehow has to do with the inventory size difference when you're you vs when you're a satellite (i.e. when you're in nav view).

1 year, 8 months ago

… you should wear something that increases your max inventory size, fill your inventory, and then go into nav view; I believe it somehow has to do with the inventory size difference when you're you vs when you're a satellite (i.e. when you're in nav view).

This is really strange! SE will raise on_remote_view_stopped after it has put the player from god mode into character mod and re-attached the character + restored the inventory. After that, miniMAXIme will copy the inventories from the player's dummy to the real character, using LuaItemStack.set_stack() if LuaItemStack.can_set_stack() succeeds. I would understand if items were spilled on the ground if I'd try to insert the stored items into a full inventory, but checking for can_set_stack() should prevent this. Also, I don't understand why the items are only spilled if the player is wearing an armor that gives a bonus to inventory_size.

Anyway, replacing line 1658 in scripts/character.lua:

minime_character.copy_character(p_data.dummy, char)

with

copy_properties(p_data.dummy, char)

should prevent the duplicated items even though I don't understand why. :-)

1 year, 8 months ago

Version 1.1.23 should fix this -- does it?

1 year, 8 months ago

I'll go check. Haven't got it yet.

1 year, 8 months ago

It does! Thank you.

1 year, 8 months ago

Wait… oh no…

1855.502 Error MainLoop.cpp:1288: Exception at tick 64894229: The mod miniMAXIme: Character scaler and selector (1.1.23) caused a non-recoverable error.
Please report this error to the mod author.

Error while running event minime::Custom event (ID 379)
Given entity doesn't exist anymore.
stack traceback:
    [C]: in function '__newindex'
    __minime__/scripts/character.lua:51: in function 'copy_properties'
    __minime__/scripts/character.lua:1678: in function 'event_handler'
    __minime__/scripts/events.lua:252: in function <__minime__/scripts/events.lua:249>
stack traceback:
    [C]: in function 'raise_event'
    __space-exploration__/scripts/remote-view.lua:385: in function 'stop'
    __space-exploration__/scripts/remote-view.lua:704: in function 'toggle'
    __space-exploration__/scripts/remote-view.lua:770: in function 'callback'
    __space-exploration__/scripts/event.lua:15: in function <__space-exploration__/scripts/event.lua:13>

Crash happened trying to transition out of nav view into normal mode. I'm not sure what other circumstances would have contributed. Here's the full log, but it's no more useful.

1 year, 8 months ago

Actually, something so much more cursed has popped up. For some reason, now and again, my cursor will start spawning dropped items whenever I'm in nav mode and mousing over a building. In my case, it was spawning tons of dropped UV lights from the Will 'o the Wisps mod, which is an item I previously made a deconstruction planner for, but I wasn't using it at the time the glitch happened I don't think. The glitch persists between saving and reloading.

I tried to attach a log, but apparently my log is… this. Emacs displays the log correctly, but doesn't let me copy and paste it. I dunno, here's the file itself. But by all accounts the file is difficult to load or interpret.

1 year, 8 months ago

Thanks for the report, looking into this.

I tried to attach a log, but apparently my log is… this. Emacs displays the log correctly, but doesn't let me copy and paste it. I dunno, here's the file itself. But by all accounts the file is difficult to load or interpret.

The log is pretty useless, as debugging output isn't enabled. Unfortunately, I've noticed that the settings for logging don't take effect (already fixed that for the next version). Could you unpack the mod and change line 28 of the file libs/debugging.lua?

-- Old line:
debugging.is_debug = debugging.debug_in_log

-- New line:
debugging.is_debug = true

After this change, restart the game, let it crash, and post factorio-current.log (you could send it to me in a private message on the forum). Depending on how many mods you are using, the log file may get quite huge, so you may want to zip it. It would be even better if you could upload a saved game that I can use to sync with and reproduce the crash.

1 year, 8 months ago
(updated 1 year, 8 months ago)

I can't reproduce the bug at will other than loading that one save, so here's the save that broke and produced the cursed log. You should be able to reproduce it by just going into nav mode and mousing over any object. Apologies for the insane amount of mods. The only really important one besides yours and SE, I think, is Will o' the Wisps, as that's the mod that the item being produced is from.

edit: Now that I've uninstalled miniMAXIme to get rid of the bug, what's additionally weird is that it was apparently the mod responsible for doubling my build radius (rough estimate of effect size but for all I know it's exact). That only happened with specifically the latest update.

1 year, 8 months ago

I can't reproduce the bug at will other than loading that one save, so here's the save that broke and produced the cursed log.

Sorry, I can't download that file without a Google account. :-(

edit: Now that I've uninstalled miniMAXIme to get rid of the bug, what's additionally weird is that it was apparently the mod responsible for doubling my build radius (rough estimate of effect size but for all I know it's exact). That only happened with specifically the latest update.

Strange …

1 year, 8 months ago
(updated 1 year, 8 months ago)

Ah, I apologize. I've now set the permissions on the link so that anyone with the link should be able to download it.

1 year, 8 months ago

Thanks, I've downloaded the save!

1 year, 8 months ago

Wait… oh no…

```
1855.502 Error MainLoop.cpp:1288: Exception at tick 64894229: The mod miniMAXIme: Character scaler and selector (1.1.23) caused a non-recoverable error.
Please report this error to the mod author.

Error while running event minime::Custom event (ID 379)
Given entity doesn't exist anymore.
stack traceback:
[C]: in function 'newindex'
__minime
/scripts/character.lua:51: in function 'copy_properties'
Crash happened trying to transition out of nav view into normal mode. I'm not sure what other circumstances would have contributed.

The crash happened when trying to copy the GUI opened by the player. Apparently you had opened the GUI of some entity when you turned on nav-view. By the time you returned to left nav-view, that entity had already been mined or destroyed, so trying to access its GUI would crash the game.

1 year, 7 months ago

Oh, I see. Interesting. I'll tell the SE folk.

1 year, 7 months ago

I'll tell the SE folk.

That's not necessary: I now check whether an entity still is valid before opening its GUI, so that bug is fixed. Please try version 1.1.24!

For some reason, now and again, my cursor will start spawning dropped items whenever I'm in nav mode and mousing over a building.

So far, I couldn't reproduce this.

Now that I've uninstalled miniMAXIme to get rid of the bug, what's additionally weird is that it was apparently the mod responsible for doubling my build radius (rough estimate of effect size but for all I know it's exact). That only happened with specifically the latest update.

I've looked at the changes between 1.1.22 and 1.1.23, there's really nothing that affects build_distance. Actually, I only touch character_build_distance_bonus in the control stage. I guess if that was changed before you remove the mod, this property will persist. But I've noticed that

/c game.print(game.player.build_distance)

will show different results for the default character and Gear Girl. The prototype history (use CTRL+SHIFT+E) also shows that both characters have been modified by several mods. I suppose you were using the default character when miniMAXIme was active, which has a build_distance of 40 (probably increased by some mod from 10 to 40). When you removed my mod, Gear Girl would overwrite the default character. As its build_distance is just 10 (the default value, so the other mod probably ignored it), you end up with the vanilla build_distance without miniMAXIme.

New response