Screwtape |
Posted on 18-11-17, 02:44 in sr.ht, a new software forge
|
Full mod
Post: #41 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Posted by tomman Technically the service is self-hostable, but like any software designed to scale up to a public internet service, it doesn't scale down very well. The installation instructions mention PostgreSQL, Redis, NGINX, a mail server and a cron server, which is probably not unreasonable for the kind of service we're talking with, but if you're not willing to hire a system administrator to run the thing, maybe you should look at other options. The "make the service profitable" part is actually the part I'm really interested in. As the billing FAQ describes, there are three tiers of payment plans. Every tier gets exactly the same access to exactly the same features, but if you really want to help make the service profitable, you can pay more. That kind of business model usually stumbles because it's really hard to bump people up from the free tier to paying anything at all, but in this case there is no free tier, so I'm feeling optimistic about it. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-18, 10:32 in Games You Played Today REVENGEANCE
|
Full mod
Post: #42 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I backed the kickstarter for Bloodstained: Ritual of the Night, an open-world action-platformer with a gothic-horror theme designed by Koji Igarashi that's legally distinct from Symphony of the Night and other Castlevania games whose intellectual property belongs to Konami. I happened to back at the tier that included beta access, but it was Steam only, which made me sad. Then they added it to GOG too, which made me happy. Then I couldn't download it from the GOG website, then I discovered I could download it with lgogdownloader, then I discovered it wouldn't work in Wine, and then after some Wine updates it *did* work in Wine. I finally got to play the E3 demo I'd seen so many screenshots of, I wryly noted that since the demo first came out they'd made the first boss' breasts *much* smaller, and I was quite pleased to have completed it. Then I noticed the game *hadn't* ended, and I could exit through the right-hand-side of the boss arena to a wholly new area, which turned out to be the game's base of operations (like the town in Dawn of Sorrow, where all the merchants hang out), I got to hear some voiced dialog and found a save room and apparently could make my way forward to the castle proper, and was very excited to continue. Unfortunately, my PC was *also* very excited, and I could hear my CPU and GPU fans screaming and the "CPU overheat" buzzer blaring, so I had to stop playing. So far as I can tell, Bloodstained doesn't have any graphical quality options so I was very sad to think that I might never be able to actually play the game I'd paid for. Today I dug a little deeper, and discovered an undocumented INI file with settings like "sg.ShadowQuality" and "sg.AntiAliasingQuality". They were all set to 3, so I cranked them down to 0, and also set "sg.ResolutionQuality" from 100 down to 50, which I think means it renders at half-size and scales up the result with a bilinear filter? Whatever it is, it doesn't seem to affect UI rendering (thankfully), and although it makes the game look a little worse it also makes my GPU fan much quieter, which is great. As for the actual game, it definitely feels like Castlevania: The Good Parts so far. Mechanically it's much like Dawn of Sorrow, where killing monsters drops consumables and weapons and armour and abilities, and there's a crafting system to combine and upgrade all of those things. I've found secret rooms and bits of the map I can't quite get to and monsters that throw axes at a particular elevation that boomerang back and it all feels really comfortable. If you've played a bunch of Igavania games before, you know what you're in for, and it really seems like they're aiming for a polished game that does all the old familiar things really well, instead of trying to push the envelope. And really, that's pretty much what I wanted, especially after the declining quality and weird gimmicks of the later DS Castlevania games: just show us that you can cover the basics well, and when the inevitable sequel crops up we'll be much more willing to see what crazy stuff you can come up with. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-22, 12:27 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #43 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
In university I learned about shift/reduce parsers with lex and yacc (well, flex and bison), and it made parsing seem like crazy wizardry where you cobbled together a thing and beat on it until it worked and never touched it again for fear of breaking it. A few years ago, I learned about PEG/Packrat parsers, which were much, much nicer to deal with - it's just regular functions calling regular functions, so you can write and understand them like any other program. Well, any other program that does a ton of indirection and recursion. And it's not too difficult to accidentally make your grammar infinitely recursive and get a stack overflow. More recently I learned about Earley parsers, which aren't the most efficient or the most straightforward, but (I'm told) are the most robust. Simple grammars run in linear time, more complex grammars run much slower, but at least they run instead of crashing or getting stuck in an infinite loop. I even heard that they handle ambiguous grammars, and just give you *all* the possible parse trees... but I might have misunderstood. Unfortunately, about the only person on the Internet who's written anything about Earley parsers is a guy who wrote a Perl implementation called Marpa, and almost every discussion I've found on the topic winds up at "Marpa is cool and you should use it" rather than "Here's how to write an Earley parser". Luckily, I found one actual tutorial, and I've been slowly working my way through it. I've been writing software for a couple of decades now, I've done a lot of stuff and I'm confident about being able to tackle anything I come across. But I've mostly been doing the same kinds of things all that time, and eventually I forget what it's like to try something weird and alien. I got most of the way through the first page of the tutorial easily enough, and then I got to a part where the tutorial said "...and obviously our program produces output X" while my program produced output Y, and I had no idea what had gone wrong. Eventually I figured it out and made my way onto the second page of the tutorial, which introduces a new wrinkle to the problem. This time the tutorial said "...our program produces buggy output X", and instead, my program straight up crashes. I have heard it said that the most important skill when learning to program is the ability to imagine what the computer is doing, step by step. I'm sure the second most important skill is the patience to work through ridiculously unhelpful errors. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-26, 10:25 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #44 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I am still plugging away at this. I have gone through the "basic recogniser", "dealing with empty rules" and "dealing with right-recursive rules" sections of the tutorial, and I believe my code all works as it should and gives me linear-time parsing, etc. etc. The first section, the "basic recogniser", went pretty smoothly. The second section, about empty rules, showed up some problems I hadn't noticed in the first section, but after fixing them and carefully considering the tutorial text, I figured it out, and was happy. The third section, about right-recursive rules, was a bit hairy. This time, the tutorial started off basically saying "this is *kind of* how you do this, but it makes life complex and I'm not sure it's a good idea", which was worrying. It described the problem and kind of sketched a solution, which helped a bit but wasn't the guided tour I was hoping for. The tutorial also linked to somebody else's comment on the tutorial, which basically said "don't get confused by the original academic paper, do it eagerly instead of lazily" which didn't help at all since I wanted to be *un-confused*, not to study a confusing academic paper and then study a pithy decryption key. So I tossed all that aside and tried to figure something out from first principles, and after banging my head against the wall for a few hours I finally got something that seems to work. Next up is the fourth section, about turning this cool recogniser into an actual parser. I had a brief read of it this evening, and it doesn't seem like there's anything tricky in this at all. That's good, since it means I don't have to puzzle out subtleties. It's also bad, since it means a bunch of brute-force programming. I'm not even sure what data structures I'll need; the tutorial has a whole bunch of stuff about how to select a parse-tree to return if the grammar is ambiguous... but I didn't pick a parsing algorithm that handles ambiguous grammars to not return a parse forest at the end. I guess we'll see how it goes. I wonder if I'll have to write a literate implementation guide for Earley parsers like I did for suffix arrays. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-27, 11:07 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #45 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I sat down to work on making a parse-tree today, and because I want to work with ambiguous grammars, my first test-case was the good ol' "dangling else" situation:
Does the "else" belong to the first "if" or the second? Properly, it's ambiguous; according to my code it's "Invalid input: got 'else', expected EOF". I pretty quickly figured out why that was happening, but when I fixed it, it broke my "empty rule" handling. I spent a good few hours adding print-statements to my code to figure out what it was doing, trying to look up other Earley parser guides and tutorials to see if they explained things any better, and there might even have been some solitaire games in there somewhere to clear my mind. Eventually I decided that I must have misunderstood a crucial chunk of the tutorial - it explained a crucial idea briefly, in English, and it didn't occur to me there might have been interpretations other than mine. I tried a different approach and then all my test cases passed at the same time. Huzzah! Surely that must be the very last bug in my code, and I'll spend *tomorrow* figuring out parsing. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-28, 05:46 in I have yet to have never seen it all.
|
Full mod
Post: #46 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Posted by james4591 Eh, there's a bunch of Linux distros with official ports for the s390x architecture, including RedHat, Debian, Ubuntu, and SuSE. I can tell you those ports weren't contributed by random weekend hackers with a spare IBM mainframe in their basement. Yeah Blockchain is dead pretty much. Monero is the only real de-centralized cryptocurrency still worth mining. BitMain pretty much has Ethereum, LiteCoin, and BitCoin by the balls. Monero just takes a month or so, even on good hardware, to get even 1 coin mined out. Good news for tomman! The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-29, 05:38 in I have yet to have never seen it all.
|
Full mod
Post: #47 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
The voice-actor for the Emperor of the Universe in the recent Voltron series sings a song from Hamilton. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-11-29, 11:55 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #48 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
> You could say the tutorial was... ambiguous. Ayyyyyup. Long story short, I now have working code that builds a parse tree. Just as I expected, I spent a *long* time scraping away at this, with no particular insights or sudden moments of clarity. It took me a couple of attempts to figure out what the resulting data structures should look like, and then it took even longer to figure out how to fill them in. The nature of an Earley parser is that there's a bunch of phases that the parser goes through for each character, before and after it updates the "current offset", and things are usually filed under the offset in which they completed, but if you do a thing *before* the current offset is updated you might need to file it as though it happened *after* the offset was updated, and does a thing complete on the offset of its last character or the offset *after* the last character, and even if it completes on the offset of the last character maybe you want to *file* it under the following offset to make range arithmetic easier... Basically, it was a rats' nest of off-by-one errors that I had to trace through and understand. I couldn't just hammer at it until it worked, I had to make sure there weren't equal-and-opposite errors cancelling each other out. But it's done now, I got it working and I begin to have faith that maybe I can understand this contraption after all. Now that the tests pass, the next step is to refactor and simplify. I already found a collection field that always had exactly one item in it, so I cleaned it away. There's another compound data-type I'm using in a bunch of different places that should really be its own data-type, so I can hang some methods off it instead of doing the same verbose tickling in a bunch of places. I went through and marked as "private" all the things I could, so the auto-generated documentation is very clean and focussed, which I like. So, yeah, next up: cleaning and tidying and polishing, before I start building the next crazy new thing on top. I'm looking forward to it really, since it won't require deep thinking. I can just make a change, re-run the tests, and if they fail, undo and try something else. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-01, 06:43 in Games You Played Today REVENGEANCE
|
Full mod
Post: #49 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Posted by CaptainJistuce That's what the thread's for, bring it on! ---- I finally finished the the Bloodstained Backer Beta today. Compared to the previous Igavanias I've played (specifically the GBA games), it seems pretty much on-par with Aria... which is to say, it's not too difficult, as long as you're OK with dodging enemies and running past them occasionally, especially while you're lower-level. That was up until I met the second boss. Where the first boss was mostly spectacle, the second boss actually required me to notice attack patterns and dodge to a safe place well in advance of the attack going off... preferably a safe place within melee striking distance. I probably handicapped myself a bit by picking the slowest, heaviest weapon I had, but I didn't have the patience to chip away at a boss with no visible HP bar Anyway, I got to that second boss a week ago, and tried for maybe half an hour to beat it up, with no observable progress. I tried again today, took a bit more care and discovered the boss has a second form (because of course it does). Cheered by my progress, I kept trying and eventually I beat him, the screen faded to white, and apparently I beat the demo in an hour and fifty minutes. I'm really eager to see the full game now, though. Maybe it's finally time to try out SotN in earnest? Also, a fun trick for doing damage with that slow, over-the-head swing: run toward the target, hit the attack button, *then* jump if necessary, and hopefully you'll reach the target before the animation ends, and deal your damage. Then immediately attack again, and now the target's within range you'll do damage at the *start* of the animation. Once you get the timing down right, and as long as you're in an area of the castle where enemies die in two hits, you can still get around pretty quickly even with a slow weapon. It certainly beats the heck out of dancing around every bone-throwing skeleton... I mean, uh, Morte Bone. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-01, 23:43 in Games You Played Today REVENGEANCE
|
Full mod
Post: #50 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Posted by BearOso Is that just hitting backdash while the attack animation plays? Posted by Covarr That's the one with the weird playing-card-based magic system, right? I don't have a lot of strong memories of it, aside from that part where two paths open up and one is much, much higher-level than the other, and the first "you must have item X to progress" lock is quite a ways in. Guess which one I picked and tried to get through, suddenly surprised at the intense difficulty spike? I think Harmony was my favourite so far; it was definitely the easiest of the three, and weirdly garish (like the original NES games, in some ways), but even if the monsters weren't lethal, it was harder to get through a room unscathed. The level-designers seemed to have a knack for putting monsters in hard-to-reach places, or choosing monsters whose movement was a good match for the terrain, or deploying groups of monsters whose strengths made up for each other's weaknesses. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-02, 21:30 in Something about cheese!
|
Full mod
Post: #51 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Posted by Covarr There's this thing where humans like to use social pressure to enforce social norms. If somebody is flagrantly violating a social norm, there's an escalation of responses until the violation stops. Often that escalation is along the lines of: funny looks, dirty looks, grumbling, telling off, yelling, and physical violence. This works pretty well for social norms like "stand to the side of the escalator if you're not going to keep walking", but less well for social norms that involve a rational or moral component. I imagine there's a lot of people whose views on immigration don't come from economic or moral argument, but have been learned from the people they grew up with. "When I was a kid, I saw somebody hassling an immigrant, and all the grown-ups around me gave that guy dirty looks and grumbled, so I understand that hassling immigrants is violating a social norm, and I should enforce it the same way". When somebody comes along with an anti-immigration argument, they are by definition violating a social norm, and if they don't stop they're going to get yelled at, even if their argument is sensible. (rewriting that last paragraph to describe the anti-immigration viewpoint is left as an exercise for the reader) It seems to me that America really needs to have a sensible, level-headed discussion of immigration (among other things) that's not filled with subtle "I'm clearly in the right and those guys are clearly chumps" jabs, but that's always going to be really, really difficult while there are so many people who only understand the subject in terms of social norms. As an aside, I'd like to thank RetroUnknown/james4591 for posting their viewpoint here. Because of the whole social norms thing, it's rare to find anybody talking about their actual experiences, mostly you just get yelling. I found it very educational to hear about what you'd seen in a rural community and what issues you're worried about. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-06, 06:56 in NSF/SPC to MIDI automated converter project
|
Full mod
Post: #52 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
But the SPC file-format only provides initial registers and RAM content for the SPC, it doesn't give the CPU anything to do. So what should an SPC-player do? The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-07, 11:55 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #53 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
It turns out I do not have working code that builds a parse tree. Or rather, it *generally* builds a parse tree, but there's a specific case where things break. In the tutorial I linked, the page "Optimizing Right Recursion" describes an algorithm whose logic is approximately "keeping track of all the details is expensive, so we'll just remember the big picture". Turns out, that's fine if you just need to recognise whether an input matches a grammar, but if you want to reconstruct the parse tree (as I do) then you legitimately *do* need all those details. Apparently this right-recursion optimisation is an important part of the Earley/Marpa algorithm's big-O performance guarantees, so I don't want to toss it. On the other hand, I can't really say I support grammars with right-recursion if they just mysteriously fail. I think maybe it's time to email the guy who wrote the tutorial and ask for further illumination. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-07, 23:52 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #54 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Recursive descent (PEG, combinator) parsers have problems with left-recursion because they're eager: they immediately try the first option and backtrack if it didn't work out. However, Earley parsers are lazy: they keep matching incoming tokens against grammar rules, ruling out possibilities as they go, and don't actually need to do much of anything until they find a complete rule. As a result, when a rule does complete, it can trigger an avalanche of completions. This right-recursion optimisation works by skipping over all the intermediate stages of the avalanche and going right to the top... but thoes intermediate stages still need to be part of the parse tree, so I'm a bit stuck. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-08, 02:42 in Monocultures in Linux and browsers (formerly "Windows 10") (revision 1)
|
Full mod
Post: #55 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
Mozilla's market-share has been sliding downward for a long time, and they've been chasing Chrome for a long time, but correlation is not causation. If Mozilla had avoided copying Chrome and had stuck with their previous plan of copying IE6, or their even older plan of copying Netscape 4, maybe they would have been doomed even more quickly—at this point, we can't know. Mozilla's goal has never been to make a "good" browser; there have been many good browsers over the years that didn't amount to much of anything (hi, Opera!). Mozilla's goal has always been "to ensure the Internet is a global public resource, open and accessible to all". One of the best ways to do that is to have a non-ignorable chunk of market share, one of the best ways to do that is to build a popular browser, and building a good browser is useful but not necessary or sufficient to become popular. Mozilla has the advantage of being (associated with) a non-profit, and a good reputation, and they have used those advantages well, but when you're up against the sheer marketing muscle of the world's largest advertising company, it's never going to be a fair fight. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-10, 10:18 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #57 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I mentioned Earley parsing on Lobsters the other day, and somebody replied with a link to a parsing tutorial of their own. It's less wordy than the first one I tried, but it comes with automatically tested code in Python which I'm much more familiar with: and best of all, it actually acknowledges that the problem I'm facing exists and provides a worked solution! Unfortunately, things are never simple: - The Earley algorithm keeps track of things by their end-offset, so when the parse is done it's natural to start at the end and work your way back to the beginning. However, both tutorials I've seen devote a lot of effort to re-indexing all the parse data by its start offset because it's "less confusing". I'm not confused by the Earley model, but I *am* confused when I try to convert "just do X, Y and Z' instructions to my inverted frame of reference - Pulling a parse tree out of the Early working data involves finding and stitching together the few relevant fragments. The tutorials I've seen seem to run through the input and then as a second phase wade through the results for the interesting bits, but it seems to me you can recognise the interesting bits as and when they occur, so why not build the parse-tree as you go? Unfortunately, this makes it very hard to map concepts from the tutorials onto my code-base. After staring at this new tutorial for a while and digging around, I eventually came up with a simple solution that fixed my broken test-case. I wasn't sure it was completely correct or preserved the linear-time property, but "seems to be working" always feels a lot better than "definitely broken". The new tutorial also came with some extra examples and test-cases, so I added those to my test suite... and they broke. In fact, if I comment out the whole "optimization" entirely (which should be safe since optimizations shouldn't affect correctness), one of my original test-cases is still broken. It's 9PM and I'm too tired to think any more tonight, but at least I'll have actual reproducible problems to dig into tomorrow. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-11, 06:29 in I keep forgetting how hard it is to learn new things
|
Full mod
Post: #58 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I hadn't thought of it that way, but after looking into it more closely, I believe you're right. The core idea of yacc/bison parsing is shift vs. reduce, the core idea of PEG parsing is recursive descent, but the core of Earley parsing is a soup of parse-rules in progress whose convection is fuelled by the arrival of new tokens. One of the most basic things about rule-soup is that the rules are unordered, and although the algorithm will advance all the relevant rules eventually, there's no guarantee that they'll show up "in document order" as the HTML specifications say. I still think it's a good idea to collect completed rules into a separate data structure as they're found, instead of rummaging in the soup for them afterward. HOWEVER, I had assumed that when a rule was completed all its symbols would already be completed, and that is not true. All its symbols will be completed before we receive the next token, but they might not be completed yet. Now that I think back, I've been bitten by this assumption a couple of times already, but I just assumed it was an implementation flaw, rather than a design flaw. So I need a new approach: collect completed rules as they occur into a separate data structure, but don't try to impose any structure. When parsing is complete, we can assume all the completed rules have arrived, and we can build our parse tree in one go. And *if* we're going to stuck completed rules into a separate data structure, we might as well index them by starting offset rather than ending offset... And thus I wind up at the same approach everybody told me to use, except that now I understand why it's important. Now to try and implement it, and see what my original problem looks like by the time I work my way back to it... The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-11, 11:21 in How the Dreamcast copy protection was defeated
|
Full mod
Post: #59 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
http://fabiensanglard.net/dreamcast_hacking/It turned out that the scrambler was nothing more than "security through obscurity". The SDK contained a reverse-scrambler which transformed a valid executable into reverse-mashed-potatoes so it would be valid again when loaded and scrambled by the Dreamcast when booting from a CD-ROM. As an aside, it looks like the ".gdi" metafile used for Dreamcast images is vastly more sane than the .cue metafile used by everything else these days. Another tally-mark for worse-is-better, I guess. The ending of the words is ALMSIVI. |
Screwtape |
Posted on 18-12-12, 05:12 in How the Dreamcast copy protection was defeated
|
Full mod
Post: #60 of 443 Since: 10-30-18 Last post: 1101 days Last view: 172 days |
I was pretty impressed with the Playstation anti-circumvention tech when I understood it, encoding a signal into the "track wobble" that CDs use to maintain constant linear velocity, but of course that wasn't the weak link in the chain. Somebody just recorded that signal and made a chip that played it back, The ending of the words is ALMSIVI. |