Skip to content
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions programs/utilities/keepalive.sc
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
// re-logs fake players upon server restart
// must need to place it directly in the world scripts folder

__config() -> {'scope' -> 'global'};
global_cached_players = {};

__config() -> {
requires -> {
'minecraft' -> '>=1.8', // spectator was not a thing prior to 1.8
},
'scope' -> 'global'
};

__on_connect(e) -> (
// forcing the fake-players that were spawned in spectator back into creative to retain flight per their data
if(e:'gm' == 'creative' && e:'fly' == 1,
// scheduling the modification at the end to ensure the entity was created properly and resetting it back to the intended gamemode
schedule(0, _(e) -> (modify(player(e:'name'), 'flying', e:'fly')), e);
);
);

__on_player_connects(player) -> (
player_name = player()~'name';

if (has(global_cached_players, player_name),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After checking this, i would suggest removing the entry from the map too. After all the player might be spawned multiple times in different gamemodes manually later.
For example:

  • /player test spawn in creative (Spawn flying player in the air)
  • Reopen server, script spawns player back in creative and correctly sets flying to true
  • /player test kill
  • /player test spawn in survival
    Now you got a flying player in survival, since it still saved that test should be flying

Copy link
Author

@VoidedBlades VoidedBlades Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than removing the map i reckon it may be better to clear the key from the map on __on_player_disconnects?
this would support utilizing the map for any future usages where needed alongside removing the obstructions mentioned.

Ive tried moving the task into __on_server_starts as well as a hopeful functioning alternative but alas. it has to be through __on_player_connects of sorts

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would work too, though i don't see any use for that currently.

Do you have any more details on why modify is not working if you use a task? Is the player not available?

Copy link
Author

@VoidedBlades VoidedBlades Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the player is not available during __on_server_starts but afterwards during the __on_player_connects it is obviously, no errors seem to happen even removing the task inside of __on_player_connects however when entering the server the actual modification hasnt happened without said task and the player is on the ground but in creative.

im assuming this is due to some sort of race condition between a form of post initialization of the player and the value modified, in this case the flying.

its an incredibly peculiar situation nontheless.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, you are still using the schedule(0, _(e) -> (modify(player(e:'name'), 'flying', e:'fly')), e); right?
It's true that the flying state of the player is set after the player_connects event is fired, which would overwrite that if modify was used directly in the event. Scheduling to the end of the tick should fix that though.
As far as i can tell, there is no asynchronous initialization of the player, it all happens right after.

Copy link
Author

@VoidedBlades VoidedBlades Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ive pushed a new update, its still using schedule and at the time was too to modify it so everything should be fine now i reckon? do let me know if anything else needs adjusting!

task('__on_connect', global_cached_players:player_name)
Copy link
Collaborator

@replaceitem replaceitem Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see a reason to use task - theres no expensive conputation or sleep inside. It schedules immediately anyway. In that case you could also just move the contents of __on_connect into the player_connects event directly.
In fact if using the modify(e, 'flying' approach (which i prefer), using a task here could lead to some delay before setting the flying, during which the player could be ticked, causing the player to drop down a bit.

I would consider removing the task for __spawn_players in __on_server_starts too. This seems to have been a fix for this script previously (#410) seemingly not working for everyone. Since this should now be fixed fully by waiting for the player to be spawned with the event, it should be fine to remove.

Copy link
Author

@VoidedBlades VoidedBlades Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quite curious thing is happening if i remove the task directed towards __on_connect and put the contents directly into the function. It seems that modify doesn't actually function accordingly in this instance. you are right in that we can remove __spawn_players' task however this specific task in __on_player_connects seems to be required to stay unless we have any other viable options for replacement.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my attempts, replacing task('__on_connect', global_cached_players:player_name); with __on_connect(global_cached_players:player_name); worked fine. As long as there is still the schedule(0,...) in there, it will run the modify on the main thread (end of tick, after the player fully connected) anyway.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, last time i checked i removed __on_connect to move the code directly into __on_player_connects which didnt function, it did just now when i checked

)
);

__spawn_players() -> (
data = load_app_data();
if (data && data:'players',
data = parse_nbt(data:'players');
for (data,
for([str('player %s spawn at %f %f %f facing %f %f in %s',
_:'name', _:'x', _:'y', _:'z', _:'yaw', _:'pitch', _:'dim'),
str('gamemode %s %s', _:'gm', _:'name')],
logger('warn', _);
run(_);
);
modify(player(_:'name'), 'flying', _:'fly')
)
data = parse_nbt(data:'players');

for (data,
global_cached_players:str(_:'name') = _;
run(str('player %s spawn at %f %f %f facing %f %f in %s in %s', _:'name', _:'x', _:'y', _:'z', _:'yaw', _:'pitch', _:'dim', _:'gm'))
);
);
);

Expand All @@ -42,4 +61,4 @@ __on_server_shuts_down() -> (
);
store_app_data(data);
if (saved, logger('warn', 'saved '+saved+' for next startup'));
);
);