Jump to content

[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)


jakj

Recommended Posts

No need for an API when the block's functions can just be called directly or (preferably) by reflection. The practice of API s in modding is bad anyway, because it encourages lazy programming and inter-mod dependence for no good reason. Only in the case of having to extend or implement something does an API make sense.

My code is still a mess, though, so the 3.0.0.0 release for Minecraft 1.7 will include some cleanup for easier access.

Regarding threading again, note that I already have to synchronize on Computercraft control against three Minecraft main thread, because the cc thread has stale world data that in turn fail to propagate without switching control to the Minecraft. In essence, I halt Computercraft entirely every time I move. Your efforts are admirable, but you're looking at the potential for a DOUBLE deadlock even, and that's horrifying.

Link to comment
Share on other sites

I had hoped to get around reflection, since APIs generally make it harder to do things wrong (unless the designer screws up royally). The threading in CC sounds to be more complex than I thought... I'll evade that then. I considered basic CC peripheral support - and simple stuff like the disk drive works - but after hearing that I'll happily take it out again. Anyway, reflection it is, and it surprisingly works really well (sorry for the terrible quality).

Link to comment
Share on other sites

I had hoped to get around reflection, since APIs generally make it harder to do things wrong (unless the designer screws up royally). The threading in CC sounds to be more complex than I thought... I'll evade that then. I considered basic CC peripheral support - and simple stuff like the disk drive works - but after hearing that I'll happily take it out again. Anyway, reflection it is, and it surprisingly works really well (sorry for the terrible quality).

Reflection (if you don't need to extend or implement anything) allows you to have simple code that works whether or not another mod is installed, without even having to do version checks: You simply pre-load the class/method/field values, and if any fail, your target mod is not available in its proper version.

Using an API locks you to that other mod: If your mod uses another mod's API, and that other mod is not installed, your mod crashes MInecraft on load. "Just distribute the API" you say. Well, time and again that has proven to fuck things up, as Minecraft mods change rapidly as do their APIs, and Java is just as likely to take your outdated one first as the other mod's, actually replacing a newer version of a mod's classes with older versions of its own classes, sometimes even breaking every other mod in the installation that also uses that API's newer version.

Sure, APIs make it a little harder to screw up, but really only from typoes; Face it: Most bugs are logic bugs that result in runtime NPEs or casting errors, not anything a compiler would catch, plus the fact that mods are a hackjob anyway that mess with Minecraft's already-messed-with internals, in addition to type erasure. Even Javac's annotations are a hackjob: "@Override" is great for what it does, but there's no converse or inverse, so it's little more use than taking a parakeet into a mineshaft: You're warned about bad air, which is great, until a weakend rock shelf collapses and takes you and the track down into the cavern below.

As for the CC threading, just implementing it to work with Minecraft isn't too bad: You can override an existing method and add "synchronized" to it, so what I do is I have both callMethod and updateEntity synchronized, callMethod sets a flag and yields, the next run of updateEntity sees the flag, acts, notifies the yielded thread, and returns, causing callMethod to resume and return as well. If all you need your peripheral to do is edit the world, a basic mutual lock is all you need.

Link to comment
Share on other sites

All good points, in particular in the modding environment. But to be fair, if there's no API, it's much more likely for code to get "out of sync" with the reflected classes, since the author of those classes won't even know someone else is using them - as opposed to when an API is defined, as a clear interface to the valid interactions with those classes.

I agree that differing versions of an API are an objective reason to avoid it. I suppose not even Forge's dependency system could help with that issue, since it probably has to load every class in every jar/zip before it gets to that point? Still, aside from spelling mistakes, there's one other thing that irks me about reflection: it makes things harder to read - even more so when the parameters of a function also have to be reflected. Which in turn makes it harder to spot mistakes.

I'd like to argue that changes to an API should be a very rare thing, and be accompanied with the appropriate major version change, but I've read enough rants to see the futility in that. And starting to talk about performance in the context of Minecraft... well, never mind.

Threading: interacting with CC as a... client, sure. I have a block that acts a peripheral for CC and behaves like a modem, so I can send messages between my mod and CC. For that simple synchronization does the job just fine. What I am more worried about is trying to talk to other peripherals, since I have no way of telling what sort of assumptions they make. As I wrote above, callMethod of the carriage controller lead to a deadlock/block (depending on whether the callback ran in the computer thread or the server thread), and no amount of synchronization would have helped there, since it's just not possible to solve this synchronously when the calling computer is moved. But I wasn't too comfortable with that anyway... so good riddance.

I'm actually looking forward to the 1.7 update. For now I'm calling SetupMotion + Move in the CarriageController (from the server thread). Since that works I guess that's enough? Oh, just one more question and I'll shut up: is there a reason you don't use ForgeDirection for the movement direction (e.g. in SetupMotion) but a custom enum?

Link to comment
Share on other sites

Yeah, performance in Minecraft... My code is actually awful in a lot of ways, super inefficient with unnecessary instantiations billowing out like steam from a power plant, and yet my code is still blindingly fast in comparison to Minecraft actually moving the blocks such that I've never even needed to try to optimize it at all.

My direction enumeration is just a mirror of Forge's that is easier for me to read and use. It's so much easier to figure out NegX/PosZ and such rather than NORTH/SOUTH/EAST/WEST, and some coding conventions (like constant names in all-capital letters) gives me hives. My coding style is pretty alien to the rest of the universe, and even my usage of extra whitespace can give fits to normal coders who read it.

I should clarify that the API itself isn't actually the problem: The method of access is. For example, things like Buildcraft absolutely need an API because it's just too complex to mess with directly, and obviously the tight-assed modders who don't even release their source do better by giving out APIs because it saves having to decompile their mod to do simple things. But you should absolutely never actually just directly use the API in your mod but rather should reflect it. For example, my carriage controller has to extend a CC interface, so I attempt to load the controller class by reflection, and if that reflection fails, I do not add the recipe for it nor do I add it to the creative menu. (The newest line of Forge has a special transformer that lets you strip out an interface from a class at load if it's not available, which is great, but of course Forge never backports or supports old versions like we have to, so that feature is actually useless to us until we stop supporting 1.5.)

