Hello, I'm absolutely new in Lua and Factorio modding (but I'm familiar with C, C++, Java and JavaScript), and I want to host a server for 4 players and enforce rules below:
— all players have separate research progress, and because of this, belong to separate forces;
— despite that, players are not allowed to commit damage to each other, nor directly, nor using turrets and another crafted items.
Main goal is to let players choose between playing together and playing on their own. That's why I'm going to use approach of quadrants in maps with these terms:
— every player is an “owner” of his quadrant (list of ownerships of quadrants will be fixed in script);
— owner of a quadrant can add a player as a “member” of quadrant, and revoke membership, using commands handled by my script;
— players without ownership and membership of a quadrant are “guests” of quadrant;
— square in a middle of the map, e.g. with 16 chunks side, and 4 infinite rectangles having one side from some side of central square, is the “DMZ”.
And here are rules for quadrants:
— guest is not allowed to build, cause damage to existing buildings, open inventories of buildings, mine resources, take objects from ground and belts;
— guest is not allowed to approach to spawners in twice a distance of taunting (or any other way to prevent mob-griefing);
— if building was built with a member and his membership is revoked, ownership for this building comes to owner of quadrant, and restores if player's membership is restored.
And rules for DMZ:
— anyone is allowed to build in DMZ, but without obstructing way through DMZ (every building should have at least one block of free space in eight directions, except belts, and special case for pipes, they can form four-way cross, but this cross still should have free blocks on its perimeter);
— wires don't connect poles with different owners automatically and are not allowed to be set unless both players issue some command which has effect in set time, e.g. 30 seconds or 5 minutes;
— guest with mobs chasing him, is not allowed to enter quadrant.
Finally, my questions:
— is this possible, or what is impossible in list above?
— what should I read to implement this? It would be good if you point to classes, required methods (if class has tons of methods), and maybe good practices for doing this.
Counter-griefing quadrant approach: what should I read?
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Counter-griefing quadrant approach: what should I read?
I assume you know https://lua-api.factorio.com/latest/
Over the years I've pondered making something similar a few times, so I'll post some thoughts. Difficulty of what you're trying to do is quite high. The main problem is that the modding api does not have any way to prevent or undo things. Realistically you have to deal with all events post-factum. The only practical way to really prevent a player from doing something is by using the LuaGameScript.permissions. If the DMZ between the quadrants is larger than player reach (== larger than screen at full zoom-out if you use long-reach mods) then you can theoretically use on_player_changed_position to dynamically assign players to permission groups. But that approach prevents players from building inside the DMZ if they currently are inside the DMZ, they can only build into the DMZ while standing inside their own quadrant.
Preventing damage should be relatively easy (compared to all the other stuff). You can just heal the entities in on_entity_damaged.
For biters I'd assign four different forces - one for each quadrant (on_chunk_generated + LuaSurface.find_entities_filtered). Then make each biter force friendly towards the other three quadrants so that they don't react to other forces than the owner of the quadrant (LuaForce.set_friend + LuaForce.set_cease_fire).
I wouldn't bother with tracking membership of entities. Anything that's built inside a quadrant should be reassigned to the force that owns that quadrant.
Over the years I've pondered making something similar a few times, so I'll post some thoughts. Difficulty of what you're trying to do is quite high. The main problem is that the modding api does not have any way to prevent or undo things. Realistically you have to deal with all events post-factum. The only practical way to really prevent a player from doing something is by using the LuaGameScript.permissions. If the DMZ between the quadrants is larger than player reach (== larger than screen at full zoom-out if you use long-reach mods) then you can theoretically use on_player_changed_position to dynamically assign players to permission groups. But that approach prevents players from building inside the DMZ if they currently are inside the DMZ, they can only build into the DMZ while standing inside their own quadrant.
Preventing damage should be relatively easy (compared to all the other stuff). You can just heal the entities in on_entity_damaged.
For biters I'd assign four different forces - one for each quadrant (on_chunk_generated + LuaSurface.find_entities_filtered). Then make each biter force friendly towards the other three quadrants so that they don't react to other forces than the owner of the quadrant (LuaForce.set_friend + LuaForce.set_cease_fire).
I wouldn't bother with tracking membership of entities. Anything that's built inside a quadrant should be reassigned to the force that owns that quadrant.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Counter-griefing quadrant approach: what should I read?
Thanks a lot for your answer, I will read that.
Well, there could be old “action–reaction” approach, like posting rules, and automatically killing a player who violates rules. Maybe with multiplied damage back to buildings.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amThe main problem is that the modding api does not have any way to prevent or undo things. Realistically you have to deal with all events post-factum.
Thanks a lot, I will read that.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amThe only practical way to really prevent a player from doing something is by using the LuaGameScript.permissions.
Looks like DMZ regulation is quite complicated. I'll think about that.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amIf the DMZ between the quadrants is larger than player reach (== larger than screen at full zoom-out if you use long-reach mods) then you can theoretically use on_player_changed_position to dynamically assign players to permission groups. But that approach prevents players from building inside the DMZ if they currently are inside the DMZ, they can only build into the DMZ while standing inside their own quadrant.
And healing will work even if entity is destroyed? Well OK.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amPreventing damage should be relatively easy (compared to all the other stuff). You can just heal the entities in on_entity_damaged.
I'd like to prevent a way for griefer to enter another player's quadrant, anger some biters on himself and lead biters to buildings of quadrant's owner.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amFor biters I'd assign four different forces - one for each quadrant (on_chunk_generated + LuaSurface.find_entities_filtered). Then make each biter force friendly towards the other three quadrants so that they don't react to other forces than the owner of the quadrant (LuaForce.set_friend + LuaForce.set_cease_fire).
I think it's good idea.eradicator wrote: ↑Tue Jun 01, 2021 11:47 amI wouldn't bother with tracking membership of entities. Anything that's built inside a quadrant should be reassigned to the force that owns that quadrant.
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Counter-griefing quadrant approach: what should I read?
Entites are not destroyed in on_entity_damaged. They're destroyed after on_entity_died if at the end of on_entity_damaged they have 0 health.
If you set up the forces like described above the griefer can only aggro his own biters. And those would have to pass through the DMZ to get to another player.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Counter-griefing quadrant approach: what should I read?
I did find a trick to forbid placing two buildings together, but it's rather awkward — I warned you! Here it goes:Northsoft wrote: ↑Tue Jun 01, 2021 8:40 am— anyone is allowed to build in DMZ, but without obstructing way through DMZ (every building should have at least one block of free space in eight directions, except belts, and special case for pipes, they can form four-way cross, but this cross still should have free blocks on its perimeter);
- Choose a collision layer "layer-NN" and add it to collision_mask of all entites that you want to prevent building next to each other. (Probably in data-updates phase to account for new entities from other mods).
- Create bunch of invisible entities with collision_mask = {"layer-NN"}.
- Whenever e.g. a 3x3 entity in placed in DMZ (on_built_entity, on_robot_built_entity, script_raised_built, script_raised_revive), place a 5x5 entity below it (mods can place entities in violation of collision_mask, so that's fine). Voilà! Now nothing can be built in one-tile radius around the original entity.
- Whenever an entity is removed (on_player_mined_entity, on_robot_mined_entity, on_entity_died, script_raised_destroy), remove the blocker entity.
Now, how do you forbid building certain entity types in DMZ? The solution is actually similar to the one above, but simpler:
- Again, create a special collision layer. Add it to all entities that you want to prohibit building in DMZ.
- Add a 32x32 invisible entity with this collision layer.
- Whenever a chunk is created (on_chunk_generated), check if this is a DMZ chunk and, if yes, place the entity there.
Instead of spawning invisible entities you could also replace tiles in DMZ with some special tiles (because tiles also have a collision_mask). The choice is up to you.
This seem quite hard, albeit not impossible. Preventing the player from entering DMZ is in fact easy: just subscribe to on_player_changed_position and teleport the player back. Checking if player is being chased in hard. But you could try to find_enemy_units and check their current command. If you check all biters within max_pursue_distance this would probably be quite robust. But I haven't don't anything like that, so I can't guarantee this would actually work.
However if you simply want to prevent the mobs from crossing DMZ, this could be done easily via the trick above. Add the new collision layer to biters and they wouldn't be able to enter the DMZ.
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Counter-griefing quadrant approach: what should I read?
If you're already using special blocking tiles for the DMZ you can just add that to the biters as well. Thus they can't enter the DMZ and are locked into the quadrant they were spawned in.andrei wrote: ↑Thu Jun 24, 2021 3:17 pmAnd that's it. Now only entities without the new collision layer can be built in DMZ.
Instead of spawning invisible entities you could also replace tiles in DMZ with some special tiles (because tiles also have a collision_mask). The choice is up to you.
This seem quite hard, albeit not impossible.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Counter-griefing quadrant approach: what should I read?
Maybe OARC can help