Jump to content

jakj

Members
  • Posts

    3240
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by jakj

  1. 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.
  2. Sounds like you're right about it being a strange interaction between the mods: One of them is pulling shenanigans.
  3. 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.
  4. Time to get a non-shitty coding font. Man, I miss Mishawaka from my 68k assembly days, though...I would kill to get a copy of Mishawaka 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.
  5. 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 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. 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. 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. 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.
  6. The enumerations are in the same order, so their ordination is identical and they can be used interchangeably. It's cosmetic only. 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. 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 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.
  7. 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
  8. Oh sweet. This is cool because some might prefer an in-game interface like I do and some might prefer file editing like you do. Yay options!
  9. 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.
  10. 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.
  11. 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.
  12. Setting aside the fact that C# and Java are about as similar as peanut butter and horseradish, no: Suspended or not, they cannot be stored to and retrieved from disk in any reasonable way, nor can they be deconstructed/reconstructed in any sort of independent context.
  13. And the thread of execution can't be preserved in the same way as a block, anyway: Data are serializeable, not processes, and you really can't cryo-state a thread the same way you can an entire system. My mod has as a core element the fact that all of the object in-transit cease to exist for the duration of the transit, as if they were in suspended animation, so nothing can be allowed to follow those objects that continues to be processed in the interval.
  14. Your idea is flummoxed by the fact that the computer (and carriage controller) are destroyed and recreated in order to move them, so there can be no continuity of call. Again, this is not Redpower that moves the tile entities directly: I cause them to write to a record just as if they were being saved to disk, and then I delete them entirely (letting ComputerCraft clean up however it does, although according to another post, ComputerCraft actually doesn't clean them up properly and leaves thread-turds all over your system, but anyway), wait a bit while doing Fancy Graphics, and then recreate them as if they were being loaded from the disk, but in a new position.
  15. Eloraam's method was to directly transfer the tile entities from block to block while keeping everything in memory with placeholders, meaning nothing was saved to disk with the world and didn't survive a crash. My method instead tricks the blocks into thinking they're being saved to disk (which gets around the aforementioned countermeasures, since obviously a block MUST save to disk), and those records are stored in a stable placeholder of my own which in turn saves itself to disk. Assuming no bugs in my code, this means the only possible way for a carriage to be destroyed while in-transit is if a catastrophic hard-lock or coredump happens in the JVM or your system, because any time Minecraft itself crashes normally, it does an immediate emergency disk-save (thus preserving the carriage).
  16. Sigh. Sounds like it's time to start thinking about doing an FAQ or something. Anyway... 1) This isn't RP. Eloraam did things in a different way that was better while the game was running but fucked up if the game stopped. Also, her actions were in a different environment: Nowadays, there are modders trying to implement active countermeasures against mods that move their blocks, and my method is the only method that can defeat those countermeasures, short of having to write and maintain individual-per-mod code to handle every edge case, as well as version detection if the cases change rapidly. 2) Write a smart startup program that can handle being rebooted, or use some sort of remote control with wireless redstone (or whatever) and don't move the computers at all. 3) ComputerCraft uses a separate meta/work thread that has its benefits but generally fucks everything up if you try to mix CC and non-CC things, so you need to introduce substantial delays (in the usual worst case, as much as a full second) to let things settle and reboot, before trying to use them again. Oftentimes, you can just put an os.sleep(0.1) (for a fast computer) or os.sleep(1) (for a slow computer or on a server) as the first line of your startup program.
  17. In that case, you'll have to give me more to go on than "it no work".
  18. Oh, is that what he meant? I thought he meant they were shutting down as in not rebooting and rerunning the startup program. If they're running startup, they're working right.
  19. That's not even a thorough description of the problem, let alone any kind of error report I could actually do something about.
  20. That list is rapidly shrinking. The best I can say is, at least nobody whom I personally listed has fallen off: They're all still good.
  21. Ugh, more trouble because of CC's multithreading. I know why he did it that way, and I can't wholly disagree, but it's such a massive pain in the ass.
  22. Yeah, buildcraft has probably changed quite a bit since I put in that initial hack. You can go into your config file to turn off the buildcraft workaround, which will stop the log spam. Buildcraft pipes still work fine with being moved, but without the workaround (which those errors show isn't working for you anyway), they need a second after motion to really reinitialize and get going again because of the wonky-assed way they're programmed.
  23. Sounds like the tesseract is not properly deconstructing/reconstructing itself on invalidate()/validate(). I'll call that a flaw in the other mod for now.
  24. Eh. I've played out vanilla a long time ago. (In fact, I was about to put the game down and not touch it again, when the Yogscast started putting out Technic videos and I went "oh, you can mod it? This is interesting".) Multiplayer is so laggy even on good servers with 3 people online that I can't bear to try it. None of the minigames like queef or whatever the hell it's called are actually fun to me. Adventure maps are usually just a bunch of poorly-spelled signs or books with a bunch of jumping puzzles. Heavily-modded Minecraft is what I like, and I have at times played it for 200+ hours in a single month. I just can't really get myself to do it right now. It's much more fun to fuck around with Java and Bash scripts. I've made myself a Bash script that works like the C preprocessor, except in Java, so I've got all kinds of nice things for myself now like build-value substitution, file inclusion, conditional compilation, and many shortcut commands. Like this: /*` #collection Carriage , CarriageEngine , Spectre `*/ becomes this: public Carriage Carriage ; public CarriageEngine CarriageEngine ; public Spectre Spectre ; public static void Initialize ( ) { Carriage = new Carriage ( ) ; CarriageEngine = new CarriageEngine ( ) ; Spectre = new Spectre ( ) ; } and this: public class Whatever { public int Ordinal ; /*` #provide Ordinal as int for IIndexer with getOrdinal `*/ } becomes this: public class Whatever implements IIndexer { public int Ordinal ; @Override public int getOrdinal ( ) { return ( Ordinal ) ; } } and this: /*` #errormode log `*/ { return ( ( int ) Class . forName ( "foo.bar.Baz" ) . getDeclaredField ( "quux" ) . get ( BazInstance ) ) ; } becomes this: try { return ( ( int ) Class . forName ( "foo.bar.Baz" ) . getDeclaredField ( "quux" ) . get ( BazInstance ) ) ; } catch ( Throwable Throwable ) { Throwable . printStackTrace ( ) ; } It's really quite neat.
×
×
  • Create New...