For coding clarity...that's why I've got my own Java preprocessor (like the C preprocessor but tailored to my style) so I can use very short incantations for complex things that makes the code easier to write.

Link to comment
Share on other sites

See everyone, Jakj is a Wizard. He has distilled a universe of possibility down to a few key words of power, and can create feats of magic by invoking that power with mere finger wiggles.

Oh, piffle, I just like to spend 8x the time rearranging my code than it took to write it in the first place.

Also this: http://instinct.org/texts/jargon-file/jargon_24.html#TAG931

Link to comment
Share on other sites

My direction enumeration is just a mirror of Forge's that is easier for me to read and use. It's so much easier to figure out NegX/PosZ and such rather than NORTH/SOUTH/EAST/WEST, and some coding conventions (like constant names in all-capital letters) gives me hives. My coding style is pretty alien to the rest of the universe, and even my usage of extra whitespace can give fits to normal coders who read it.

Yeah, I noticed the wrapping, that's why I was wondering. I didn't really run into a case where the actual "global" direction mattered, since I mostly use it to either iterate all directions or as a relative direction for an already rotated block, but I concur that your way is clearer when it does matter. I also wholly agree that the all-caps thing is a horrible convention.

Since you bring it up: how did you come to format your code that way? I have never seen such a unique beast anywhere else. It's almost like a unicorn. A horribly twisted unicorn, but still.

I should clarify that the API itself isn't actually the problem: The method of access is. For example, things like Buildcraft absolutely need an API because it's just too complex to mess with directly, and obviously the tight-assed modders who don't even release their source do better by giving out APIs because it saves having to decompile their mod to do simple things. But you should absolutely never actually just directly use the API in your mod but rather should reflect it. For example, my carriage controller has to extend a CC interface, so I attempt to load the controller class by reflection, and if that reflection fails, I do not add the recipe for it nor do I add it to the creative menu. (The newest line of Forge has a special transformer that lets you strip out an interface from a class at load if it's not available, which is great, but of course Forge never backports or supports old versions like we have to, so that feature is actually useless to us until we stop supporting 1.5.)

