Jump to content

Mod Thoughts and Feedback


Recommended Posts

@PeterA Thanks for reading it! :)

 

I ran into it mainly when I was trying to get Abigail's Flower to work consistently between hosts and clients. In its current state (I know it's not released yet, but someone did go partway to updating it), it will behave like single-player if you're the host, but if you're a client it removes Abigail/her flower when you leave. The host's behavior is preferable, but the client needs a workaround like it currently has, and it seems weird to have the gameplay of it be inconsistent between them.

 

But as for how it might be used in the future... any scenario where you want leaving the game to not be treated differently whether you're a host or a client. But one situation where it might be useful is if one day you're hosting a server the way you do now, but then for some reason you decide you want to host it dedicated and maybe not play for the entire time you're hosting. Then you've transitioned from a host to a client between exiting and entering the next time, so any code that needs to be coupled to those two events would likely get tripped up unless they specifically anticipated that. Maybe that won't be possible come dedicated servers, though xD

 

My reasoning in general, though, was that since distinguishing the cases once you have them lumped together is really easy, but currently each requires a separate hook. Although in retrospect that rationale also extends to the other one, so we don't need a separate OnLocalPlayerSpawned, oops.

Link to comment
Share on other sites

This was originally a message to you.

 

~~~~~Dear @PeterA  ,

 

~~~~~Thank you for opening this message, this message is about the compatibility of mods to the game in reference to the modded characters and their avatars.

 

~~~~~If you decide to work it in soon, it can be handled similarly to the character select images.

 

~~~~~Please consider the following:

~~~~~Assume: [(modchar) == (your modded character's build name)]

 

~~~~~Therefore:

~~~~~[(modfolder/images/avatars/avatar_modchar)

~~~~~and

~~~~~(modfolder/images/avatars/avatar_ghost_modchar)]

 

~~~~~This could be a possible link to help add in mod character support, for avatars at least.

 

~~~~~Currently ghost mod support is working smoothly. Ghosts are automatically set to be ghost_"modchar"_build, so nothing really needs to be done to fix them, thankfully.

 

~~~~~Thank you for your time.

 

Best regards, Dryicefox.

Edited by Dryicefox
Link to comment
Share on other sites

Just to add to the above post, the places this would need to be addressed are in scripts/widgets/playerbadge.lua and scripts/widgets/targetindicator.lua. You could figure that out pretty quickly, but I figured it wouldn't hurt to point it out.

Link to comment
Share on other sites

I PMed this to @PeterA, but it belongs here.

 

Okay, a few things I've noticed so far:

 

  • The new networked components (seasons, clock, weather) suffer from the age-old mod kryptonite: file local functions/variables. I know that there is some give and take in this area (file local can help developers), but it kills moddability, and therefore I think it should be used very sparingly.

     

    For example, seasons.lua defines the SEASONS and SEASON_NAMES tables as file local (actually, Class constructor local), yet those are clearly tables that would be useful to modders (# SEASONS is a useful thing to know). Them being file local means that we'd have to copy the definition into our mod files to be able to use it, which makes things infinitely more prone to breakage down the line.

     

    See the GROUND_TURFS table in components/terraformer.lua for a really glaring example of this problem (and one that has existed forever).

 

  • The new componentactions.lua totally breaks mod backwards compatibility and is completely mod-unfriendly in general. As far as I can tell, it's not possible to insert new component actions from a mod without some major hackery (hooray for file local tables!). This'll likely need a new mod API function or something. I'm not sure why the CollectAction stuff was moved out of the component files, but I'm sure there was a reason.

     

     

  • Most simutil.lua GetX() functions are broken, and only a few have obvious solutions. I've written a bit of code to allow some backwards compatibility: http://privatepaste.com/60889df448 (those old SeasonManager/Clock member functions were very useful). I can't stress enough how often these GetX functions were used in mods.

     

Edited by squeek
Link to comment
Share on other sites

Another thing:

 

The worldstate component does not listen for the "clocksegschanged" event, thereby making it impossible for mods to access that information (meaning the current seg values) without writing our own listener.

 

Example fix:

 scripts/components/worldstate.lua | 6 ++++++ 1 file changed, 6 insertions(+)diff --git a/scripts/components/worldstate.lua b/scripts/components/worldstate.luaindex 7161be9..c389326 100644--- a/scripts/components/worldstate.lua+++ b/scripts/components/worldstate.lua@@ -70,6 +70,10 @@ local function OnMoonPhaseChanged(src, moonphase)     SetVariable("isfullmoon", moonphase == "full") end +local function OnClockSegsChanged(src, segs)+    SetVariable("clocksegs", segs)+end+ local function OnSeasonTick(src, data)     SetVariable("season", data.season)     SetVariable("issummer", data.season == "summer", "summer")@@ -129,11 +133,13 @@ self.data.isday = true self.data.isdusk = false self.data.isnight = false self.data.isfullmoon = false+self.data.clocksegs = {}  inst:ListenForEvent("clocktick", OnClockTick) inst:ListenForEvent("cycleschanged", OnCyclesChanged) inst:ListenForEvent("phasechanged", OnPhaseChanged) inst:ListenForEvent("moonphasechanged", OnMoonPhaseChanged)+inst:ListenForEvent("clocksegschanged", OnClockSegsChanged)  --Season self.data.season = "summer"
Edited by squeek
Link to comment
Share on other sites

 

I PMed this to @PeterA, but it belongs here.

 

Okay, a few things I've noticed so far:

 

  • The new networked components (seasons, clock, weather) suffer from the age-old mod kryptonite: file local functions/variables. I know that there is some give and take in this area (file local can help developers), but it kills moddability, and therefore I think it should be used very sparingly.

     

    For example, seasons.lua defines the SEASONS and SEASON_NAMES tables as file local (actually, Class constructor local), yet those are clearly tables that would be useful to modders (# SEASONS is a useful thing to know). Them being file local means that we'd have to copy the definition into our mod files to be able to use it, which makes things infinitely more prone to breakage down the line.

     

    See the GROUND_TURFS table in components/terraformer.lua for a really glaring example of this problem (and one that has existed forever).

 

  • The new componentactions.lua totally breaks mod backwards compatibility and is completely mod-unfriendly in general. As far as I can tell, it's not possible to insert new component actions from a mod without some major hackery (hooray for file local tables!). This'll likely need a new mod API function or something. I'm not sure why the CollectAction stuff was moved out of the component files, but I'm sure there was a reason.

     

     

  • Most simutil.lua GetX() functions are broken, and only a few have obvious solutions. I've written a bit of code to allow some backwards compatibility: http://privatepaste.com/60889df448 (those old SeasonManager/Clock member functions were very useful). I can't stress enough how often these GetX functions were used in mods.

     

 

I also had a long chat with peter about the modding issues the other day as well, i could cover more 'examples' but the base idea is there, they're writing exactly the way that's harmful for us modders by using locals and not returning them.

Link to comment
Share on other sites

In game there a some distance around player where npc is active, probably its 2-3 screens away from player position.

Outside this area monster will be in "pause" state.

 

I want to ask only one thing.

 

Please make this radius configurable. In any way. I understand that its made to keep game perfomance on descent level (especially for consoles/netbooks). But i am pretty sure that my PC can handle more. Ability to increase this radius of actual life can bring much more options to game, where monsters can live their own life without player interaction. Have some ideas about it, but current game situation doesn't allow to implement it.

 

Edited by Rincevvind
Link to comment
Share on other sites

@PeterA

In DST we can no longer lerp (or even set) the ambient colour in the same way we previously could via GetClock():LerpAmbientColour(), since now this is handled via hardcoded private methods and variables in TheWorld.components.ambientlighting (we can call TheSim:SetAmbientColour() directly, of course, but that'd get overriden the next time TheWorld.components.ambientlighting:OnUpdate() runs). Could you expose that functionality via a public method in components/ambientlighting.lua? And could you also expose the ability to customise the contents of the tables PHASE_COLOURS and CAVE_COLOUR (also found in components/ambientlighting.lua)?

Edited by simplex
Link to comment
Share on other sites

Why is DST making everything private/local?

 

Yep, even old stuff has been rewritten to enforce 'private' (look at kramped). It's... disheartening, to say at the very least, that they are trying to enforce the (nonexistant) concept of private functions (by saccing OOP completely, of all things), as the only thing it really does is block modders - and as I said before, they should be protected not private in the first place. The reason it's scary (to me) is that it exposes the mindset that 'it shouldn't be modded'. I hope I'm wrong, otherwise....

 

Link to comment
Share on other sites

@DeathDisciple, I think it's important to keep in mind that it's (a) only happened with files that required total rewrites (kramped is included there) and (b) that they were under a lot of time pressure to get the basic game ready for PAX. I'm guessing the large amounts of local stuff was just due to rushing to get that completed, and at that time mods weren't a consideration.

 

I'm pretty sure these will get exposed as PeterA gets around to visiting different mod compatibility topics. 

Link to comment
Share on other sites

@PeterA

Why is DST making everything private/local?

As Death said above me, when we first got access to DST and checked out the code, it just seemed to have been made with the mindset to block out any form of serious modding, I spoke with Peter about the issue and pointed out several things in the code a couple weeks ago.

 

We are currently just waiting to see what they change in the code and if any of the major suggestions get implemented before we even attempt to prepare our mod to  port over to DST. 

Link to comment
Share on other sites

@DeathDisciple, I think it's important to keep in mind that it's (a) only happened with files that required total rewrites (kramped is included there) and (b) that they were under a lot of time pressure to get the basic game ready for PAX. I'm guessing the large amounts of local stuff was just due to rushing to get that completed, and at that time mods weren't a consideration.

 

I'm pretty sure these will get exposed as PeterA gets around to visiting different mod compatibility topics. 

 

Um if you're under time pressure, you certainly arent rewriting files in such a way to remove the modding capabilities. The very component I mentioned has comments about 'private functions' that show the intent to do what's been done, not the 'hurried fix of old stuff'. If anything, the extent at which it was rewritten would be considered a waste of time if under time pressure. And it hasn't exactly been 'entirely rewritted', it was fixed/shuffled around and member functions were deliberately  moved into private. Please look at the files.

 

When I'm under time pressure and have to fix other people's code I just fix what is there, I don't try to rewrite it to fit my personal style/agenda/view of programming concepts/patterns. Then when the chaos is over, you sit down with your team and debate what and how should be improved to be more extendable/better/whatever.

 

Perhaps you have inside information that I don't *shrugs*. Ultimately, I do hope you're right..

 

EDIT: The main point is not about this file or that, but the mindset/direction of setting stuff as private/local/unmoddable. One file or the other could be fixed later, but the mindset has to change now, or if everything continues in that direction exposing every single case later would take too much time/effort and ultimately may be dismissed by Klei (and rightfully so, there's only so much we are worth, it's all business). It's not a matter of 'does mod X need ability Y' but 'could some mod  in the future use the ability to extend Y'.

Edited by DeathDisciple
Link to comment
Share on other sites

@DeathDisciple, No, they didn't need entire rewrites so that they could somehow not support mods. They required rewrites because the way they were written before didn't make sense in a multiplayer context. The reason they're local is because it's easier and faster to write them that way. 

 

Edit: Definitely make suggestions on how to improve mod support, but an "omg klei why are you trying to kill mods" attitude isn't going to make them want to work with you...

Edited by rezecib
Link to comment
Share on other sites

@DeathDisciple, No, they didn't need entire rewrites so that they could somehow not support mods. They required rewrites because the way they were written before didn't make sense in a multiplayer context. The reason they're local is because it's easier and faster to write them that way. 

 

Sigh. Did you do the file compare between DST and original files?  Please reread what I said. There is nothing easier in moving  function from class member to local vs simply not moving it and changing the rest just the same. It's extra effort. It's not being entirely rewritten.

 

Either way, I've given my feedback to the developers, wether they want to take it into account or not is up to them.

 

EDIT

 

Edit: Definitely make suggestions on how to improve mod support, but an "omg klei why are you trying to kill mods" attitude isn't going to make them want to work with you...

 

And defending bad choices is feedback how? How does that help Klei, let alone modding community? What has your attitude contributed to the topic at hand? There are places for showing your appreciation and warm feelings towards people, objects, or companies, I'm afraid this thread isn't one of those. Again, it's up to them if they want to consider my input or opinion valuable, not you, and as such, I will continue.

Edited by DeathDisciple
Link to comment
Share on other sites

 

 

EDIT: The main point is not about this file or that, but the mindset/direction of setting stuff as private/local/unmoddable. One file or the other could be fixed later, but the mindset has to change now, or if everything continues in that direction exposing every single case later would take too much time/effort and ultimately may be dismissed by Klei (and rightfully so, there's only so much we are worth, it's all business). It's not a matter of 'does mod X need ability Y' but 'could some mod  in the future use the ability to extend Y'.

I could not have said it better myself, If these issues are not resolved while the game is in development, it's most likely they will never be resolved.

Link to comment
Share on other sites

I'll try to mediate here.

It seems the increase on private members was motivated by hiding network specific code, which in itself is quite understandable, since (a) that code is very likely to undergo alterations along the road and (b) the way networking was implemented in DST is surprisingly low level for a game written chiefly in a high level language.

The way DST is handling private members is through local variables, which is not very OOP friendly (most Lua class implementations with access control do so via __index and __newindex metamethods to preserve proper OOP patterns), is not a great way but it is a way. And given that this way was chosen, access to these local variables requires everything to be defined in the constructor itself. That being said, excluding the very implementation specific wrapper functions, there's no good reason why Klei should write something like

local function Foo(baz)    -- stuffend
instead of

function self.Foo(baz)    -- the exact same stuffend
inside the constructors. I hope that, considering DST is still in closed beta, this was done provisionally because they didn'e have the time to think about what really needs to be private and what doesn't, though that explanation sounds a bit strange, since refactoring code is always more time consuming than planning beforehand. This also wouldn't explain the scripts/containers.lua case I pointed out before.

But I don't want to see this turning into a conflict; DST is still in closed beta, and PeterA hasn't even had a chance to reply. Though, regardless, I must say I find this spot on:

The main point is not about this file or that, but the mindset/direction of setting stuff as private/local/unmoddable. One file or the other could be fixed later, but the mindset has to change now, or if everything continues in that direction exposing every single case later would take too much time/effort and ultimately may be dismissed by Klei (and rightfully so, there's only so much we are worth, it's all business). It's not a matter of 'does mod X need ability Y' but 'could some mod  in the future use the ability to extend Y'.

I would really like to see a shift in software engineering mentality from "what absolutely needs to be exposed?" to "what absolutely cannot be exposed?" when designing classes and files. Edited by simplex
Link to comment
Share on other sites

Edit: Definitely make suggestions on how to improve mod support, but an "omg klei why are you trying to kill mods" attitude isn't going to make them want to work with you...

 

From past experience, there is no attitude that will make Klei want to work with us. They (and by they I mean one Klei developer at most at any given time) work with us only when and if they want to, independent of our 'attitude'.

 

Perhaps I'm just a curmudgeon when it comes to modding Don't Starve, but this is nothing new.

Link to comment
Share on other sites

 

From past experience, there is no attitude that will make Klei want to work with us. They (and by they I mean one Klei developer at most at any given time) work with us only when and if they want to, independent of our 'attitude'.

 

Perhaps I'm just a curmudgeon when it comes to modding Don't Starve, but this is nothing new.

I could not agree more, this is exactly what Death and I were talking about after we first got access to DST and saw how it was coded.

Link to comment
Share on other sites

  • Developer

Hey everyone,

 

Thanks for your feedback, it’s been valuable for me to see what’s important for you to make mods within Don’t Starve. There are a lot of topics being brought up in this thread, but I’ll try to address the general sentiments.

Many of the changes you’ve had issues with, in particular more things being local, were done during the rather significant re-write for multiplayer. At the time, mod support was set aside as a future task, simply because trying to maintain a functioning mod system while undergoing a significant re-write was prohibitively difficult given the time constraints. Much of the previous Don’t Starve functionality simply cannot be accessed the way people used to understand them. Because of this, the re-write included many changes to encapsulate functionality better. This was helpful for us when working on Don’t Starve Together, as the code base has changed significantly from the original Don’t Starve.

 

The intention of the re-write was never to hinder mods, it was simply a consequence of getting Don’t Starve to work multiplayer. While Don’t Starve Together is conceptually an expansion on Don’t Starve, from a technical standpoint it is a proper sequel. Despite sharing a common base, mod support between the two games is going to be different and it’s not expected that a Don’t Starve mod will drop right into Don’t Starve Together with no changes.

 

Originally we had not planned to have public mod support be functional this soon, but the overwhelming support from the community during the beta has encouraged  us to get mods working as soon as we could. The downside of this is that there are certain areas of the game that are simply not ready for modders yet. That said, I’m very eager to work with you all to open up access to game in a way that works both for you and for us.

 

Regarding how things will be become more accessible, it will be a combination of three things. Proper mod APIs, public tables/data where possible, and data driven mods. The reason why some things will continue to be local is that certain tables and components simply cannot be modified dynamically and still work, i.e. stuff that runs on server and client and must be in sync. We already encountered this with the actions and component actions tables for example, and they have to be extended indirectly via the new mod functions. Feedback from the community helped to identify this and the potential consequences of having multiple mods enabled. The purpose of us providing proper APIs for extending some of the core tables is to make it easier to maintain inter-mod compatibility, which is even more of an issue now, since clients may have more mods loaded than the server.

I look forward to working with the community, to build new and compelling experiences in Don’t Starve Together.

 

Link to comment
Share on other sites

  • Developer

Hello,

I'm starting with mods creation for DST and wonder how I can send custom RPC from server to a specific player ? 

 

I've already managed to send a message from client to server using SendRPCToServer()  (removing local keyword on RPC_HANDLERS in order to adding my own).

Server side, I don't know how I can send a Lua RPC from server to All or One of the client.

Do you have any Idea ? :)
 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...