-
Posts
72 -
Joined
-
Last visited
-
Days Won
2
Everything posted by Sangar
-
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Ah, right, that was a stupid mistake. Tracking events across the reboot would indeed be a pain in the ass. I got a little confused jumping between CC and what I'm currently working on... guess I'll shelf that approach and ask another question: do you plan on adding some rudimentary API to allow controlling carriages from other mods? Regarding process serialization, that's actually possible with Lua's coroutines, but as far as I know it has only been done for the vanilla C Lua libraries (e.g. via Pluto). I have a working prototype but ran into deadlocks emulating CC's interface, because I cannot allow saving while the executor runs (only yielded coroutines can be persisted). And when I do the call from the server thread the wait() in the CC callback obviously blocks for ever. Which triggered my previous post. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Regarding the CC threading issues, couldn't you solve it like CC does itself, e.g. for Turtles: set a flag when move is called and immediately return some 'event id' that you also save (unless the flag is already set/carriage is already moving in which case the call just fails immediately). Also store the computer that triggered the call. When the next server thread update runs, perform the move (if the flag is set). When the move is complete, queue an event in the computer that triggered the move with the previously returned event id and any additional results (stuff that's now returned directly). So basically convert the synchronous call into an asynchronous one. True, it involves quite a bit more bookkeeping, but it should do away with any threading issues. This makes the Lua side a tiny bit more fiddly, but that can be easily wrapped away (same way CC does it). It may look similar to this: -- Reusable wrapper stuff local function pack(...) return {n=select("#", ...), ...} end local function wait(moveId, ...) -- could be used to wrap any move callback if not moveId then return nil, ... -- immediate failure case end while true do -- wait for result event local result = pack(os.pullEvent("carriage_moved")) if result[2] == moveId then -- if we're done, return any results return unpack(result, 3, result.n) end end end -- Example usage local c = peripheral.wrap(side) wait(c.move(...)) -- replaces normal c.move -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
I don't really mind the move+drive combo, but while we're brainstorming alternatives: maybe you could do something like adding a... state to the controller? Similar to how one toggles continuous mode, just for motor/engine mode of the controller. So we could then change that state, instead of passing it as a parameter. A code example to make it more clear what I mean: local controller = peripheral.wrap(side) controller.setAnchored(true) assert(controller.isAnchored()) controller.move("east") controller.setAnchored(false) if controller.check("west") then print("ok") end Just an idea, not sure if it's the best way to do it, but it would work well with the use cases I can think of - where you normally would work in one mode for multiple moves and not switch the modes all the time. Another consideration would then be what to make the default. I'd opt for unanchored mode. Also, the controller should probably forget this state when broken by the player, to avoid unexpected behavior - i.e. it should always be in the same starting state after being placed. Thoughts? -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Thanks for that! I can confirm that it works. I uploaded the Lua program I used for testing to pastebin if anyone would like to verify. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
And here I was thinking "oh look, it's the Half-Life intro!" Regarding (simple) elevators: I've found continuous mode to be really useful for this. I'm using redlogic, too because the "wiring" would be larger than the platform otherwise. With a lever on board of the carriage, and one line inverted you just have to flip the switch to change direction: Would've used spoilers if I could, sorry... -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
@Maximal: is this using the hotfix version (1.2.0.1)? Also, some images would be nice, the descriptions are rather vague. Finally, could it be you have optifine? -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
It won't return a table, it'll return a tuple, i.e. multiple values (see the Lua documentation for a more in-depth explanation). Currently move() will throw an error if it fails, even the simulation, which is why you have to wrap it with a pcall. The pcall in turn does almost the same thing the new version will do without the pcall: it will return multiple values. The only difference to the returned values will be in the "success" case, where pcall returns (true, true), the first indicating the called function didn't cause an error, the second being the returned value of the called function, and the new move() version will return only true (meaning "whyNot" will be nil -- again: in the case of success). If something goes wrong, move will return the same thing as pcall would now (or almost, depends on how the error is formatted). It may be that if whyNot == "obstructed" we will get some additional values, that being the coordinates, but we'll have to wait and see about that. If we do, you could write something like this Edit: Oh well, that took too long to type up :P -- DISCLAIMER: again, this is all hypothetical until we get the new version local didMove, whyNot, x, y, z = drive.move(direction, anchored) if not didMove then if whyNot == "obstructed" then print(string.format("obstacle at (%d, %d, %d)", x, y, z)) else print(whyNot) end end -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
@Spaceshipable: in short, it means you won't have to worry about move() throwing errors (unless you input bad variables, say wrong types or values, which is something you can control/check before calling the function). Plus it sounds like we'll get an extra function for the movement simulation. So instead of local drive = peripheral.wrap(side) local canMove, whyNot = pcall(drive.move, 0, true, true) you would then write something along these lines local drive = peripheral.wrap(side) local canMove, whyNot = drive.simulate(0, true) which is a lot clearer when reading the code. Note that I don't know what that function will be called, it might well be something else like drive.test (which in hindsight I think would be nicer) or drive.check or whatever. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Awesome, thanks a bunch! -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
That's exactly how it is To grab multiple result values in Lua you just write a, b, c, d = f() which would try to receive 4 return values. If there are more they are discarded, if there are less, the rest of the variables will be set to 'nil'. To avoid others who are only slightly familiar with Lua getting confused, I'd like to clarify that you get the result "without the curly braces" in Lua (those indicate a table in Lua, which is a mix of an array and a map - it has numeric indices for array behavior and arbitrary typed keys for map behavior at the same time). Tuples are not an actual datatype in Lua, they're just a convenient... concept for returning, passing and assigning multiple values at once (you can also write stuff like a, b = b, a for example). -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
I know I'm a little late, but I'd just like to add my 2 cents to the discussion about the Lua API real quick. Sorry in advance for the lengthy post... for the tl;dr skip to the list below. It has already been mentioned that the call can be wrapped with pcall to avoid an error blowing up your whole program, but I'd like to make a small distinction: while Java loves to throw exceptions to indicate whether some operation was successful or not (say, read from a file or stream), as to my knowledge this not very... "Lua-esque" (and bad style IMO, but that's just me disliking Java). In Lua, an error normally means you have a bug in your program, and unless you write something pretty special, it should be fatal. It is an error, not an exception, in Java terms. For example, throwing on invalid parameters, as is done, is a perfect application of this. You should really know what arguments you're passing along, and if they come from some dynamic source (user input) you better validate them! However, what should not throw errors are things that may or may not fail, in this case: all the errors based on where the carriage is in relation to the controller and such things, so basically the ones in Move() and GeneratePackage(), as far as I can tell. Instead, the Lua way is to have a function return a tuple of which the first value indicates whether the operation was performed successfully or not, and the rest represents optional output (results on success, error messages on failure). That tuple is the array of objects you return on the Java side of things. So, in short, I propose the following behavior: throw an exception if the input arguments are invalid, no change here. return new Object[] { true } on success, no change here, either. return new Object[] { false, errorMessage } if the command cannot be executed as desired (so instead of the if (Error != null) throw Error; part something like if (Error != null) return new Object[] {false, Error.toString() }; I guess?). I personally don't feel this would be necessary, but it may be possible to specialize this in case there's an obstruction to return new Object[] { false, errorMessage, x, y, z } to include the coordinates of whatever is blocking the carriage based on the exception type? This would be very consistent with how one writes most other Lua code, for example even something as low-level as pcall does this: it returns (true, retval1, retval2, ...) on success and (false, errorMessage) if the wrapped function threw an error (pcall in Lua is, put simply, what try-catch is in Java). So on the Lua side you'd then write: local drive = peripheral.wrap(side) local success, reason = drive.move(...) if not success then print(reason) -- or whatever end As I said, this is just my humble opinion on this matter, I'm not trying to tell anyone what to do, just hoping it is taken into consideration. Thanks! Long as this post already is... while on the topic of the Lua API, I'd like to bring up just a few tiny ideas The first is probably a matter of preference, but still, I'd regret not mentioning it: I personally think it would be clearer to split the exposed move() function into move() and simulate(), instead of passing that as a parameter. It'd just make the code so much more readable. One can obviously write small wrapper functions for this, but it'd be nice if it were... official. The second is also just a matter of convenience: how about a way of querying the number of blocks a controller is connected to? So you could do peripheral.call(side, "count") or whatever you choose to name it. That would be very helpful when building large "ships", to know how much more you can add (in particular in multiplayer when working with other players). It could return some magical string constant (e.g. "uncountable") when there's too many for the controller to move the frame, to guarantee it never throws (similar to ComputerCraft's turtle.getFuelLevel()). Whether or not these ideas make it in, thanks again for your brilliant (open source ) work! -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Sweet. Some ideas, since you asked 1) Why not use textutils.serialize/unserialize instead of string manipulation for saving your state? I think that would make the code more readable (and be less error-prone). 2) It may be safer to write the state to disk before calling peripheral.call, in case the computer is reset before that returns. Even better: call it in simulation mode first, save if it's OK, then do the actual move. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Sweet, thanks. And right you are; just tested it with the latest version of IC2 (I belatedly realized that there was one available not requiring the latest forge dev build), and the issue ceased to exist. Sorry for the distraction. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
I guess the good old "In theory, theory and practice are the same. In practice, they are not" applies here, then. Looking good, I get no more AE crashes however I try! :) -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
1, 2 and 3 crash with the same error as when both move with the frame. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
I really didn't even think about it, since I had the program running already, so that was the quickest way to check. ^^ Edit: Also, I don't see the sources in the experimental ZIP. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Well, the decompiler tells me the synchronization code is in there, so no idea. Maybe you could attempt something like the turtle movement functions of ComputerCraft do? I.e. just return some ID and process the actual move in the main update thread, then send a ComputerCraft event with that ID and the result as parameters when done (for non-simulated moves only, I guess). I'm talking about the turtle.native.* functions, just for clarity. Just a quick test that went well: triggering an engine using the redstone signal a CC computer emits does not cause a crash. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
1) Very good point. I just built a carriage with every single AE block on it. Turns out this also happens for a couple of other AE blocks. Also crashing in the scenario where the ME Controller crashes are ME Pattern Provider and ME Crafting CPU (both are multiblock parts, just for the record; the other multiblock components are fine, though) and ME Dark Cable. And yes, this only happens when using the Controller, normal Engine/Drive works fine. 2) Yes, happens both with the normal and the experimental version. Normal Engine/Drive movement has yet to cause AE crashes for me. Only have the one with certain blocks attached to IC2 cables in IC2 1.117, as mentioned above. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Sadly the AE crash and IC2 cable oddness still occur. I even rebuilt the test carriages from scratch, just to be on the safe side (and in a different location, too). Right, sorry. Happens as soon as I place the redstone block used to trigger the engine, i.e. I don't see the whole thing move even one pixel before the game shows me the crash report. After reloading the world, the carriage has moved successfully, though. -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
That might well be it. I have not yet been able to reproduce the invalid cast exception in AE nor the IC2 rendering glitches with the drive or engine - and I did quite a few tests Update: something new, again IC2 related. But I'm not sure if you're the one that has to fix it, since this only happens in 1.117, 1.116 works fine. Still, since this only happens when moving carriages... consider this setup, i.e. some block attached to a Platform Carriage via an IC2 Cable (doesn't have to be Glass Fibre, Copper Cable causes the crash, too). Moving the carriage crashes with this log. This only happens for select blocks. Ones that crash are the vanilla Hopper as well as Applied Energistics' Basic Import and Export Buses (possibly others, only tested the basic ones). -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
That's good to know. On that topic: although I wasn't breaking things, I placed them in creative mode. I just double-checked by placing them "legally", and my last post is still valid Another minor thing: you might add multicore chunkloading to the list of evil OptiFine features. At least for me it breaks rendering (when placing/removing blocks). I did not read the through the complete thread, admittedly, but as I didn't see it in the first post I thought it'd be worth mentioning. Oh and: awesome mod! Update: got something else, this time it's IC2 + Carriage Controller related. Consider this setup. Glass Fibre Cable on top of Frame Carriages with a Carriage Controller plus ComputerCraft Computer. Moving the whole thing "towards the frame" (i.e. to the back of the computer) leads to this rendering error. I'm not sure if this is purely visual, since IC2 logs this: 2013-07-11 05:14:32 [WARNING] [iC2] EnergyNet.addTileEntity: ic2.core.block.wiring.TileEntityCable@75b0848e is already added, aborting 2013-07-11 05:14:32 [WARNING] [iC2] EnergyNet.addTileEntity: ic2.core.block.wiring.TileEntityCable@4895bd1 is already added, aborting This only happens when using a Carriage Controller. Using a Carriage Engine or Carriage Drive works fine. Also happens for Copper Cables and Insulated Gold Cables. Tested with IC2 Devbuild 1.116 and 1.117. Didn't try 1.118 because that breaks my game (changelog says something about porting to 1.6.1 so maybe it needs a newer minecraft version, not sure). -
[1.6.x/1.5.x] Redstone In Motion (Redpower Frames) 2.3.0.0 (October 8)
Sangar replied to jakj's topic in Modders Metropolis
Minimal (I think) setup for reproducing this issue every time: http://imgur.com/jm8UNGT Top to bottom, left to right: ME Cable ME Controller Frame Carriage Frame Carriage Carriage Controller ComputerCraft Computer On the Computer run: lua peripheral.call("left", "move", X, false, false) Where X is the direction that is to the right on the screenshot, i.e. towards the computer/controller. Starts moving fine, then crashes when the move finishes. Notes: The cable can be replaced with other ME Blocks as far as I can tell (tested with ME Interface and ME Access Terminal). The Frame Carriage can be replaced with Platform Carriage blocks (tested) and probably other ones (untested). Additional testcase: Remove ME Cabel. Move the carriage as described above. Place an ME Block where the ME Cable would be now (i.e. next to the ME Controller). Game crashes with the same error (invalid cast). I guess this indicates it's not necessarily something happening during the move, but some invalid state left behind after the move.