Hmm, I never really thought about that, actually - reflecting an API, that is. Food for thought. Regarding Forge's transformers, I didn't really get into that, yet, because I'm not particularly keen on messing with Java byte code, and from the few resources on it I could find that seems to be what it boils down to. Stripping out unnecessary interfaces on the other hand might just make me. It'd be nice if it were possible to just drop an annotation on the class, declaring which interfaces to rip out if mod xyz isn't present, but I fear it won't be that easy...

For coding clarity...that's why I've got my own Java preprocessor (like the C preprocessor but tailored to my style) so I can use very short incantations for complex things that makes the code easier to write.

I read about that earlier in the thread, sounds pretty wicked. I write my stuff in Scala, which some may consider weird, but I find it's just so much nicer than plain Java, since it cuts down on the noise dramatically. Mostly thanks to its clever type inferral.

Edit: oh how timely. Just checked the Forge changelog, and what do I see?

Add in an API marker for API type packages. This does several things: 1. Packages marked as API will generate a new "modid" (the provides) that can be depended on. 2. Packages marked as API will be searched systemwide, and anything declaring that package (even without the API marker) will get an implicit dependency on the API package. 3. The API package itself will get a soft dependency on the "owner" package.
Link to comment
Share on other sites

Yeah, I noticed the wrapping, that's why I was wondering. I didn't really run into a case where the actual "global" direction mattered, since I mostly use it to either iterate all directions or as a relative direction for an already rotated block, but I concur that your way is clearer when it does matter. I also wholly agree that the all-caps thing is a horrible convention.

The enumerations are in the same order, so their ordination is identical and they can be used interchangeably. It's cosmetic only.

Since you bring it up: how did you come to format your code that way? I have never seen such a unique beast anywhere else. It's almost like a unicorn. A horribly twisted unicorn, but still.

Self-conceit: No matter what it is in life, I always think of myself first. So, when learning programming, my brain does not even absorb things like whitespacing conventions or the like, instead first thinking about what is easiest for me to personally see and understand, and so my own style is established. When I was young, it genuinely never even occurred to me that I should even be thinking about how other people format their code, and just thought about the code itself.

I just can't stand the cramped nature of how people do things, with single-letter variable names everywhere and six-level conditional expressions all smooshed to half a line. I believe in self-documenting code that makes comments useless 99% of the time, and so much reliance on operator precedence instead of explicit usage of parentheses, and shit like "doathing(x++);doanotherthing(--y)" just adds extra time, when you look at a statement, and instead of immediately understanding it, you have to sit there and analyze it and remember the operator precedence and add the parentheses in your mind.

It seems like most people consider code to be just scribbles they spew out that make the machine do something, and don't really treat it with any kind of concern or pride at all. They give it no more thought than the mortar between bricks in a wall.

Hmm, I never really thought about that, actually - reflecting an API, that is. Food for thought. Regarding Forge's transformers, I didn't really get into that, yet, because I'm not particularly keen on messing with Java byte code, and from the few resources on it I could find that seems to be what it boils down to. Stripping out unnecessary interfaces on the other hand might just make me. It'd be nice if it were possible to just drop an annotation on the class, declaring which interfaces to rip out if mod xyz isn't present, but I fear it won't be that easy...

Don't let your wariness drive you away from one of the coolest things about Java: Its flexibility, and its mentality that "sure, we try to give you all these safety measures and make things orderly, but if you reeeeeally want to, we let you do brain surgery with a toothpick". It's an attitude that suits Minecraft so well: It's why our modding scene is so diverse in the first place, that the language is so flexible and says "hey, if you know what you're doing, you can do anything". (Which makes it even sadder when the modders themselves start acting like the holy untoucheable saliva of an angel come down to drool on us, but anyway.)

That Forge feature is genius: It gets rid of all the hoops I'm going through to support mods' presence and absence. For the most part, mod support boils down to "implement interface, override functions that do shit", and to support that, you generally have to either have two copies of the class (one with and one without the interface) and hotswap them through reflection, or else you have to use reflection to load your class and ignore it if it fails. (Or you be a lazy asshole and just crash if it's not present, and have two versions of your mod that the user has to select.)

But with this feature, you have one class, and you just say "get rid of x, y, and z if they error out", and that's ALL. You never distribute an API, but you use them, and it's as simple and easy as leaving your coat at the door as you walk into the restaurant.

I just wish Forge gave a fuck about modpacks and would backport this feature to 1.5. But the Forge team is all about "driving into the future" and CPW especially finds it repugnant that we support old Minecraft versions at all, so that ain't happenin'.

I read about that earlier in the thread, sounds pretty wicked. I write my stuff in Scala, which some may consider weird, but I find it's just so much nicer than plain Java, since it cuts down on the noise dramatically. Mostly thanks to its clever type inferral.

I tried scala, but I'm just not man enough to handle it. It has some really nice things that I wish Java had, but it also obliterates a lot of nice things that Java does have. Type inferral is actually a regression in my opinion, because I think one of the biggest mistakes Sun ever made was to implement generics with type erasure for backwards compatibility. I believe backwards compatibility is a good thing, and should be present at all reasonable times, but in this case it crippled the feature and cut its effectiveness by nearly a half.

Part of Java's excellence is that it wraps you and your code up in soft and gentle cloths to protect you against yourself and everything else, but it also allows you to slice right through those cloths and manipulate anything and everything all the way down to the bit level as you will. It's the perfect blend of functionality and freedom.

Link to comment
Share on other sites

The enumerations are in the same order, so their ordination is identical and they can be used interchangeably. It's cosmetic only.

Cosmetic: from your point of view, sure. From a logical standpoint, absolutely. When calling things via reflection? Not so much. Is it a problem? Not at all.

Self-conceit: No matter what it is in life, I always think of myself first.

I see. I started reading coding conventions when picking up a new language pretty early, since they often contain little tidbits about the language that otherwise get lost in lengthy introductions. So I've become a little obsessive when it comes to having my code not only be logically structured well, but also "look" uniform and clean.

I just can't stand the cramped nature of how people do things, with single-letter variable names everywhere and six-level conditional expressions all smooshed to half a line. I believe in self-documenting code that makes comments useless 99% of the time, and so much reliance on operator precedence instead of explicit usage of parentheses, and shit like "doathing(x++);doanotherthing(--y)" just adds extra time, when you look at a statement, and instead of immediately understanding it, you have to sit there and analyze it and remember the operator precedence and add the parentheses in your mind.

Clear code makes comments redundant for the most part, true. But if the context is small enough, single letter variable names don't really make things worse I think. Say you have a function named getSize(), it'd be pretty obvious what two variables 'w' and 'h' in that function would mean.

As for the language feature category (operator precedence, ...), I wouldn't throw all of that into the same bin. Sure, there are some concepts that are... awkward. But I often find that once I get used to it they make reading code easier (as a big example: functional programming languages in general). Scala is a prime example of that also. I'd say "good style" actually differs from language to language. Some languages just are more verbose than others by nature, and it's usually easier to "go with the flow".

It seems like most people consider code to be just scribbles they spew out that make the machine do something, and don't really treat it with any kind of concern or pride at all. They give it no more thought than the mortar between bricks in a wall.

The sad reality is that the majority of all humanity is stupid (just look at how people vote), so that probably has something to do with that.

That Forge feature is genius: It gets rid of all the hoops I'm going through to support mods' presence and absence. For the most part, mod support boils down to "implement interface, override functions that do shit", and to support that, you generally have to either have two copies of the class (one with and one without the interface) and hotswap them through reflection, or else you have to use reflection to load your class and ignore it if it fails. (Or you be a lazy asshole and just crash if it's not present, and have two versions of your mod that the user has to select.)

But with this feature, you have one class, and you just say "get rid of x, y, and z if they error out", and that's ALL. You never distribute an API, but you use them, and it's as simple and easy as leaving your coat at the door as you walk into the restaurant.

I suppose this is what you're talking about? I'm officially impressed. It actually is that easy. I must say, one issue I have with Forge is that it's a little tiresome to learn what's possible and what isn't. The wiki seems to be generally out-dated except for the basic tutorials.

I tried scala, but I'm just not man enough to handle it. It has some really nice things that I wish Java had, but it also obliterates a lot of nice things that Java does have. Type inferral is actually a regression in my opinion, because I think one of the biggest mistakes Sun ever made was to implement generics with type erasure for backwards compatibility. I believe backwards compatibility is a good thing, and should be present at all reasonable times, but in this case it crippled the feature and cut its effectiveness by nearly a half.

What does type inferral have to do with generics? It just means you don't have to explicitly write the type in most cases, it doesn't change anything with regards to the underlying type. E.g. writing 'val nodes = mutable.Set(node1, node2, node3)' still makes 'nodes' a 'HashSet<Node>'. That doesn't mean Scala doesn't suffer from type erasure, too - that's built into the JVM (but there's ways around that in Scala, actually, TypeTags are one). I just mean to say that has no relation to type inferral whatsoever.

Link to comment
Share on other sites

Cosmetic: from your point of view, sure. From a logical standpoint, absolutely. When calling things via reflection? Not so much. Is it a problem? Not at all.

Well, I suppose it adds an extra line as you have to reflect the Directions class too, but I meant cosmetic as in "ForgeDirection foo" -> "foo == ForgeDirection . values ( ) [ Directions . values ( ) [ foo . ordinal ( ) ] . ordinal ( ) ]".

I see. I started reading coding conventions when picking up a new language pretty early, since they often contain little tidbits about the language that otherwise get lost in lengthy introductions. So I've become a little obsessive when it comes to having my code not only be logically structured well, but also "look" uniform and clean.

I started by just reading the books in the library written by the guys who made the languages, like Stroustrup. They did have sections in there about code layout, but I didn't bother to read them, because I just assumed they were more "beginner student" material and I cared about the actual information.

I don't really remember my university courses in programming much at all, but I also don't remember butting heads with professors/instructors over whitespacing, so I'm guessing I've just never really encountered any actual time of being "forced" into matching widespread conventions. And since I didn't even finish university, I'm not ever going to actually get a job doing this nor rejoin the current academia, so there's really no incentive for me to do anything but what makes me most comfortable.

A bus driver really isn't held to the same standards as a Google engineer.

Clear code makes comments redundant for the most part, true. But if the context is small enough, single letter variable names don't really make things worse I think. Say you have a function named getSize(), it'd be pretty obvious what two variables 'w' and 'h' in that function would mean.

As for the language feature category (operator precedence, ...), I wouldn't throw all of that into the same bin. Sure, there are some concepts that are... awkward. But I often find that once I get used to it they make reading code easier (as a big example: functional programming languages in general). Scala is a prime example of that also. I'd say "good style" actually differs from language to language. Some languages just are more verbose than others by nature, and it's usually easier to "go with the flow".

Some limited examples, sure, like w/h for width/height, i for index, t for time, and what-not. But it also makes it more difficult to read because single-letter variables are almost always lowercase (and my eye picks out uppercase as the "start of a thing"), and also they tend to blend with punctuation/operators, ESPECIALLY near-baseline operators like period and comma, and even more so when there isn't any whitespace between them. Seeing things like "runid = f.getInt();" is just so much less clear to me than "RunId = Fallback . getInt ( ) ;". My eye just flows over the latter like a real-language sentence, whereas the former I have to take a moment to break apart into bits (almost as if my brain were a parser) to understand.

I suppose that's a good way to explain it: The way I write code, it flows directly into my brain in exactly the same way reading regular English does, but the way most people write code, my brain has to sit there for a second and tokenize it just like an actual parser does.

I suppose this is what you're talking about? I'm officially impressed. It actually is that easy. I must say, one issue I have with Forge is that it's a little tiresome to learn what's possible and what isn't. The wiki seems to be generally out-dated except for the basic tutorials.

Yeah, the Forge team oscillates between "we are dedicated to making our code understandable" and "suck it up and read the code, ninny; we're not here to spoonfeed you". It's one downside to unpaid volunteer coding, really.

Between the poor performance, the sparsity, and the fact that it's not even maintained by Forge but rather by people just like us who read the code to understand it anyway, the Forge wiki is 100% useless and to me doesn't even exist.

What does type inferral have to do with generics? It just means you don't have to explicitly write the type in most cases, it doesn't change anything with regards to the underlying type. E.g. writing 'val nodes = mutable.Set(node1, node2, node3)' still makes 'nodes' a 'HashSet<Node>'. That doesn't mean Scala doesn't suffer from type erasure, too - that's built into the JVM (but there's ways around that in Scala, actually, TypeTags are one). I just mean to say that has no relation to type inferral whatsoever.

I wasn't relating type inferral and generics: Those were different topics. I didn't like type inferral because I thought it was weak typing, but if it's not, I still don't like it because it elides the clarity of having the type at the declaration. Not having the type there reduces the self-documenting quality of the code in most cases.

Link to comment
Share on other sites

ESPECIALLY near-baseline operators like period and comma

Funny you mention that. For example, I need to have commas to immediately follow some text and to be followed by some whitespace for the best reading performance (hence I stumbled quite a bit reading your code, since they become hard to distinguish from periods). Luckily everyone can choose their own preference, and auto-formatting can act as a translator for the most part (at the level google translate does for real languages...).

I wasn't relating type inferral and generics: Those were different topics. I didn't like type inferral because I thought it was weak typing, but if it's not, I still don't like it because it elides the clarity of having the type at the declaration. Not having the type there reduces the self-documenting quality of the code in most cases.

Fair enough. You can deliberately annotate the type if you feel like it, though (in some cases it's even necessary). So you're not forced to rely on the type inferral. For example, `val x = 10` is the same as `val x: Int = 10`. In fact, Scala makes it a lot easier to get readable type names when you want them, since it allows for aliases.

Which comes in handy quite often, because it generally encourages a style of few variables and more functions... like in... you know, functional programming. And for functions specifying the types is required (since it's strongly typed). Except for the return type, which can be inferred. Well, and for anonymous functions, there the parameters can usually be inferred, too. Speaking of which, one big reason I can't be bothered to code in plain Java anymore is because functions aren't first-class citizens. I just loathe having to explicitly implement an interface to get the equivalent of a closure.

... damn, I sound like a Scala evangelist, don't I? I'll stop now.

Link to comment
Share on other sites

Funny you mention that. For example, I need to have commas to immediately follow some text and to be followed by some whitespace for the best reading performance (hence I stumbled quite a bit reading your code, since they become hard to distinguish from periods). Luckily everyone can choose their own preference, and auto-formatting can act as a translator for the most part (at the level google translate does for real languages...).

Time to get a non-shitty coding font. :P Man, I miss Mishawaka from my 68k assembly days, though...I would kill to get a copy of Mishawaka now.

Fair enough. You can deliberately annotate the type if you feel like it, though (in some cases it's even necessary). So you're not forced to rely on the type inferral. For example, `val x = 10` is the same as `val x: Int = 10`. In fact, Scala makes it a lot easier to get readable type names when you want them, since it allows for aliases.

Which comes in handy quite often, because it generally encourages a style of few variables and more functions... like in... you know, functional programming. And for functions specifying the types is required (since it's strongly typed). Except for the return type, which can be inferred. Well, and for anonymous functions, there the parameters can usually be inferred, too. Speaking of which, one big reason I can't be bothered to code in plain Java anymore is because functions aren't first-class citizens. I just loathe having to explicitly implement an interface to get the equivalent of a closure.

... damn, I sound like a Scala evangelist, don't I? I'll stop now.

Java is getting closures.

And that explains the absolute pain in the ass it was to reflect into scala code to change the value of a field.

Link to comment
Share on other sites

Hi there.

I think I've stumbled upon a world crashing issue.

I have on my template frame construction the following

{a}{a}{a}{a}{a}{a}{u}{b}{a}{a}{a}{a}{a}{a}

{c}{c}{c}{c}{c}{s}{e}{B}{a}{a}{a}{a}{a}{a}

where {a} is air block

{c} is clear glass from the smeltery stuff (not sure of the mod name tbh? tinkerers construct?)

But the real world breaker is the following

{s} = a mv compact solar panel

{u} = an ultimate hybrid solar panel

{b} = power crystals BC producer

{e} = power crystals HV consumer

{B} = power crystals bridge

What happened is I accidently moved the platform left (was trying to find a better spot for a pressure plate) and it crashed because it can't cast a TileEntityCompactSolarMV to a powercrystals.powerconverters.power.TileEntityBridgeComponent

I don't have the logs from the original crash, but when logging back into the server I get these logs

Client console log - http://pastebin.com/m0jxHrDH

crash-2013-11-06_21.24.57-client.txt http://pastebin.com/hQgF0g48

Server console log - http://pastebin.com/96W7AGrR

Link to comment
Share on other sites

I can't diagnose this just from the information you've presented, but one of the two following things is possible:

If you are able to replicate this crash 100% of the time with the same block layout in the same direction of motion, and you are able to prevent the crash by doing everything the same way except replacing one or more of the PC blocks with other blocks carrying tile entities, then it's probably a bug in PC or else PC is doing funky things with the way it initializes blocks that it shouldn't.

If you are able to replicate this crash 100% of the time with the same block layout in the same direction of motion, and you keep getting the crash even by doing everything the same way except replacing one or more of the PC blocks with other blocks carrying tile entities, then it's probably a bug in my code that's screwing up or garbling the replacement of tile entities.

Link to comment
Share on other sites

I've fixed it for tonight (removed compactsolars mod, moved the platform forward a bit, reinstalled the mod) tomorrow I'll set up a single player world and try to replicate - I can even get you a screenshot.

I'd say it's a a strange interaction between PC, CS and RIM, I've got all sorts of other blocks (rednet cable, computer craft computer, bc pipes/facades/gates miners, te tesseracts & conduit, extra utilities transfer nodes/pipes, and MFR Block breakers) on this thing and that's the only is that interaction.

Link to comment
Share on other sites

I've fixed it for tonight (removed compactsolars mod, moved the platform forward a bit, reinstalled the mod) tomorrow I'll set up a single player world and try to replicate - I can even get you a screenshot.

I'd say it's a a strange interaction between PC, CS and RIM, I've got all sorts of other blocks (rednet cable, computer craft computer, bc pipes/facades/gates miners, te tesseracts & conduit, extra utilities transfer nodes/pipes, and MFR Block breakers) on this thing and that's the only is that interaction.

Sounds like you're right about it being a strange interaction between the mods: One of them is pulling shenanigans.

Link to comment
Share on other sites

Further digging for Mishawaka leads me to say that, sadly, it's a Mac-only font. I did find out that ProFont and Monaco are pretty damn close, however, and both are avaliable in TrueType formats. (In fact, you should already have Monaco installed.)

Link to comment
Share on other sites

Hmmm. I just tried to move my mining well frame quarry with the translocator and the server crashed. Now I am getting a ton of errors in my server's console:

013-11-07 23:06:34 [iNFO] [sTDERR] java.util.ConcurrentModificationException

2013-11-07 23:06:34 [iNFO] [sTDERR] at java.util.HashMap$HashIterator.nextEntry(HashMap.java:839)

2013-11-07 23:06:34 [iNFO] [sTDERR] at java.util.HashMap$ValueIterator.next(HashMap.java:868)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.nbt.NBTTagCompound.func_74734_a(SourceFile:25)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.nbt.NBTBase.func_74731_a(SourceFile:119)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.nbt.CompressedStreamTools.func_74800_a(CompressedStreamTools.java:140)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.world.chunk.storage.AnvilChunkLoader.func_75821_a(AnvilChunkLoader.java:198)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.world.chunk.storage.AnvilChunkLoader.func_75814_c(AnvilChunkLoader.java:184)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.world.storage.ThreadedFileIOBase.func_75736_b(SourceFile:30)

2013-11-07 23:06:34 [iNFO] [sTDERR] at net.minecraft.world.storage.ThreadedFileIOBase.run(SourceFile:23)

2013-11-07 23:06:34 [iNFO] [sTDERR] at java.lang.Thread.run(Unknown Source)

I shut the server down, disabled RIM, booted the server back up and am getting the same error.

Looking at the crash dump, it seems my wireless redstone receiver might of been the cause. Or at least the interaction between the two mods.

Now I've disabled both Wireless Redstone and RIM... but on world load I still get the CME filling my logs. I don't have a recent backup of the world. What can I do?

Crash-dump: http://pastebin.com/7ywgpmN8

Link to comment
Share on other sites

Well, analyzing the crash dump, it looks like what happened is Wireless Redstone erroneously decided its block was improperly-placed and tried to delete itself, and there's a bug in his vector code that caused it to crash. However, at that time, all the blocks had successfully been placed back down in the world, and the crash should have forced an emergency save to disk, so the world *should* be intact.

Probably, your ConcurrentModificationException is still happening because of Forge Multipart (which Wireless Redstone uses), though I'm not sure how that could be. Your two options to try to get your world back are to either keep disabling mods until it works, or use a world editor to see if there are stray tile entities or otherwise to just delete blocks until it works.

Link to comment
Share on other sites

Thank you jakj for taking the time to help :)

While I don't know much about minecraft modding or java in general, I'm pretty adept at trying logical tactics to resolve my problem (after having a "clean" backup of my world made). Since disabling the RIM/WRE-CB mods didn't do it, I figured it was mutlipart causing it. I opened up the map inside of MCEdit and didn't see anything out of the ordinary in the two places the frame carriage was.

My server won't load (due to mod dependancies) without multipart, so I just went after WRE-CB and multipart.

To resolve the issue I deleted three files from underneath my world folder:

forcedchunks.dat

multipart.dat

RedstoneEther\*

I tried to delete just one or the other, but it did not have the desired affect. Deleting all three however made the errors go away and everyone is happy as a clam.

Love your work, having a lot of fun.

Link to comment
Share on other sites

Got the following crash combining Power Boxes on a Redstone in Motion frame...I was able to replicate the problem, and it occurred every time the frame moved. I don't know if this crash is on your end, or with Power Boxes, so I'm posting the crash report in both places.

http://pastebin.com/kb7MjW4z

Another class-cast exception? Hurgh. Never did figure out why that happens. Does the crash happen when you initiate the motion, or when it finishes? Is anything left of the carriage when you reload the world? Does it happen the same way no matter which direction the carriage is moving?

Link to comment
Share on other sites

Another class-cast exception? Hurgh. Never did figure out why that happens. Does the crash happen when you initiate the motion, or when it finishes? Is anything left of the carriage when you reload the world? Does it happen the same way no matter which direction the carriage is moving?

Let's see...the crash appears to happen when the motion finishes...at least I can see the hitboxes of everything shift, and then the crash happens. I was able to reload the world once and the frame machine looked intact, though it was only loaded for a couple seconds before it crashed again (I set up a computer with one of your computer controlled motors and its programmed to move the frame every 10 seconds as long as it's got a redstone signal, and well, I used a lever :S...and well, the world's loaded even though I'm still on the loading screen for much of those 10 seconds due to my using an old old old computer). When I tried to log into the world after the second crash the world didn't load fast enough for me to see the frame before it crashed again. I'm probably going to have to go into MCEdit and delete a lever to get the computer to stop processing forward movement so I can get back into that world. I'll try to do that later and test moving different directions...the direction I was moving when it crashed was North.

edit: and don't worry about ruining my world...this was one my test worlds where I mock up builds to make sure they work before making them for real...and it was the first thing I built in the world, so no loss :)

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
×
×
  • Create New...