Archive for May, 2018

Foxybot Enhancements Part 4: Slicing Off The Tip

Thursday, May 31st, 2018

Ok, so I’m walking the earth, takin' names an makin' claims. There’s a rhythm to it. I get one scroll, I use one scroll. So long as nothing breaks my stride I’ve got no problems.

However, on occasion something comes up. Target selection is improved but it’s not perfect. Maybe I target a spent marker and try to build again. It fails and I move on, with naught but 15 seconds wasted and an extra scroll in my pack. Not a big deal really. Like swallowing a kernel of corn without chewing: you don’t even know it until you look at what comes out in the end. (And then, you know, you flush it, you don’t re-eat it!)

Except in this case that kernel of corn is a ticking time bomb that’s going to go off as soon as you try to build a different type of claim. Because as it turns out, that extra scroll (or scrolls) is equipped. When Foxybot tries to equip the new type of scroll it fails and Foxybot doesn’t realize it. It then tries to build the claim which succeeds in producing a bundle of the old type which you still have in mind, but fails to build the claim.

Now you’re going to have an accumulating abundance of bundles instead of the resources you’re actually after. That old scroll is stuck up in there and it’s no joke. Lets have a look at the code.

if (!worldHandler::IsInBrain(scrollName))
        if (!worldHandler::EquipRecipe(scrollName))   (1)
                        OutputMsg(csString("Missing blueprint for the claim!"));
                        //noBuild = true;
            return false;

1 Location of equip attempt

This is part of ExploreActivity::DoBuild() and, in the case where the proper scroll is not already equipped, it’s calling worldHandler::EquipRecipe(). If these sounds familiar it could be because we’ve looked at them before. Now it’s time for another look. Here’s how we left EquipRecipe() last time:

bool worldHandler::EquipRecipe(csString itemName)
	psInventoryCache::CachedItemDescription* slot = FindItemSlot(itemName, true);
	if (slot == NULL)
		return false;

	//if (slot->containerID != CONTAINER_INVENTORY_EQUIPMENT) //equip only if truly needed
		MoveItems(slot->containerID, slot->slot, CONTAINER_INVENTORY_EQUIPMENT, PSCHARACTER_SLOT_MIND, slot->stackCount);

	return true;

If you take a close look at that code listing, you’ll see that the only case where it returns false is when the a source slot containing the needed scroll is not found. After that it returns true after the move attempt regardless of success. This explains why Foxybot doesn’t notice the failure.

Well, we know from the prior listing that this code is only called when the proper scroll is not already equipped. So lets add a check to see if there is anything in there and, if so, remove it.

bool worldHandler::EquipRecipe(csString itemName)
+      	if (GetBrainItemName() != "") (1)
+	{
+		Dequip(GetBrainItemName()); (2)
+	}
	psInventoryCache::CachedItemDescription* slot = FindItemSlot(itemName, true);
	if (slot == NULL)
		return false;

	//if (slot->containerID != CONTAINER_INVENTORY_EQUIPMENT) //equip only if truly needed
		MoveItems(slot->containerID, slot->slot, CONTAINER_INVENTORY_EQUIPMENT, PSCHARACTER_SLOT_MIND, slot->stackCount);

	return true;

1 If she’s cramping your style
2 Show her the door

What’s meant to happen now is equipped scrolls get removed before attempting to equip a new kind. However, if you run this, you’ll actually find that nothing appears to happen differently at all. Further investigation shows that eventually, down the call chain, InventoryWindow::Dequip gets called to grunt through each inventory slot in search of a match.

pawsSlot* fromSlot = NULL;
// See if we can find the item in the equipment slots.
for ( size_t z = 0; z < equipmentSlots.GetSize(); z++ )
    if ( equipmentSlots[z] && !equipmentSlots[z]->IsEmpty() )
        csString tip(equipmentSlots[z]->GetToolTip()); (1)
        if ( tip.CompareNoCase(itemName) )
            fromSlot = equipmentSlots[z];

1 Enter: the tip

So what’s that doing? It’s looping through all the equipment slots and if there is something in there, it’s comparing the tool tip of that thing to the name of the item you’re trying to dequip. In our case it’s never finding a match and so Dequip() never finds what to dequip.

Funny thing, that tool tip seems to come with its very own leading space character. So the values are never equal because of that extra space on the front. Let’s give that tip a snip.

pawsSlot* fromSlot = NULL;
// See if we can find the item in the equipment slots.
for ( size_t z = 0; z < equipmentSlots.GetSize(); z++ )
    if ( equipmentSlots[z] && !equipmentSlots[z]->IsEmpty() )
-       csString tip(equipmentSlots[z]->GetToolTip());
+       csString tip(equipmentSlots[z]->GetToolTip().trim());
        if ( tip.CompareNoCase(itemName) )
            fromSlot = equipmentSlots[z];

Bang! There you go. Improper scrolls are now removed as needed; fresh, crisp scrolls are equipped in their place; un-chewed corn passes without incident, and you no longer have to walk around with old ideas stuck in your head.

You’re welcome.

Diana Coman - 2018-05-31 20:38:23

Nice catch that extra space on the tooltip, I had no idea!

(Initially a move to an occupied slot would just swap but like pretty much everything else in Eulora, it…​ changed.)

Mocky - 2018-06-01 04:02:31

Yeah, it’s like an archeology dig into Eulora’s past, in the sense of inferring how this used to work from looking at the code.

Foxybot Enhancements Part 3: Getting Into Trouble And Back Out

Thursday, May 24th, 2018

Running around exploring various areas, I discovered it’s possible to get into some trouble. Trouble specifically of the 'sail off the edge of the map' variety. In this case there were not dragons there, but there was a lot of falling and more than a few clouds.

I was offered a helpful suggestion to pull myself up by my own bootstraps in a way I hadn’t even considered. In this case, to just change the y coordinate for your avatar.

I had a look around in the code for an appropriate place to do that. After some trial and error I discovered that changes to y alone wern’t going to be enough in this case; I needed a little x and z. Just enough to get my feet back on solid ground. Well, I already knew of one place where I had been typing in coodinates and that was 'Foxy’s autopilot', so I decided to piggy back on that command.

Autopilot works like this: you punch in some coordinates and it faces you in that direction. For example, on occasion, to face toward the trainer, I had been entering:

/pilot 40 0 312

The three parameters are x, y and z. I added a couple lines at the bottom of the existing code to enable a new and optional 4th parameter, the word 'move'.

else if(words[0] == "/pilot")	//point character in the direction of the given coordinates
        if (words.GetCount() < 4)
                return "Usage: /pilot x y z";

        csVector3 currPos;
        csVector3 gotoPos = csVector3(words.GetFloat(1), words.GetFloat(2), words.GetFloat(3));
        float yRot;
        iSector *sector;
        psengine->GetCelClient()->GetMainPlayer()->GetLastPosition(currPos, yRot, sector);
        csVector3 diff = gotoPos - currPos;
        float targetYRot = atan2(-diff.x,-diff.z);

        psengine->GetCelClient()->GetMainPlayer()->Rotate(0, targetYRot, 0);
+       csString s;
+       words.GetString(4, s);
+       if (s.CompareNoCase(csString("move"))) {
+               psengine->GetCelClient()->GetMainPlayer()->SetPosition(gotoPos, 0, sector);
+       }
        return "Foxy's autopilot done.";

When you pass in 'move' as 4th parameter, the client not only faces you in that dirction, but then also moves you to that location. Using this mechanism I was able to nudge myself in the right direction, and back onto the map.

Log Reference: Why Ada

Monday, May 21st, 2018

Why Use Ada For Critical Code

This page is a listing of all known "Why ada" log threads to date (2018-05-21). A summary list of the reasons is provided at the top.


  • Bounds checked

    • Bounds checked arrays and array slices

    • Hardwareizeable bounds checking

  • Standardized

    • Well specified in a written standard

    • Standardized stdlib

    • Standardized threading mechanism

    • Standardized scheduler

    • The level of completion allows the writing of whole systems using the language as described in the standard.

  • Brain damage not forced upon user

    • No Promiscuous Cast

    • Can eliminate promiscous pointers

    • Can Eliminate Buffer overflows

    • Type Safe

    • Deterministic memory usage

    • Static Memory Alloc

    • Integers not presumed machine words

    • Strict Conformance Enforced on Whole Program

  • Provides 'Rationale Manual' for every aspect of language

  • Compact binaries - the binaries are compact enough to run on small chips. It does not require the inclusion of a runtime.

  • Auditable binaries - with a corespondence between lines of code and physical machine

  • Non-proprietary

  • Native compiler for major cpu archs

  • No GC

  • Predicated Types

  • Links with C Code

  • Statically Compiled

Log References

Well Specified, Strict


asciilifeform: if i could fork myself, i'd be severely tempted to: attempt an
ada bitcoind.
thestringpuller: mircea_popescu: re: could you imaginge if Gavin was magically
replaced by ryanxcharles?
mircea_popescu: i'd have thoughjt a cl bitcoind
mircea_popescu: or for that matter a c bitcoind (as opposed to cpp)
thestringpuller: the original qt uses MFC stuff
thestringpuller: Satoshi sure did like windows.
mircea_popescu: i suspect ti's a case very close to the ida situation
asciilifeform was deploring last week
mircea_popescu: we're so fucking lucky satoshi wasn't any good with code.
asciilifeform: i suspect that mircea_popescu would actually like ada. not
writing it, mind you, but seeing it written?
BingoBoingo: !b 2 ?
assbot: Last 2 lines bashed and pending review. (
mircea_popescu: i'm not entirely unfamiliar.
mircea_popescu: !s ada from:mircea
assbot: 1 results for 'ada from:mircea' :
asciilifeform: naggum's -other- lang. the only one other than cl that had not
only a standard but a -rationale document- for every page
mircea_popescu: hm.
mircea_popescu: i thought i musta mentioned it
asciilifeform: still used for genuinely safety-critical systems worldwide
(virtually all jet engine controllers, etc.) - language from hell, required you
to specify ranges for integers, and the like
mircea_popescu: uh. what typed language doesn't ?!
asciilifeform: i confess that i rather like it...
mircea_popescu: going int blabla; says : blabla between 0 and 65535 or w/e
asciilifeform: nononono - explicitly.
mircea_popescu: listen, everything in a program is explicit. whethr the user is
aware or not of this...
mircea_popescu: no means yes. yes means anal. it's how computiong works.
asciilifeform: as in 'this one is odd and between 3 and 15 and if it ever
isn't, pump in the halon
mircea_popescu: not that i disagree with the principle of making people
verbalize the stuff they're abotu to do.
asciilifeform: << examples
assbot: Ada Programs ... ( )
assbot: [MPEX] [S.MPOE] 34100 @ 0.00042927 = 14.6381 BTC [+]
asciilifeform: ugly, pascal-like, but extraordinarily well-specified and strict
to the point of bdsm

Standardized, No Runtime, Can Eliminate Buffer overflows, Standardized in its

entirety 2015-02-16

asciilifeform: re: gnat: 4.6.4 builds but actually attempting to use yields
'gnatgcc: fatal error: -fuse-linker-plugin, but not found'
asciilifeform: ^ does anyone other than me care
asciilifeform: if not about gnat, the overall state of decay.
decimation: asciilifeform: what are you trying to compile that is written in
asciilifeform: 'hello world'
decimation: heh
BingoBoingo: about decay yes. WFT "fix" was important enough to kill this
asciilifeform: who wants to laugh, but there are precisely two programming
languages in existence which are 1) standardized and 2) you can -actually write
complete systems- using -the language described in the standard-
asciilifeform: two and only two.
mircea_popescu: ada and lisp ?
asciilifeform: common lisp
asciilifeform: and yes - ada.
decimation: asciilifeform: even usg has abandoned ada
decimation: but not because it failed to serve a purpose
asciilifeform: (pet peeve of mine - 'lisp' (or worse, the '60s-ism LISP) is a
hopelessly nonspecific term that encompasses languages that differ from one
another far more even than 'algol' differs from 'c')
asciilifeform: decimation: usg, interestingly, did not entirely abandon. but
under pressure from microshit (primarily) relaxed the ancient laws
asciilifeform: avionics, power plant controls, the like - systems whose failure
reliably produces piles of corpses and messy 'pr' - are still very heavy on ada.
BingoBoingo: Also sun when they were monied enough to bezzel up Java
decimation: presumably they do not use gcc
assbot: [MPEX] [S.MPOE] 49000 @ 0.0004195 = 20.5555 BTC [+]
asciilifeform: decimation: actually - they do
decimation: heh
asciilifeform: or rather, the ada component of gcc is based on the ancient
usg-commissioned thing
asciilifeform: an ancient usg
decimation: I doubt they use x86 for such purposes either
asciilifeform: thing is mainly architecture-agnostic, interestingly
asciilifeform: (no big surprise to folks accustomed to gcc)
BingoBoingo: ^ most good things are architecture agnostic
asciilifeform: i advise folks to learn enough ada to understand why something
quite like it is necessary.
asciilifeform: it is more or less the antithesis of the 'hip language'
asciilifeform: in being tremendously unpleasant to work in
decimation: the problem is that many of the promises of ada cannot be kept by
the underlying hardware
assbot: [HAVELOCK] [AMHASH1] 2450 @ 0.0007311 = 1.7912 BTC [-] {18}
asciilifeform: situation today is that most folks would not even notice a
promise broken by hardware
asciilifeform: because it can be reliably blamed on softs.
asciilifeform: you more or less have to present a smoking cratered cpu to make
others believe in 'it was the hardware'
decimation: yeah that's a good point
asciilifeform: there are interesting things to be learned from the ada
approach, if you can pinch your nose and get past the 'ick factor'
asciilifeform: for instance, all error messages refer to a page in the
rationale book
asciilifeform: (in traditional implementations)
asciilifeform: buffer overflows, pointer fandango, etc. - are impossible
asciilifeform: ^ without requiring a bulky 'runtime'
TheNewDeal: ;;Later tell TomServo sorry I missed you last evening. Went out for
some drinks and left my irc on. Will be back thursday evening
gribble: The operation succeeded.
asciilifeform: just what the doctor ordered for proggys whose behaviour (and
error modes) must follow rigorous spec, or user - dies.

Standardized in its entirety, Non-proprietary, Provides 'Rationale Manual' for

every aspect of language 2015-02-18

decimation: asciilifeform: that was a neat link about ada
decimation: I wasn't aware that it was still going strong in non-defense areas
asciilifeform: i've learned that there is not actually a good substitute for
ada, as of yet.
asciilifeform: as in, something that actually provides the same functionality
asciilifeform: without the 'bondage & discipline' stylistic aspects
decimation: the trouble is that it seems the real toolchains used by these
projects are all $$$ commercial
asciilifeform: nope.
asciilifeform: gnat is both widely used and gpl
asciilifeform: (one of the conditions for the ancient usg mandate establishing
ada 'foundation' is that the product must be gpl'ed)
decimation: I guess the difference is the 'usg certificate'
asciilifeform: the certificate has nothing to do with ada per se
[]bot: Bet created: "BTC to top $500 before 1st May"
asciilifeform: and is a separate racket
assbot: [MPEX] [S.MPOE] 47900 @ 0.0004491 = 21.5119 BTC [+] {2}
asciilifeform: for which the chumps, yes, pay
decimation: no it's the real time os I think
asciilifeform: at any rate, all of the 'standard library' is public
asciilifeform: and (iirc) lgpl
asciilifeform: there are proprietary ada systems, yes. i have not been able to
learn who uses them, and for what.
asciilifeform: but this being one of the only two programming languages in
existence which are -standardized in their entirety-, in principle there is no
reason - aside from retardation - to use a proprietary ada
asciilifeform: - actually - i can think of one
asciilifeform: gnat/gcc lacks support for some of the more exotic chips used
asciilifeform: 'MIL-STD-1750A' etc.
asciilifeform: ^ yes - actual cpu!
decimation: << "For these
projects, Honeywell purchased DDC-I, Inc.'s Ada Compiler System, using it as
the front-end source for Honeywell's symbolic debugger. "
assbot: The Boeing 777 Flies on 99.9% Ada ... ( )
[]bot: Bet placed: 1 BTC for Yes on "BTC to top $500 before 1st May" Odds: 94(Y):6(N) by coin, 94(Y):6(N) by weight.
Total bet: 1.1 BTC. Current weight: 99,996.
decimation: asciilifeform: you can probably get access to mil-std's
asciilifeform: considering that the sole remaining makers of the product
described in that one are chinese...
asciilifeform: not so hard
asciilifeform: at any rate, all of the ada-related material is thoroughly public
asciilifeform: and guess which are the only two programming languages to have
'rationale manuals' for every aspect of the language ?
asciilifeform: i can sorta see why naggum went in for ada
decimation: "23-Jan-2015                        MILITARY STANDARD
Sixteen-Bit Computer Instruction Set ArchitectureMIL-STD-1750A, dated
12-Apr-2010, remains inactive for newdesign; however, the document is valid for
asciilifeform: it's a kind of 'polar opposite' of common lisp..
decimation: wouldn't you put it in the 'algol' family?
asciilifeform: decimation: that's traditional notation for a standard that no
longer has a working group but has not been retracted
asciilifeform: decimation: definitely. more specifically, pascal-likes.
asciilifeform: (ada is quite like a more 'fascist' incarnation of pascal)
asciilifeform: phun phact:
asciilifeform: quite a few usg-sponsored war projects are still -struggling to
modernize to ada-
asciilifeform: and making use of 1970s-era monstrosities (e.g., 'JOVIAL')

Standardized to Completion


asciilifeform: interestingly, even though ianal, i do so enjoy a good hardcopy
iso standard (that describes something useful, naturally)
asciilifeform: just got 'ada 95: the language, reference manual, and standard
libraries' ansi/iso/iec-8652:1995 in the post?
asciilifeform: and it's a work of art
asciilifeform: the pages are numbered like a bible's
asciilifeform: with paragraph indices
asciilifeform: for citing 'chapter & verse' at n00bs
thestringpuller: !up The20YearIRCloud
asciilifeform: and the thing has totality, even more so than common lisp - even
character sets are included in the standard
asciilifeform: as in, you can actually program without thinking about any
building block that isn't in the book...
asciilifeform: the down side is that you get to essentially write in pascal
asciilifeform: (the similarity is more than skin deep)

Brain Damage not forced Upon User


decimation: asciilifeform: unfortunately ada (derived from pascal-algol) has
1-based array indexes
assbot: [MPEX] [S.MPOE] 15186 @ 0.00040757 = 6.1894 BTC [+]
asciilifeform: decimation: foo: array (Integer range 0 .. N) of Whatever;
asciilifeform: decimation: so nope.
asciilifeform: at least, not if you don't want.
decimation: ah that's useful
decimation: all the examples I've found start with a 1
asciilifeform: can start with 31337 if you like.
decimation: I assumed it was a language 'feature' like matlab
decimation: matlab 1-based indexing is enraging
asciilifeform: ada, like common lisp, is interesting for the mostly-complete
absence of any obviously braindamaged decisions forced upon the user



asciilifeform: do any of you feel up to the task of ada-izing this ?
asciilifeform: until this happens, we're playing 'underhanded c contest'
BingoBoingo: <asciilifeform> put'em on separate continents. << Hard part is not
cloning the hardware. It is cloning the history and software.?
asciilifeform: BingoBoingo: we're talking about the classical fictional clones,
naturally, rather than the boring younger twin brother kind
BingoBoingo: Ah
mats: asciilifeform: i may be able to wrangle some time on a cluster if you're
interested in doing a batch job
mats: would be a good stop-gap until jurov gets going
asciilifeform: mats: i am specifically not interested in shuttling crud back &
asciilifeform: have plenty of cpu here at home
asciilifeform: but want to push button and forget again.
mats: ok
punkman: asciilifeform: I wonder how much extra code we'll need to make
microecc (or whatever else) parse/verify all the different crap already in
assbot: The FCC approves strong net neutrality rules - The Washington Post ...
( )
asciilifeform: punkman: that is clearly part of the puzzle
punkman: I'd be interested in learning Ada (or other language), but damn that's
some gnarly syntax
BingoBoingo has build against LibreSSL 2.0 syncing, 9 days of history left, no
wedge blocks
asciilifeform: punkman: get the 'rationale' book. every piece of 'gnarl' is
justified, and the justification reads like your local fire code - every line
is likely there because of a corpse
punkman: I don't think we have fire code :P punkman: asciilifeform: should I be looking at ada 2012 flavour?
asciilifeform: punkman: 2005 or better yet 95
asciilifeform: none of the post-95 features are likely to be usable on a
bare-metal build
asciilifeform: (they require the runtime libs)
asciilifeform: while the original 1983 standard had warts that were fixed in 95
punkman: handy table
assbot: Ada 2012 : Ada Comparison Chart ... ( )

Standardized, safe types, deterministic memory usage, extant compiler backends

for major cpu archs 2015-03-04

adlai: asciilifeform: any particular reason for your love of ada, specifically?
asciilifeform: (yes, let's call things by their true names - sabotage)
asciilifeform: adlai: i'd love to learn of a substitute for ada
decimation: asciilifeform: well, this is a general problem in C programming -
the failure to provide a global namespace
decimation: "no, I want the writef() that does the stuff, not the writef() that
displays singing monkeys"
asciilifeform: that is, a hard-standardized (iso preferred) prog. lang. with
safe types and deterministic memory usage, that has extant compiler back-ends
for all major cpu architectures
asciilifeform: and is happy with, e.g., 64k of total machine ram
asciilifeform: ^ ocaml, say, is right out
asciilifeform: ditto erlang
asciilifeform: ada's the only game in town for this not-uncommon set of
decimation: asciilifeform: also it's probably never going to attract hipsters
asciilifeform: in much the same way that mpex is the only game in town in its
asciilifeform: i don't give a flying fuck either way about the hipsters

Type Safe, Bounds Checked, Standardized, No GC, Static Memory Alloc


thestringpuller: asciilifeform: so brought up ADA at work, and coworker started
having Vietnam-esque flashbacks from school. Is this normal behavior?
asciilifeform: thestringpuller: absolutely
asciilifeform: thestringpuller: try 'scheme' on him
asciilifeform: never fails to bring back 'vietnam'
PeterL: and this is what you want people to use?
thestringpuller: this compels me to learn the language more.
asciilifeform: PeterL: life-critical embedded systems must be written in a
typesafe, bound-safe standardized language with hard-real time run (that means
no garbage collection) and static memory alloc.
asciilifeform: PeterL: there is precisely one such language in existence.
BingoBoingo: !up qntranet
BingoBoingo: Hello visitor
asciilifeform: PeterL: it's ugly as sin, and originally usg-promulgated, but
that doesn't change the facts.
PeterL: could we make a prettier version?
asciilifeform: PeterL: sure, go make. we'll check again in 50 yrs.
PeterL: ok, I'll get right on that
asciilifeform: PeterL: but you'll find that much of what programmers actually
object to in ada is precisely the good parts?
PeterL: what part do you find ugly?
asciilifeform: 'it's not sexy. whaddayamean i have to specify thing'
BingoBoingo: !b 7 ?
assbot: Last 7 lines bashed and pending review. (
asciilifeform: PeterL: the pascal syntax mostly
asciilifeform: but even it contributes to the actual purpose of the thing.
assbot: [MPEX] [S.MPOE] 3950 @ 0.00037468 = 1.48 BTC [-]
asciilifeform: which is safety and nonambiguity at any cost.
PeterL: in my initial introduction to ada, it seems verbose, with extra words
hanging around where a symbol could work just fine
asciilifeform: that's just about everybody's first impression
asciilifeform: then you actually read a book and try to think of which
'verbosity' could be cut
asciilifeform: and find that you are actually snipping off a living organ and
not dead weight.
asciilifeform: there is even a 'rationale' document (also book) ready to argue
with you?
jurov: << some samples
assbot: Ada Programs ... ( )
asciilifeform: it's numbered like a bible - for folks to quote chapter & verse.
PeterL: well, it has the same named closing tags like you complain about in
html (begin thing ... end thing)
asciilifeform: PeterL: has many things that feel 'heavy'
asciilifeform: but the result adds up to the fact that there will never, ever
be an 'underhanded ada contest'
PeterL: programs should be boringly obvious what they are doing?
asciilifeform: precisely.

Standardized stdlib, Standardized threading Mechanism, Standardized Scheduler


ben_vulpes:  << how so???
assbot: Logged on 10-04-2015 01:04:50; asciilifeform: because it declares war
on microshit and unix, 'a pox on both their houses'
mike_c: (as i patiently wait for cardano)
ascii_field: ben_vulpes: it carries own stdlib
ascii_field: ben_vulpes: and even has own threading mechanism, scheduler.
assbot: [MPEX] [S.MPOE] 100300 @ 0.00028657 = 28.743 BTC [+]
ascii_field: ben_vulpes: as a result, it is actually much easier to - usably -
plant ada on 'bare metal' (sans os) than nearly anything else

Type Safe, Bounds Checked, Sane Error Handling (undefined?), Standardized,

Multiple Native Compilers 2015-09-20

asciilifeform has been recently carrying out a kind of survey of programming
systems ~built for adults~. so far, nominees: common lisp, ada, standard ml.
and that's ~it~
asciilifeform: rough and non-exhaustive summary of what 'for adults' means:
asciilifeform: 1) type safety 2) MULTIPLE independent implementations 3) at
least two NATIVE compilers exist 4) written international standard, preferably
published on dead tree
asciilifeform: under (1) i also include bounds checking and sane error handling
asciilifeform: that's pretty much it.
mircea_popescu: i was hoping for whips and cuffs
asciilifeform: under (3) i also include that native compiler must support unix
asciilifeform: (or it is not properly speaking 'native')
asciilifeform: whips and cuffs come with ada
asciilifeform: if your book didn't come with then, get yer money back
asciilifeform: *them
mircea_popescu: lol
asciilifeform: i'd include forth, but it has the 'safety' of a frag grenade.
asciilifeform: (a frag is not a useless thing, has its place where nothing else
will do. but only there.)
asciilifeform: i recall there was a thread where mircea_popescu unzipped and
pissed on standards, but they are pretty much the only way you get to have (2)
and (3)

Bounds Checked, Auditable, No Runtime


asciilifeform: i was willing to deal with the cpp miseryu of trb because 1) it
pre-dates bitcoin being valuable 2) it was - and remains - the schelling point,
'father's pistols'
shinohai: I will use trb as long as it works on the overall network, failing
that I will have to find something else to occupy my time.
asciilifeform: this pointedly does not mean that i am interested in attempting
to wash the smell of shit off a rando sickly rat from rando sewer.
asciilifeform:  << ada.
assbot: Logged on 10-03-2016 10:52:32; jurov: but seriously, what is a must
have? mempool sanity and anything else?
asciilifeform: i am sick and tired of there being usg c/cpp code in the loop
asciilifeform: ENOUGH wotless nonboundschecked language.
asciilifeform: (i loathe ada, but this needs a BOUNDS-CHECKED language where i
can AUDIT THE BINARY and NO RUNTIME COMPONENT / GC - which leaves exactly ONE)

(External Reference)


asciilifeform: shinohai, mod6, et al: <<
possibly helpful?
assbot: A Random Walk Through Ada ... ( )
asciilifeform: ^ mega-recommended to everyone with the faintest inkling of an
interest in subj. overview of nearly all key aspects.

Bounds Checked, No Runtime, No GC


asciilifeform: ;;later tell mircea_popescu i had a notion: if we're no longer
holding the 'father's pistols' line, is there any good reason not to replace
openssl in trb with, e.g., ada bignum ?
gribble: The operation succeeded.
asciilifeform: (the issue of whether the muscle exists, to do this, is a
separate question. the above is simply re the political aspect of whether it is
a thing that is even to be contemplated.)
asciilifeform: i regard it as a mircea_popescutronic question.
phf: wasn
phf: err
asciilifeform: in other 'news', in my dream, mircea_popescu was camping in a
tent in my house, and reading a dead tree copy of the logz summarized by
somebody or other, and it was a thing on ancient yellowed paper, he cursed and
spat and in the end tore it up and started smashing things, then went out the
door and started firing some sort of energy weapon at the trees
mircea_popescu: asciilifeform there is no good reason - for the contemplated
july alternative offering
asciilifeform: aha this is what i thought.
mircea_popescu: on the contrary - the more crud that can be snipped the very
asciilifeform: mircea_popescu: how about c-s in place of ecdsa ?
mircea_popescu: if we had a working implementation!
mircea_popescu: and something instead of bdb. but INSTEAD not alongfuckingside!
mircea_popescu: and and and.
asciilifeform: again these are mircea_popescutronic questions! they leave aside
the issue of 'have we the divisions'
mircea_popescu: truth be told our diligent efforts over the years - and by our
i mean mostly not mine - exposed so many hooks for fixing and improving it's
not even funny.
asciilifeform: the reason i asked was that i noticed that ada links just fine
with cpp crud, both having been shat out of ordinary gcc
mircea_popescu: nb.
asciilifeform: so piecemeal organ replacement is a realizable thing.
mircea_popescu: this is pretty great news, actually.
asciilifeform: folks who have been experimenting with gnat prolly already
realized this. but i am leaving it here for n00bz.
phf: property of all gcc, can link fortran for numerics
asciilifeform: aha
asciilifeform: (i can't fathom ~why~ you would, but yes, you can)
asciilifeform: 90% of why i like ada is that it 'compiles like c' (i.e. without
massive runtime or bytecode claptrap in place of ida-able binary) WHILE having
bounds-checked array accesses etc.
asciilifeform: if this were available somewhere else, i would look into the
somewhere else.
asciilifeform: 9 or so of the remaining % is because you get static memory (no
consing, no gc, FORCED to intelligently allocate).

Predicated Types, Standardized, Integers not presumed machine words


mircea_popescu: phf fwiw i believe "threads" are a miserable kludge, so i can
see the angle.
asciilifeform: even mcl has threads.
asciilifeform: mircea_popescu: no threads, no multicpu
phf: asciilifeform: quiters
mircea_popescu: asciilifeform were you gonna explain how the grocery thing
relates ?
mircea_popescu: and srsly, what, it's my job to tell the processor how to
process ? that's why it's a processor, let it process!
asciilifeform: mircea_popescu: in that most effective software isn't public.
mircea_popescu: but oh, no, "you gotta make this hacky flagging scheme to show
us what to paralellize!"
asciilifeform: mircea_popescu: you'd like ada then
mircea_popescu: asciilifeform that is utterly besides the point, isn't it ?
most well made statues were kept in temples, in the dark, untouched and unseen.
this doesn't mean they had ergonomic spoons in mass production!
asciilifeform: ada tasks, afaik, is the only sane implementation of parallelism
where you ~never~ specify explicit thread
asciilifeform: mircea_popescu: consider, e.g., naggum's oil/gas exploration
asciilifeform: they were 100% commonlisp (allegro) but never will be published
or advertised.
mircea_popescu: consider what i'm actually saying : it's one thing to solve
correctly a well defined problem ; it is another thing to solve well a nebulous
asciilifeform: they are not part of what folks think of as 'software ecosystem'
mircea_popescu: we'll be doing a lot of the 2nd willy-nilly.
asciilifeform: right
mircea_popescu: and it is good that the good tools, derived from 1st, get some
battle experience.
asciilifeform: i can't argue with this.
mircea_popescu: so then why are you :) asciilifeform: my objection was to 'lisp never tested in Serious Business'
mircea_popescu: I DID SAY!!11!! "without importing" did i ?
mircea_popescu: and yes, the more i hear about ada the more i like it, or
properly speaking the more it sounds like right thing.
asciilifeform: mircea_popescu: i wish it weren't the right thing...
asciilifeform: but it is.
PeterL: asciilifeform could you make a "right thing" that is better than ada?
asciilifeform: has, e.g., predicated types. (which means, you can declare a
variable, where, say, assigning a prime number to it is an error condition in
the runtime. which means, yes, a check on EVERY assignment.)
asciilifeform: PeterL: when? by friday morning before breakfast ??
mircea_popescu: PeterL not in a lifetime.
PeterL: no, just conceivably, as in have you identified places where it could
be improved?
mircea_popescu: liek that it's a pretty good q.
asciilifeform: PeterL: understand, ada is necessary because we are stuck with
the idiot c machine.
asciilifeform: a properly constructed computer would perform ALL of the same
checks, and more, IN HARDWARE
asciilifeform: but we haven't such a thing.
PeterL: aha, so if you ditch c-machine then you could do better?
asciilifeform: PeterL: definitionally
mircea_popescu: different and incomparable.
asciilifeform: ^
mircea_popescu: there's no "better" in that space.
mircea_popescu: also you can't implicitly sort complex numbers.
phf: well, incremental improvement on ada doesn't seem like a particularly
interesting problem, thing comes with a lineage, wirth's pascal, modula,
oberon; ada fits into that ecosystem, so simply going over wirth's research you
can find a lot of existing ideas for ada improvements
asciilifeform: the 'better' is in the sense of 'less screaming idiocy in the
mircea_popescu: if idiocy screamed in the forest where there's no alf the
bee-dog to hear it,
mircea_popescu: would the world be better ?
asciilifeform: phf: there are some very obvious warts in the language - e.g.,
the compiler is one-pass and you end up having to write c-style prototypes for
some functions.
asciilifeform: but there is also a STANDARD
asciilifeform: and if you improve the thing, you break it.
asciilifeform: as in common lisp.
phf: but if you start with scheme-81/cadr or greenarrays or whatever, could
probably get more interesting results by a margin
mircea_popescu: incidentally, WHY is the compiler single pass ?
asciilifeform: phf: yes, but we haven't the factory.
asciilifeform: what we have is a great many rusty old pentiums.
asciilifeform: mircea_popescu: why? because it is.
asciilifeform: because it made sense in 1980
asciilifeform: when cpu cycles were precious, and disks - glacially slow.
mircea_popescu: i've been wondering bout this.
mircea_popescu: but might be the lowest fruit.
asciilifeform: incidentally, i recommend the 'random walk' article to anyone
with even a passive interest in the subj
mircea_popescu: asciilifeform> [...] you can declare a variable, where, say,
assigning a prime number to it is an error condition in the runtime. which
means, yes, a check on EVERY assignment. <<< now imagine the converse type :D asciilifeform: at least read the section about pointer leakage prevention
asciilifeform: it is unique, afaik, to ada
asciilifeform: mircea_popescu: l0l
mircea_popescu: aha ?
mircea_popescu: but there's a point here. it's not a bounded problem!
mircea_popescu: and yeah, i get the "doc it hurts when i do this" "so don't do
it then" thing. but ...
asciilifeform: mircea_popescu: generally folks will use simple predicates
(e.g., 'not equal to 0')
asciilifeform: sorta like c 'assert' but you can attach it to ~anything~
mircea_popescu: hey. is it a thing or is it not a thing! stop giving me jam!
asciilifeform: which ?
mircea_popescu: the predicated types.
mircea_popescu: "all of the same checks, and more, in hardware". what now ?
miner core in every cpu, to check for primality ?
asciilifeform: mircea_popescu: basic hygiene.
asciilifeform: as in, arrays live with their bounds
asciilifeform: and ALL accesses are bounds-checked;
mircea_popescu: your idea of basic hygiene differs from the medieval french
only in form, not in substance.
mircea_popescu: it's still give or take "what everyone else does".
mircea_popescu: and fwiw most arabs'd be horrified at the notion of not
actually washing bunghole after defecation.
asciilifeform: integers are MARKED AS SUCH and tested when arithmetizing;
mircea_popescu: poorest village public toilet still had water implement in
working condition.
asciilifeform: mircea_popescu: i did not say that basic hygiene is a ~stopping~
place, but a starting point.
asciilifeform: we don't even HAVE the toilet yet.
mircea_popescu: the problem is that it being unbounded, it can't really be
asciilifeform: we're still at the shit-where-you-stand level.
asciilifeform: the basics ABSOLUTELY belong in hardware.
mircea_popescu: reasoning past the faith ?
hanbot: davout moar for you.
asciilifeform: there is no excuse for buffer overflows to be a thing.
mircea_popescu: why not ?
asciilifeform: why not shit where you stand?
asciilifeform: in your pants?
asciilifeform: do i have to justify that also ?
mircea_popescu: listen : the EARTH permits you to do so.
mircea_popescu: do you propose "not shit where yo ustand" should be a property
of earth and standing ?
mircea_popescu: would you buy pants with buttplug ?
asciilifeform: mircea_popescu: this is a ludicrous analogy.
asciilifeform: the butt plug has a down side.?
mircea_popescu: "as long as these are securely fastened, an absolute guarantee
to no pants shitting can be offered by manufacturer". and yes i used such
thjings, but for very peculiar purposes.
mircea_popescu: and if it's a shitty analogy blame yourself - you brought it in!
mircea_popescu: ha! what, and hardware has no downside ?!
mircea_popescu: now i understand why you expect the foundries to cost billionz!
you're outsourcing!
asciilifeform: sane hardware has no downside other than it not yet existing.
mircea_popescu: ...
asciilifeform: in that respect it has the same downside as eschewing microshit
had in 1995.
phf: that's a platonist right there
mircea_popescu: seems altogether easier for you to not shit where you stand
than for us to create a new reality.
asciilifeform: not entirely new, examples existed as early as 1969
asciilifeform: (control data corp.'s products)
mircea_popescu: a more general and unrelated problem : why should the specific
number of compiler passes be set down in the standard ?
mircea_popescu: i can't write sentences with a count at the end saying how many
times you have to read them until you get them.
asciilifeform: 2.
asciilifeform: as for 'why standard' - it affects the semantics.
asciilifeform: ergo a standard is meaningless unless it contains it.
mircea_popescu: wasn't by any means a practical consideration. more of a
"thinking about the compiler of the wetware future"
phf: $up a111
deedbot: a111 voiced for 30 minutes.
mircea_popescu: hola a111
phf: << i also agree, i just politely
pointed out that the feature is obviously needed, i just don't trust bot part
enough yet to put more functionality on it. ??
a111: Logged on 2016-04-06 12:30 asciilifeform: ;;later tell phf i find myself
agreeing with adlai, the way we have it now, the log is in fact near-unreadable
EXCEPT in wwwtron. links oughta dump into the chan assbot-style
mircea_popescu: o check it out , also had a bot.
phf: it's all bots sitting there unvoiced
mircea_popescu: juj
mircea_popescu: (ftn, juj = kik ^2 = lol ^ 4)
asciilifeform: what'd be the complex conjugate of l0l ?
asciilifeform: re earlier thread,
asciilifeform: ^ predicates
mircea_popescu: which reminds me of my indignation in 9th grade. THERE ARE TWO
phf: $down a111
mircea_popescu: -a+bi / a + bi also!
mircea_popescu: "So we see that the predicate in the subtype Even cannot be a
static predicate because the operator mod is not permitted with the current
instance. But mod could be used in an inner static expression."
mircea_popescu: eh ffs.
mircea_popescu: even can be static irrespective of fucking mod wtf.
asciilifeform: mircea_popescu: you gotta know what mod means in ada
mircea_popescu: "and, in addition, a call of a Boolean logical operator and,
or, xor, not whose operands are such static predicate expressions, and, a
static predicate expression in parentheses." << right there. a xor maxint-1 > 0
asciilifeform: it means 'takes up this-many bits REGARDLESS'
mircea_popescu: EVEN is wrongly defined is the point.
asciilifeform: where?
mircea_popescu: im quoting from your link.
trinque: phf: << here's what I beat your example into
trinque: maybe we can collaborate on getting a bot that, y'know, stays
connected to an IRC channel
trinque: thing knows how to ghost, has your ping/pong code in it (thanks!)
trinque: and I have no idea if I did terrible things, so say so. I'm just some
dude reading books on lisp that washed up on my island
asciilifeform: trinque: neato
trinque: where I (think I'm) headed is the bot being a separate module. code
using the bot would pass the appropriate generic function to call for commands
into make-bot
mircea_popescu: asciilifeform basically they lazily decided "even" is to be
tested by "mod", which is unacceptable if they're going to make mod randomly
unavailable ; seeing how there are purely bit-logical ways to test for
mircea_popescu: which they don't make similarly unavailable.
phf: trinque: you can forgo the whole nickserv integration by putting password
into the irc:connect
asciilifeform: mircea_popescu: the bitwise thing works. i have nfi why not used
in the example.
phf: or better yet add ssl key
asciilifeform: or actually i no
asciilifeform: *do
asciilifeform: say it's an algebraic type (e.g. bignum)
trinque: phf: ah that's simpler
asciilifeform: ada is a civilized lang like commonlisp and there is NOT a
presumption that integers are machine words !
mircea_popescu: so you're saying i'm a sinful asm/cobol/c-head ?
asciilifeform: aha.
mircea_popescu: for shame.
asciilifeform: it is curable tho!
phf: trinque:, (irc:connect :nickname
*bot-nick* :server "" :password *bot-ns-password*)
phf: should solve all your service woes
phf: my ping/pong code was not very good. i reworked it yesterday, but haven't
yet enabled on this guy, so if he falls over, it'll be quietly, and we'll know
by lack of logs :D trinque: and that'll just boot the previous instance of "deedbot" if I connect
that way?
asciilifeform: mircea_popescu: ada is a merciless thing. e.g., you cannot use
two types interchangeably even if 'they're the same inside'; can only take
pointers of items explicitly declared pointerable-to; by default, pointers only
valid in the context where they were taken
mircea_popescu: aha.
phf: that was my impression since that's how my bouncer runs, and the only time
i had issues is when my ssl cert silently expired. but come to think of it,
i've not tested it
asciilifeform: the basic philosophy is to take the most dangerous knobs and
attach broken glass spikes to them
asciilifeform: so programmer only grips it if he ~really~ must
asciilifeform: and feels the pain.
mircea_popescu: sounds a lot like v!
asciilifeform: aha.

Bounds Checked, Link with C Code


mircea_popescu: anyway, re earlier discussion, i guess it'd be worth
belabouring the point that nothing therein contained is an argument against
using ada. it's still a great technical solution, for bounds checking, for
other reasons, it's still a great practical solution, for native linkability
with c object code, for other reasons. same stands for scheme, still best
option for a scripting language for bitcoind.
asciilifeform: mircea_popescu: re thread, see also earlier threadz re
'impedance matching'
mircea_popescu: impedance yea
asciilifeform: as in 'why using 19 bit integer is 25x slower than 16'
asciilifeform: the concept pervades physics.
mircea_popescu: "why is no insect larger than a breadbox"
asciilifeform: well that's more euclidean geometric (surface/volume)
mircea_popescu: (contrary to what noob scientists may think, "a breadbox" is
neither arbitrary nor undefined in that sentence)
asciilifeform: this'd be more of a 'why is ear shaped like-so'
shinohai: Thanks for making my day entertaining anyway pete_dushenski o/
mircea_popescu: asciilifeform geometry doesn't really matter until physics
decides d^x is a factor :D pete_dushenski: shinohai: yw!
pete_dushenski: ;;later tell davout don't scare-excite me like that next time!
(wait, what next time?) also, i wanted to show up here, but couldn't quite
meditate and irc atst?
gribble: The operation succeeded.
asciilifeform: ;;later tell mod6
gribble: The operation succeeded.
asciilifeform: ^ and anyone else
asciilifeform: spiffy resource.

Corespondence to physical machine, Type Safe, Bounds Checked


ben_vulpes: kinda interesting how haskell has yet to eke out a foothold around
ben_vulpes off to inject an urban food log down his throat
ben_vulpes: put it in mah face hole
mircea_popescu: ben_vulpes you don't get it : the "Reputation" bs is
institutionalized oppression.  in any system where group x has "reputation for
y-bad" you know for a fact that a) group z is in charge ; b) group z is y-bad
and c) group x is not.
mircea_popescu: STRICTLY that ; nothing else.
jurov: ben_vulpes: haskell is too young
mircea_popescu: ben_vulpes jurov haskell is domain specific for domains we're
not as of yet interested in ?
jurov: no it's actually quite suitable for bitcoin implementation, i have
written performant simulation in it (but had to instrument it not to gobble
memory for lazy computation)
jurov: just not stable yet
jurov: 10y old haskell code not worky
mircea_popescu: ah then that's the answer : jurov's not published yet.
mircea_popescu: apparently the "around here" is wider than previously thought.
asciilifeform: ben_vulpes: fwiw i programmed in it
asciilifeform: it has the prolog disease.
asciilifeform: (and, unlike prolog, is quite massive per se, and not easy at
all to implement, and there is ONE usable implementation...)
mircea_popescu: in other irrelevant home flavour, girl making zacusca (the
proper ro thing, baked peppers, etc) "what do i do with the juice ?" "freeze
it" "hmm... need to get bags we're out" "use an ice cube tray". now ima have
veggie broth cubed, for soups!
asciilifeform: 'lazy computation' is -- like it or not -- a horrendous idea.
mircea_popescu: asciilifeform i don't suspect he's using THAT part.
asciilifeform: (it is VERY attractive to academitards because it creates the
kind of problems which they can later convert into papers)
asciilifeform: mircea_popescu: you can't actually program in haskell 'without
using that part', not really
mircea_popescu: there's possibly a language under academia-haskell screaming to
get out ; strong types and etc
mircea_popescu: it's unclear if that language reduces then to ada, but i
suspect not.
asciilifeform: no, it reduces to ml
asciilifeform: specifically.
asciilifeform: i considered ml as a very, very close contender for 'an ada'
mircea_popescu: this is possible yes.
mircea_popescu: "typed lisp" w/e
asciilifeform: but i very much dislike the 'no native compiler exists or can
likely ever exist' part; and the 'there are 2 implementations ever made, and
only 1 is quasi-usable' part.
asciilifeform: ada suffers from the latter problem also
asciilifeform: (but not the former)
mircea_popescu: jurov did you consider and discard ml for your application
incidentally ?
jurov: never touched ml
mircea_popescu: ah.
asciilifeform: hardly anyone ever touches it today. no longer taught, afaik.
asciilifeform: it was 'replaced' with haskell in academiland, and with ocaml in
heavy industry
asciilifeform: (the latter has ONE IMPLEMENTATION, by some fr d00dz)
mircea_popescu: ocaml that ml which is ml in the sense javasCript is c.
phf: << i still think koi8-r was a
great hack. i think cleverness of that kind is no longer popular because idiots
ruined cleverness for everyone??
a111: Logged on 2016-12-13 19:54 Framedragger just discovered how phuctor's 404
page looks like: - appreciates
asciilifeform: mircea_popescu: on the contrary, it has a native compiler for
x86. but i categorically am put off by the 'one implementation' thing.
mircea_popescu: phf as per naggumg quote ; quite exactly my mind too : there
not existing cleverness is more valuable to the empire-of-idiots than any gains
from clevernesses they realise.
asciilifeform: phf: i still have multi-GB stash of koi8
mircea_popescu: which is true, too. republic grows by cleverness ; empire
shrinks by it.
asciilifeform: fwiw i am still open to suggestions re 'the better ada'
asciilifeform: because ada per se is very, very hairy hair shirt.
asciilifeform: but afaik is not escapable, no.
mircea_popescu: that open-ness is imaginary at best ; minigame will use ada rsa
for example.
asciilifeform: theoretically open.
asciilifeform: i don't expect an answer.
mircea_popescu: there was a window, but i think it closed recently.
asciilifeform: am quite certain , in fact, that there isn't one
asciilifeform: as someone who ~likes~ 'functional' languages, etc., i still
must point out that it is a highly questionable business to use a language
where there is not a simple, kindergarten correspondence b/w each line of the
program and what the machine physically does, for safety-critical equipment.
asciilifeform: of the type-safe/bounds-safe languages, ada is the only one
which fills this description.
asciilifeform: afaik.

Bounds Checked


asciilifeform: in unrelated noose, 'nqb' reads & parses a full 1MB block, with
2218 tx, and recreates it from fast-form, again to disk, in 0.123 sec. on a
3GHz opteron cum ssd.?
mircea_popescu: ah that's not bad at all.
ben_vulpes: next time someone says "i know a feller", next question is "which
mircea_popescu: "oh nobody in particular"
asciilifeform: mircea_popescu: well that's merely the mechanical process, no tx
index queries, no scriptolade use.
mircea_popescu: aha.
mircea_popescu: still.
ben_vulpes: i know in point of fact that i've demonstrated how candidates for
voice are to introduce themselves before.
asciilifeform: fuzzed it, in various ways, ada bounds checking worx like a
champ in all cases
asciilifeform: (every variable knows what its expected range is, and said
bounds are checked on any assignment)

No Promiscous Pointer, No Promiscuous Cast


asciilifeform: ada in particular is 'a harsh mistress', you can sit for 3 hrs
and your thing simply won't build, gcc won't eat it, and you gotta actually
open the book and grasp the reason why, brute force knob-twiddling will get you
0 result.??
mod6: i've quite noticed that actually.  i was trying to figure out "packages"
and did an evening worth of headbanging.
mod6: over something that should have been totally trivial.
asciilifeform: then later it dawns on you that the 'could have been trivial'
would have been at the cost of becoming c.
mod6: right. fair enough. and reasonable advise.
asciilifeform: the pointer rules are the clearest case of this.
asciilifeform: in most cases you can't even point to a thing in ~your current
asciilifeform: because machine has nfi which items in ~current~ scope will go
out of scope first...
mod6: yah hmm.
mod6: I hope it's not too prohibitive.
asciilifeform: mod6: in principle you can always beg compiler for mercy and
introduce 'unchecked', c-isms. or even (1 line, in fact) import arbitrary c.
asciilifeform: but it is only 'last resort'
asciilifeform: and more or less any problem that doesn't involve os calls, can
be solved in some other way.
asciilifeform: but it does require letting go of n decades of 'c thinking',
where you reflexively litter the proggy with pointers to whatevers
asciilifeform: there ~are~ considerable wins in convenience -- you can ask an
array how big it is; and where it starts/ends (indices are not from zero, but
can be from anything to anything, as can types -- you can have a type 'integers
from 12 to 15', say.)
asciilifeform: but yes, you will do 2-3x the work, subjectively, as when
writing c proggy. but it is not ~wasted~ work, just as the work of using v
instead of 'git' etc. is not wasted.?
asciilifeform: the end result -- is different.
shinohai finds V far easier than git now for some reason .....
asciilifeform: i don't bring them up together out of superficial similarity,
but from fundamental one -- v rejects 'merge' as a concept; ada rejects the
promiscuous pointer and cast
asciilifeform: both are items 'civilians' are quite accustomed to, to the point
of 'how the fuck can anyone even think of living without'
asciilifeform: eventually one -- learns. and then you begin to see the monkeys
who 'why should i have to look for a special place before taking a shit, i can
do it wherever' as the loathesome things they are.

Bounds Checked Array Slices


asciilifeform: mod6:
asciilifeform: btw, nobody's exempt from having to eventually grasp how ^ worx
asciilifeform: so may as well get head start.
asciilifeform: incidentally, (imaginary) prize to the first d00d who
understands why this had to be rewritten with the loops indexing from 0 .. L-1,
rather than, e.g., for i in X'Range ... as formerly
asciilifeform: rot13 spoiler: Nqn neenl fyvprf xrrc gur 'Svefg naq 'Ynfg bs
jurerire va gur cnerag gurl pnzr sebz! sbe fbzr ernfba guvf vf abg zragvbarq
naljurer ohg va gur fgnaqneq. Xnengfhon bs pbhefr raqf hc vaibxvat gur onfrpnfr
zhygvcyvre jvgu fyvprf gung qba'g ortva jvgu mreb, naq gb qrfgvangvba neenl
gung yvxrjvfr qbrfa'g. Fb jr tbggn abeznyvmr.
mod6: asciilifeform: thx, will read
mircea_popescu: asciilifeform this sounds like the ugliest of hacks.
asciilifeform: mircea_popescu: it ain't tho.
mircea_popescu: why does ada do that, anyway ?
asciilifeform: because not doing it would lead to increased ugly.
asciilifeform: though i also found it at first difficult to understand why.
mircea_popescu: i realyl don't like this "and now we magic-variable the
numbers". it's one step up from magic constant
asciilifeform: slices are not arrays in their own right, they are offsets into
another array
mircea_popescu: ok...
asciilifeform: and ergo retain the original's indexing.
asciilifeform: so you can get it back from a slice
mircea_popescu: wouldn't it actually be proper to copy the slice into its own
array ?
asciilifeform: no!!!!
asciilifeform: that ain't called a sloce
asciilifeform: *slice
asciilifeform: that's a copy, we do this also sometimes.
mircea_popescu: wouldn't it be actually proper to copy the slice into its own
array and to maintain a pairing of slices and new arrays ; rather trhan do
index magics on the mult code ?
asciilifeform: nope. blows the cache.
asciilifeform: and bloats the algo.
asciilifeform: worst of all worlds.
mircea_popescu: i didn't say practical, i was just going with proper
asciilifeform: seekrit : in the 'most fascist' restriction mode, ada... copies
mircea_popescu: aha
asciilifeform: ( behind the curtain )
mod6: ah.
asciilifeform: (no_implicit_loops pragma iirc)
mod6: i've read, so far seems ok -- i've got to wrap my mind around the second
("high loop") as I did before.
mod6: gotta take it the whiteboard a bit later perhaps.
asciilifeform: upstack, array slices ( which commonlisp also has ) are
important to being rid of having to use c-style pointers
asciilifeform: in much the same way as 'in' parameters (in ada procedures)
mircea_popescu: i am sitting here wondering if this is "getting rid" as in, rid
or rid as in, hid.
asciilifeform: rid.
asciilifeform: in that they are replaced with a far more constrained item
asciilifeform: about which you can prove particulars.
mircea_popescu: what particular can i prove re the relation between an array
slice and the index fixer variable ?
mircea_popescu: ~same as the relation between pointer and its content, "better
hope programmer didn't fuck up ; and also it usually blows up if he did so
there's that"
asciilifeform: wrong
asciilifeform: they get checked against the bounds
asciilifeform: every. time.
mircea_popescu: ah so no overflow
asciilifeform: aha.
mircea_popescu: but can i overflow THE SLICE ?
asciilifeform: nope.
mircea_popescu: wedll that's something.
asciilifeform: slice has own bounds, the correct ones.
mircea_popescu: i see.
asciilifeform: ada is a thing for a reason, i found. hence this entire thread.
mod6: so recently, i've done some multi-d array programming in ada..
asciilifeform: every time, to date, when i bashed head against wall and went
'WAI DOES IT DOOO THAT!1!!1' i ended up repenting
asciilifeform: 'oooh hey turns out, Right Thing'
mircea_popescu: that's encouraging...
asciilifeform: quite possibly i'dve given up long ago if not for this repeated
mod6: all i can say thus far is; stuff seems to be strict.  my code may
compile, but indeed blows up at runtime.
asciilifeform: every single time it was 'guess wat, this is How It Works in the
adult hut. for reasons that Make Sense'...
asciilifeform: mod6: note that 'blow up' still dun mean 'segfault'
mod6: index out of bounds.
mircea_popescu: he means it catches it itself
mod6: or whatever it was.  no did not seem to be a segfault.
mod6: im just dumb.  it seemed to be smarter than i am.
mod6: at least, for nw.
asciilifeform: mod6: you won't physically ever see a segfault in ada proggy
built with default 'fascism' level
asciilifeform: most you'll get is a stop.

Hardwareizeable Bounds Checking, Strict Conformance Enforced on Whole Program


mircea_popescu: for my own curiosity, what's the state of the art re "MINIMAL
cpu design" ? ie, the theory of how many instructions mustg be in a set and why
and per-instruction justification and everything ??
mircea_popescu: you know, the basis of design and documentation.
asciilifeform: this is actually asciilifeform's primary interest re subj
mircea_popescu: im not exactly shocked.
asciilifeform: and answer very very depends on what is required in terms of
mircea_popescu: asciilifeform design does not proceed towards requirement.
mircea_popescu: design proceeds from available.
asciilifeform: upstack -- you can do a great deal with 1 instruction.
asciilifeform: ( as in, 'oisc' )
asciilifeform: there are several known schemes for this.
mircea_popescu: car gets internal combustion engine NOT because "the needs of
the buyer", but because it needs a power plant and that's the better powerplant
available. the needs oif the buyer are welcome to adapt.
mircea_popescu: that's the design flow. automobile, therefore powerplant,
therefore ice.
asciilifeform: the basic tradeoff is, the fewer the moving parts in cpu, the
more constrained is the horse by the switching elements' speed.
asciilifeform: ( consider, elementarily, pipeline vs. none , for instance. )
asciilifeform: or the cost of not having a barrel shifter.
asciilifeform: or a multer. etc
asciilifeform: ( or, on the extreme end of things, not having arithmetic other
than add-one. as scheme chip did. )
mircea_popescu: but the decision of whether to have or not have barrel shifter
is strictly carried on the cost of it.
mircea_popescu: (what is the total cost of this item ? what percentage of that
is this new addition ? what is the output of this item ? what percentage of
that would the new addition produce ? make these two rations equal, you're done
adding parts.)
mircea_popescu: ratios*
asciilifeform: correct. but the answers to these depend SEVERELY on the
substrate. for instance, if your thing lives in a fpga, not filling it up
doesn't make it cycle any faster. so you want to actually use the available
gates, if they can be used productively
asciilifeform: ditto for a die made with particular process -- empty space
doesn't get your money back
mircea_popescu: so the cost will be 0, this is correct.
asciilifeform: ( it can lower thermal output, so still makes sense sometimes to
have empty. )
mircea_popescu: the design of any general purpose item is above, there's no
mircea_popescu: asciilifeform so the cost will be epsilon, 0 from real estate
and epsilon from heat.
asciilifeform: one other gotcha: complexity has a cost.
mircea_popescu: definitely.
mircea_popescu: this is not a gotcha.
asciilifeform: it apparently is a surprise to some people.
asciilifeform: ( largely because they historically were able to externalize the
cost. )
mircea_popescu: the usg not holding up to its side of any bargain it ever made
-- also surprise. to some people.
mircea_popescu: asciilifeform ftr, the "register window" spark thing seems the
height of idiocy, but what do i know.
asciilifeform: mircea_popescu: it was a pretty ordinary thing in '80s
mircea_popescu: leaving aside how "our idea of scalable is to define a number
up to 32 and then you can go from 3 to 32 and this is now scaling" hurr.
asciilifeform not aficionado of sparc specifically. it's a complexityhog.
asciilifeform: mircea_popescu: you can't have infinitely elastic registers.
there's N bits , physically.
asciilifeform: the word is this-wide.
mircea_popescu: you can not call your spec "scalable" while it has magic
numbers in it.
mircea_popescu: this is a fact.
mircea_popescu: magic numbers === friable.
asciilifeform: physical objects all contain immutable 'magic numbers'.
mircea_popescu: asciilifeform at issue is the count of "registger windows" that
can be implemented.
mircea_popescu: not the register width.
asciilifeform: the index into these is a register. having some immutable width.
asciilifeform: the thing being indexed, gets populated ( or not ) exactly like,
e.g., ipv4, or the holes in your pci bus, etc
mircea_popescu: they did this dumb shit whereby passing was done by shared
registers ; every process or w/e could see 8 proper and 8 shared or such.
mircea_popescu: the number of such "register views" aka windows was a
per-processor thing
mircea_popescu: and the sparc designers imagined allowing this to be between x
or y counts as "Scalable"
asciilifeform: and yes it's ridiculous . but they forced themselves into it by
having the window thing at all, is the idea.
mircea_popescu: ie, if you implement 32 register views you're then making a
server cpu whereas if you implement 3 you're thereby making an embeddable cpu
mircea_popescu: asciilifeform this is true, but the fucking correct solution
was to take the bs off not to "fix it". aaanyway
asciilifeform: i mention sparc as a historic item, it is afaik no longer
possible to source it.
mircea_popescu: i don't think it was ever any good.
asciilifeform: ( other than by baking into fpga. which 1) introduces the 'which
fpga, again' problem 2) if you have fpga, big enough for sparc, you can make up
a SANE arch to go in it
asciilifeform: )
mircea_popescu: anyway, there's that thing amateur rocketry kids dfick with,
what was it
mircea_popescu: the raspberri before the raspberri
asciilifeform: ?
mircea_popescu: gimme a sec
asciilifeform: fpga only
mircea_popescu: 32 bit thing, has source, vdhl etc.
mircea_popescu: yes.
asciilifeform: never existed as an actual physical chip.
asciilifeform: there's NO shortage of these.
asciilifeform: i have own, even.
asciilifeform: what i was looking for, is actual physical off-the-shelf cpu.
asciilifeform: ( that doesn't rely on closed xilinx 20GB turdchain to fill,
doesn't contain a flash rom, doesn't double as a frying pan )
mircea_popescu: << check them out heh
mircea_popescu: dual-core leon3-ft processor, 200mips, 200mflops.
asciilifeform: looks like golden toilet asicization exists (existed) ?
asciilifeform: unsurprise
asciilifeform: but go and buy.
mircea_popescu: they're all asics, in the metal layer sense used in bitcoin
mining. they deliver.
asciilifeform: yes. but not on open market, is the point.
mircea_popescu: as in buy on amazon ?
asciilifeform: as in buy at digikey or other mainstream supply house .
mircea_popescu: aha. neah, they sell like NSA sells FG.
asciilifeform: ( and if i were producing $box by the million, i wouldn't deal
with these derps and use their weird arch, but have my own asiced. )
mircea_popescu: subject to
a111: Logged on 2017-08-02 20:04 mircea_popescu: for my own curiosity, what's
the state of the art re "MINIMAL cpu design" ? ie, the theory of how many
instructions mustg be in a set and why and per-instruction justification and
everything ?
asciilifeform: << see also thread...??
a111: Logged on 2017-06-30 19:42 asciilifeform: in fact, here's a new (afaik)
scheme for tta. an instruction is THREE addresses, X, Y, Z. and it performs Z
:= X xor Y.
mircea_popescu: to revisit a very ancient mp wonderment since his
less-interested days ( )
: why not ada-on-a-chip ??
asciilifeform: what would that mean
pete_dushenski: in other "we didn't mean to phork ITWASAJOKE",
asciilifeform: ( if mircea_popescu meant a chip-that-checks-bounds. which
existed at various points, e.g. symbolics lineup supported ada natively just as
well as lisps . )
mircea_popescu: no. i mean chip whose instructyion set is ada.
asciilifeform: lol, as in basic interpreter, actually moving the fucking
humanreadable strings around ?
mircea_popescu: not necessarily.
mircea_popescu: as in language-on-a-chip, no interpreter no compiler no linker
no assembler.
mircea_popescu: native code, is ada.
asciilifeform: that'd mean 'shuffling the human strings' necessarily.
mircea_popescu: so i guess -- like old lispm
asciilifeform: which come in variable widths.
asciilifeform: the lispm was pointedly NEVER anything of the kind.
mircea_popescu: asciilifeform ince when the fuck ? use whatever glyphs you want
for the opcodes.
asciilifeform: huamnreadables come in variablewidths, so this doesn't work in
physical reality.
mircea_popescu: humanreadable face on code is a GLYPH. the code is actually
asciilifeform: in the end when you try an' make this, you end up with
essentially the bolix chip.
mircea_popescu: you currentyly know 0f is pop and 0f a9 is pop gs and so on.
mircea_popescu: for the same money you could know 0f is if or whatever the
fuck, ada instruction.
asciilifeform: the addresses are where you diverge from humanreadablelang.
asciilifeform: not the instructions.
mircea_popescu: but i only asked for ada chip in sense of, cpu instruction set
== ada language.
asciilifeform: ada is interesting because 1) all array accesses bounds checked.
you CAN hardwarize this. but also 2) whole program is forced to conform to
strict rules, said conformance can only be evaluated during compilation, and
strictly when taken as whole
asciilifeform: you can't hardwarize 2.
mircea_popescu: but you can in fact make the cpu run the same instruction set
as the language allows ?
asciilifeform cannot rightfully apprehend the confusion that leads to this
mircea_popescu: hm.
asciilifeform: possibly mircea_popescu had read my piece. but in re lisps, there are specific
operations that are missing from extant hardware : gc/cons, and
boundscheckedarrayaccess. these are clumsily implemented in software.
mircea_popescu: ok, let's approach it this way : is the point of a "high level
language" strictly to clothe cpu instruction set in glyphs people like, or is
there an actual substantive function to it beyond ux ?
phf: << neal stephenson at some point
raised half a million dollars on kickstarter to write a realistic computer
simulation/game for sword fighting. his target audience/groupies/support staff
look remarkably similar to the people from the photo in this articles,
including the one lady in renfair getup.??
a111: Logged on 2017-08-02 19:22 mircea_popescu:
 << actually apparently they have the same dumbass on the west coast, too.
mircea_popescu: (in other lulz nobody likely cares about, * Topic for #bolix
is: *** IBM PCjr collectors club )
asciilifeform: lul
mircea_popescu: phf supposedly this was for some charity with kidsd and shit.
asciilifeform: mircea_popescu: there's a substantive function, in
transistor-poor era , to break down high level lang into the type of ops
realistically fittable into silicon
asciilifeform: ops like 'move these 64 bits from this-here-place to
that-there-place' etc
mircea_popescu: my hidden implication being that the traditional reasons to
have the cleave are no longer sound.
asciilifeform: that was the contention of my piece ( linked above )
mircea_popescu: so then why confusion of ideas ?
asciilifeform: but it was written from specific pov of lispm aficionado gripe
-- where's my boundschecked dereference and hardware gc.
asciilifeform: from ada pov only the former is relevant.
asciilifeform: but in neither case does the instr set 'fully correspond to the
language'. in the case of ada in particular, there is a useful thing that
happens ~where whole program~ is examined.

Bounds Checked, Nonproprietary, Statically Compiled, Permits Pointer-free

Code, Auditable Binaries, Standardized, No Runtime 2018-04-12

mircea_popescu: zx2c4 you ever used ada ?
zx2c4: we've also got implementations in Rust and Go
zx2c4: that are userspace based
asciilifeform: zx2c4, mircea_popescu : it is quite trivial to build a kernel
mod with gnat
asciilifeform: ( iirc i posted a cookbook re same, while back )
mircea_popescu: that was my next answer, yes.
zx2c4: ada kernel modules? cool
asciilifeform: ( it is however presently unclear to me why the entire ciphrator
has to live in kernelspace. granted the packet-thrower perhaps must. but why
whole thing. )
mircea_popescu: could you guess, zx2c4 , why we would favour ada for finnicy
work such as crypto libs ?
zx2c4: unlikely that'd make it upstream if i did wireguard that way, but neat
that that's possible
zx2c4: i dont have enough exposure to ada to say for certain. how come?
mircea_popescu: and could you guess WHY it wouldn't make it upstream ? because
ada object-links with c object code np.
mircea_popescu: ima let alf explain why ada.
zx2c4: linus has never been so happy about other languages in the kernel. for
example, he rejected a C++ layer many years ago
asciilifeform: i'ma cheat and cite my own article, : '... in a heavily-restricted subset of the
Ada programming language — the only currently-existing nonproprietary
statically-compiled language which permits fully bounds-checked,
pointerolade-free code and practically-auditable binaries. We will be using
GNAT, which relies on the GCC backend.'
asciilifeform: and add to this, that it has an actual paper standard, and
minimal 'implementation-defined' rubbish (tho sadly not zero)
zx2c4: cool
asciilifeform: and doesn't require a multi-MB runtime.
zx2c4: sounds great
mircea_popescu: zx2c4 the good news is that i am now finally in a position to
explain what EXACTLY is meant by "terrorist" : that feeling in when shit keeps coming and coming and
coming up. what is it, if not spiritual terror ????
a111: Logged on 2018-04-12 17:20 zx2c4: you guys have invented lots of things
zx2c4: performance is good?
asciilifeform: there is absolutely no justification for the continued use of c,
aka overflowlang, aka heapabuselang, since... oh, 1985.
mircea_popescu: depends. performance on ACTUAL constanttime items is not so
mircea_popescu: but that's related to how they can't even exist in c.
asciilifeform: zx2c4: performance is difficult to compare; if you remove
various safeguards, you get ~same binary as equiv c proggy would have produced
on same ver of gcc.
asciilifeform: ( gnat , the ada compiler, is based on ordinary gcc )
zx2c4: so most checking is runtime instead of compile time then?
mircea_popescu: actually, most crap is not even permitted. see all the pragmas.
asciilifeform: if you switch the runtime checks on, you get a ~50% speed
penalty in practice, vs 'naked c'
asciilifeform: zx2c4: there is some quite 'fascist' compile-time checking. most
noobs to the lang, spend a week or so getting their proggy to even build.
zx2c4: hah i like that
zx2c4: ill give ada a look. ive long heard about it but never dived in
zx2c4: i need to head out for a bit now
asciilifeform: the use of pointers, for instance, is discouraged, and their
migration between scopes is prohibited
zx2c4: but ill idle in here for a while and will be back in several hours
mircea_popescu: zx2c4 and the good news is, linus permitted ada modules before.
zx2c4: ooo scoped pointers. thats nice
zx2c4: alright, ttyl guys

Bounds Checked, No GC, Compact binaries, Support Major CPU Archs, Written

Standard, Autditable Binary 2018-05-19

Mocky: speaking of plot twists, pretty surprised by the Ada usage. I pictured
usg.DOD-design-by-committee lang commissioned to help build out the
chumpatronic-mass-programmer infrastructure for gov contracts. I guess it's
time to reevaluate my priors.?
asciilifeform: Mocky: funnily enuff, it was resisted ( by lockheed et al, the
whole golden toilet 'industry' ) from ~day1, and is pretty much dead in usgdom
( with respect to new contracts ) , the brass began to succumb to 'use cpp +
massmarket programmertards +
these-here-fancy-auditing-toolz-that-totally-work-we-promise in 1990 or so)
asciilifeform: afaik boeing's passenger craft division is the last major usgdom
holdout where still used
asciilifeform: ( folx-on-the-periphery-of-l1 : might be a good use of coupla
hrs to dredge the logs for 'why ada' material that could point n00bz to, e.g. )??
a111: Logged on 2017-07-13 15:16 asciilifeform: the other thing to remember, is
that the win from writing in ada - but not in ada in general, but the style
demonstrated in ffa in particular -- remains even if YOU HAVE NO ACCESS TO GNAT
and gotta compile by hand into asm. because it forces the style of algo that
CAN be safely so expressed - i.e. without presumption of pointerolade
arithmetic, gc, or other cost-externalizing electrosocialisms
asciilifeform: !#s bounds checked
a111: 9 results for "bounds checked",
asciilifeform: ^ a notbad place to start from.
Mocky: i'll have a look at that
asciilifeform: Mocky: it was the one item left standing when asciilifeform went
methodically through list of all known prog langs , and crossed off anything
that didn't : bounds-check, operate free of gc, produce compact binaries for
e.g. microcontrollers, support all major cpu archs , have written standard.
asciilifeform: the closest runner-up contender was standard ml, but it demands
a ~MB-sized runtime , and imposes gc , nobody is ever stuffing it into 32kB.
asciilifeform: ( it also failed on
condition )??
a111: Logged on 2014-08-30 01:55 asciilifeform generally believes that
safety-critical code must be written in such a way that auditor can see a tight
correspondence between every line and what machine physically does. note that
this doesn't entail 'use C!' but can also mean different machine.

Foxybot Enhancements Part 2: Trade All The Things

Sunday, May 20th, 2018

Being newly satisfied with state of target selection I proceeded to open up the throttle on my botting 'efforts'. I let the bot run for longer. I babysat it sometimes. I tried different things. I explored around different places. In the process I learned a few choice morsels truth.

One thing I learned is that while the weight limit on how much you can carry is a bottleneck to maximizing how much you can get from building claims, for tiny claims, the limited number of inventory slots for keys is a bigger one. You can always place the heavy-yet-stackable 'harvests' on a table. However, tables aren’t much help with keys which are light but don’t stack.

I noticed that foxybot has an option to leave the key in the claim, freeing you from the space burden. Eventually the key turns to dust and you can go back and pick up that valuable dust off the ground. This allows for alot more exploring.

I tried this approach for several days. It works well when you explore the same path, back and forth, over a long period of time because you’re right there when the key disintegrates and can scoop up the dust. But…​

But you have to pickup those little bits o' nothing of the ground manually. For me, that wouldn’t do. So I added so logic to foxybot to take note of all the little bits on the ground and try to pick them up.

Figure 1. Foxybot bending over to pick something up 'seductively' at the moment I happen to look at the screen. Coincidence?

Oh man, it worked great! I almost wrote you a post about it. In fact, this was almost that post. I used it for days but there was a small problem that bugged me more than a small problem should.

The small problem is that you don’t really get back everything you drop on the ground. Some of it is bound to disappear before you get it. So you’re constantly leaking resources. My first work around was to just stockpile some LBN and not really worry about the leak. But then later, after I burned through my reserves again. I didn’t want to do that again and the whole thing bugged me.

I realized that I don’t like the principle of it. I have too many keys and they are clogging up my inventory and instead of dealing with the problem now, I’m kicking the can down the road. But when the problem comes around later it’s worse than it was before because there’s a cost to procrastination. It’s an unpredictiable cost, and sometimes a small cost. You incur an obligation to go back at some unknown future time and get what you used to own. Only now you hope that that game gods give it back to you, or at least most of it. And they do, mostly. But they could just as easily give it to another.

I have a view on procrastination and it is this: if you’re not sure that you’ll do a thing then procrastination is a signal that maybe it’s not the priority you thought it was. And the benefit of maybe-never having to do it outweighs the cost you will (definitely) pay for having put it off. But if you know for sure that you will do a thing then you must do it when it’s right there in front you and not put it off because it’s never going to get any easier, and if nothing else, you’ll pay the extra price of mental clutter for that open loop.

In that light, since I know I’m going to deal with this inventory problem, then I want to deal with it now. So I turned off 'key dropping' and let them fill my pack. I have to run back to storage to stow them relatively frequently, which is a pain. But as a result I have a guaranteed supply of LBN, which never runs out, or leaks even one single key. And I can explore any location I see fit at anytime, without concern for keeping implict promises to myself.

Luckily for you, I didn’t write this whole post just for the talky talk. I actually solved a problem, and I’m actually more pleased with myself than I have any right to be. So let me set the stage.

Here I am with an over stuffed backpack that’s got to be drained of keys regularly. That’s not the worst of it though. And maybe I even oversold how good this approach is because…​ since keys don’t stack, when you put them in storage you have to click once for each key. With a full inventory that’s almost 80 clicks to unload. Now, while they are stowed they will crumble, but they don’t magically crumble into stacks so you have to click once for each LBN to get it back out: another 80 clicks. But pulling from storage to inventory has a noticable delay, maybe about a second (for me anyway). So that’s hundreds of painful clicks.

I opened the game yesterday and thought, "I dun wanna clicky clicky." I looked at the "Exchange All" button on the storage window and I thought, "I wish there was an ALL ALL button that stores ALL the keys and returns me ALL my LBN".

<widget_description> (1)
<widget name="StorageWindow" factory="pawsStorageWindow" visible="no" movable="yes" style="New Standard GUI">

    <frame x="100" y="100" width="640" height="400" border="yes" />
    <title resource="Scaling Title Bar" text="Storage" align="left" close_button="yes"/>

    <widget name="Transact" factory="pawsButton" id="100" tooltip="Exchange items">
        <frame x="580" y="10" width="48" height="48" border="no" />
        <bgimage resource="MerchantTrade" alpha="0" />

     <widget name="TransactAll" factory="pawsButton" id="110" tooltip="Exchange all items">
       <frame x="580" y="62" width="48" height="48" border="no" />
       <bgimage resource="MerchantTrade" alpha="0" />

    <widget name="AllLabel" factory="pawsTextBox">
            <frame x="580" y="100" width="48" height="20" />
            <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
            <text string="ALL" horizAdjust="CENTRE" />

     <widget name="TransactSingle" factory="pawsButton" id="120" tooltip="Exchange one item">
       <frame x="580" y="114" width="48" height="48" border="no" />
       <bgimage resource="MerchantTrade" alpha="0" />

    <widget name="SingleLabel" factory="pawsTextBox">
            <frame x="580" y="150" width="48" height="20" />
            <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
            <text string="SINGLE" horizAdjust="CENTRE" />

+    <widget name="TransactAllAll" factory="pawsButton" id="111" tooltip="Exchange all items with this name">
+      <frame x="580" y="170" width="48" height="48" border="no" />
+      <bgimage resource="MerchantTrade" alpha="0" />
+   </widget>
+   <widget name="AllAllLabel" factory="pawsTextBox">
+           <frame x="580" y="218" width="48" height="20" />
+           <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
+           <text string="ALLALL" horizAdjust="CENTRE" />
+   </widget>

1 Skip all that stuff up there, new stuff at the bottom.

That adds the button and the label.

-   void TradeSelectedItem( bool all = false, bool single = false );
+   void TradeSelectedItem( bool all = false, bool single = false, bool allall = false );

        #define CATEGORY_LIST         10
        #define ITEM_LIST             11
        #define EXCHANGE_AMT          100
        #define EXCHANGE_ALL          110
+       #define EXCHANGE_ALL_ALL      111
        #define EXCHANGE_SINGLE       120
        #define VIEW_ITEM             150
        #define WITHDRAW_RADIO_BUTTON 1000
        #define STORE_RADIO_BUTTON    2000

-void pawsStorageWindow::TradeSelectedItem(bool all, bool single)
+void pawsStorageWindow::TradeSelectedItem(bool all, bool single, bool allall)
    pawsListBoxRow* row = itemsBox->GetSelectedRow();
    selectedItem = itemsBox->GetSelection();
    if ( row == NULL )

+	if (allall)
+	{
+		csString selectedRowItemName = GetColumnText(row, 5);
+		csHash<csString, csString> matchingRowItems;
+		// cache id and count of all 'name matching' rows
+		for(int i = 0; i < itemsBox->GetRowCount(); i++)
+		{
+			pawsListBoxRow* currentRow = itemsBox->GetRow(i);
+			csString currentRowItemName = GetColumnText(currentRow, 5);
+			if (currentRowItemName == selectedRowItemName)
+			{
+				csString currentId = GetColumnText(currentRow, 4);
+				csString currentRowItemCount = GetColumnText(currentRow, 0);
+				matchingRowItems.PutUnique(currentId, currentRowItemCount);
+			}
+		}
+		// trade each of the cached matches
+		csHash<csString, csString>::GlobalIterator iter(matchingRowItems.GetIterator());
+		while (iter.HasNext()) {
+			csString currentId;
+			csString count = iter.Next(currentId);
+			DoTrade(atoi(count),selectedRowItemName, currentId);
+		}
+		return;
+	}
    // If the merchant only has 1 item or if we want to trade all, no need to request the count from the user
    if (atoi(GetColumnText(row, 0)) == 1 || all || single)
            DoTrade(single?1:atoi(GetColumnText(row, 0)),GetColumnText(row, 5), GetColumnText(row, 4));

    currentItem = GetColumnText(row,5);
    currentID   = GetColumnText(row,4);

    pawsNumberPromptWindow::Create("Enter count", -1, 1, atoi(GetColumnText(row, 0)),
                                   this, "Count" );

THAT, my friends, is the added code for an ALL ALL button.

And THIS is what it looks like in action:

When I say 'All', you say 'All'

That is slick as shit. And if you needed someone to tell you that, you’re in the right place!

Who’s yo daddy?

Daniel P. Barron - 2018-05-21 05:23:31

I’ve probably left hundreds of thousands if not millions of keys in claims. Cool fix. Can’t say I’m in a hurry to try it, but many noobs will thank you!

hanbot - 2018-06-09 06:53:17

This was a pleasure to read and a neat fix idea, changes went smoothly over here. If you can figure out how to make storage eat/spit large (i.e., overweight-causin') chunks at a time in addition to the "all all" feature, it’d be a…​huge timesaver, definitely #1 on my botting wishlist atm.

Mocky - 2018-06-10 02:38:19

Daniel P. Barron: yeah, I’m all about making the noob life easier, for 'practical' reasons, or was it self-serving reasons.

hanbot: that’s a good idea. I’ve started to feel some of that pain myself. I’ve added that to the pipeline.

Also, beware the use of this powerful All All button. I’ve recently become aware that it is basically spamming the server with a potentially large number of requests and no rate limit. I’ve stopped using it for that reason with anything more than 10 items.

Also in the pipeline is a domestication of this wild feature.

Foxybot Enhancements Part 1: Better Claim Selection

Saturday, May 19th, 2018

If you want to hang around, you’re going to have to pull you own weight. Foxybot is no different. And foxybot is in fact pulling her own weight. But lets not settle for merely that. Lets tune this bitch up.

Ok, so foxybot is chugging along, diggin' & buildin' and whatnot. But often, too often, she grabs the wrong stick. I mean, she’s making a sincere effort. If you watch her you’ll see that when there’s only one staff within reach she’s fine, she does her thing with it and then moves on. The problem is when you put her in a situation where she is just surrounded by wood she just ends up groping for the closest one.

Figure 1. Foxybot, overwhelmed. Last night.

Nothing 'bad' ends up happening, it’s just a missed opportunity. You’re not gonna wring anything more from a stick that’s been already drained. And the latest one you erected, well, if you couldn’t manage to get ahold of it the first time around, how are you expecting to get it later on?

So lets investigate what’s going through her mind.

        if (actionToDo == ACTION_BUILD)		//process only messages in sequence with the exploring done
                psPersistItem incoming(message, psengine->GetNetManager()->GetConnection()->GetAccessPointers());

                if (     (1)
                        if (markerID == 0)		//retain first marker  (2)
                                markerID = incoming.eid;
                                markerPos = incoming.pos;
                                csVector3 newPos = incoming.pos;
                                csVector3 cPos = worldHandler::GetCurrentPos();
                                float d = csSquaredDist::PointPoint(cPos, markerPos);
                                float newd = csSquaredDist::PointPoint(cPos, newPos);

                                if (newd < d)	//update marker ID only if new marker is CLOSER to the character
                                {       (3)
                                        markerID = incoming.eid;
                                        markerPos = incoming.pos;

1 This will get called, and evaluate to true once for each marker in the area.
2 Her memory (i.e. markerID) is wiped between encounters, when she subsequently opens her eyes, she’s gonna grab the first shaft she sees.
3 Now if sees one that is closer, she’s going to grab on to that one instead.

I’ve got to take a second here and explain a little about how the game works. First you dig. Then, if successful, a stick with a little head on it appears somewhere within reach. Now, it looks like Foxybot had a sheltered childhood where the closest stick is always the correct stick. But that’s not the way it is in these parts. In fact, the more an area gets worked the more likely it is that the closest stick is the wrong stick.

I’m going to have her take note of each marker that’s already been processed. If she ever sees an old one again, she’s going to leave it alone.

csHash<EID, EID> spentClaims;  (1)

1 add a new thing to the header thing

And then check to see if it has been used up before:

        if (actionToDo == ACTION_BUILD)		//process only messages in sequence with the exploring done
                psPersistItem incoming(message, psengine->GetNetManager()->GetConnection()->GetAccessPointers());

                if (
+                       if (spentClaims.Contains(incoming.eid)) {  (1)
+                               break;
+                       }
                        if (markerID == 0)		//retain first marker
                                markerID = incoming.eid;
                                markerPos = incoming.pos;
                                csVector3 newPos = incoming.pos;
                                csVector3 cPos = worldHandler::GetCurrentPos();
                                float d = csSquaredDist::PointPoint(cPos, markerPos);
                                float newd = csSquaredDist::PointPoint(cPos, newPos);

                                if (newd < d)	//update marker ID only if new marker is CLOSER to the character
                                        markerID = incoming.eid;
                                        markerPos = incoming.pos;

1 Hey! Keep your damn hands off that one, jeez!

Now I need to actually save the claims in there.

void ExploreActivity::DoUseCombine()
	if (claimType.CompareNoCase("Tiny"))
	else if (claimType.CompareNoCase("Small"))
+	spentClaims.Put(markerID, markerID);
void ExploreActivity::DoTakeResult()
+	spentClaims.Put(markerID, markerID);

Here I’m saving the claim marker after the combine and after taking the result. In a perfect world I could do it only after taking the result. But either of these could fail, and so I’m covering both cases.

And ba-da-bing ba-da-boom…​ efficiency! What can I say, I’m an architect. And I do imports and exports.

Required Foxybot Fixes

Saturday, May 12th, 2018

With a successful build from source it was time for a closer look at that foxybot code. The actual chronology of my code changes I would liken to a drunken walk down a narrow alley with an unfamiliar game world as a brick wall on one side and an unfamiliar codebase on the other. I stubbed my toe on things and did my best to stumble past them. I didn’t actually know much about how the bot was supposed to behave. I knew how to build tiny claims myself (manually), I knew I was sick of clicking and I knew there was a bot.

At this point I just wanted to get it to work. What follows are the minimum changes I needed to make to get it to work for me.

Parse the Item Name Correctly

So as I mentioned before, it seemed like there was an easy fix to my motivating bot problem: replace a single character in the message parsing code. I made that change but it did not fix the problem.

        else if (text.StartsWith(CLAIM_PLACED))
                exploreFinished = true;
                noBuild = false;
-               size_t end = text.FindLast('!');
+               size_t end = text.FindLast('.'); (1)
                size_t start = CLAIM_PLACED.Length();
                csString thingName = text.Slice(start, end-start-1); (2)
                if (thingName.StartsWith("Tiny"))
                        claimType = csString("Tiny");
                else if (thingName.StartsWith("Small"))
                        claimType = csString("Small");
                else claimType = csString("Unknown");

                claimName = thingName;

                //and get the item name too if we are at it
                end = claimName.Find(" Exploration Marker"); (3)
                start = claimType.Length()+1;
                size_t length = end - start;
                itemName = claimName.Slice(start, length);

1 My edit
2 thingName declared
3 itemName parsing

I looked at that parsing code some more and I came to see that the thingName shown above was later used to find the itemName which needed to be correct for the bot to build the claim. This code, when parsing a message such as:

Eulora Dig Message
You placed an Tiny Rickety Reeds Exploration Marker.

assigned a value to thingName such as:

Tiny Rickety Reeds Exploration Marke

which led to the itemName being assigned:

Rickety Reeds Exploration Marke

So there was an off by one issue at the end of the string. There also happens to be a -1 at the end of the thingName assignment line. I deleted it and sure enough the value assigned to thingName recieved it’s proper final letter and itemName parses out to:

Rickety Reeds

Success? No. The bot still locks the claim instead of building it.

Find the Build Item

Ok, so I take a stroll to the code where all that claim locking shit is going down and I notice that the item required to build the claim is not being found, eventhough I have it in my inventory. The FindItemSlot method is being passed a value of false for anywhere. Well I’m not aware of the full implications of this, but at this point I’m ready to 'look anywhere', so I make it true:

-		psInventoryCache::CachedItemDescription* from = worldHandler::FindItemSlot(item, false);
+		psInventoryCache::CachedItemDescription* from = worldHandler::FindItemSlot(item, true);

		if (!from || from->stackCount < quantity)
			//not enough items to build claim, so just move on (don't lock tinies and smalls!!!)
			Notify1(LOG_USER, "will go on");
			noBuild = true;
			return true;

But still it’s not working.

Equip the Scroll Correctly

Now it is failing to equip the scroll. The code looks like this:

if (!worldHandler::IsInBrain(scrollName))               (1)
        if (!worldHandler::EquipRecipe(scrollName))     (2)
                        OutputMsg(csString("Missing blueprint for the claim!"));
                        //noBuild = true;
            return false;

1 test if it’s equipped
2 equip it

I know something’s wrong here immediately because that missing blueprint message has never displayed. Testing this out reveals that IsInBrain always returns false, even when it’s equipped, and that EquipRecipe always returns true, eventhough it’s failing. So Let’s fix them one at a time:

bool worldHandler::IsInBrain(csString itemName)
	pawsSlot* slot = FindInventoryItemSlot(itemName);
	if (slot == NULL)
		return false;
		return (slot->GetID() == PSCHARACTER_SLOT_MIND);

Well I’ve already had a run in with a different Find method, so I’m suspicious of this one. I noticed this worldhandler class has a method called GetBrainItemName. Seems to me this whole thing can be a one liner:

bool worldHandler::IsInBrain(csString itemName)
    return GetBrainItemName() == itemName;

I took it for a spin and IsInBrain is now working correctly: returning false only when the scroll is actually missing. One down, one more to go. So I moved on the the actual equipping method.

I saw that EquipRecipe contains an additional check so that the equip will be attempted 'only if truly needed', as the comment says. I don’t know about all that, if I call EquipRecipe I damn well want it equipped. I decided to just comment out that test.

bool worldHandler::EquipRecipe(csString itemName)
	psInventoryCache::CachedItemDescription* slot = FindItemSlot(itemName, true);
	if (slot == NULL)
		return false;

-	if (slot->containerID != CONTAINER_INVENTORY_EQUIPMENT) //equip only if truly needed
+	//if (slot->containerID != CONTAINER_INVENTORY_EQUIPMENT) //equip only if truly needed
		MoveItems(slot->containerID, slot->slot, CONTAINER_INVENTORY_EQUIPMENT, PSCHARACTER_SLOT_MIND, slot->stackCount);

	return true;

Aaaaaaand…​ SHAZAM! We have lift-off. Foxybot’s jukin' and jivin' and building those claims. Make me dat money, daddy’s gotta make a livin'!

Diana Coman - 2018-05-19 07:27:25

Bwahaha, those are fun to read. Foxybot has indeed all sorts of warts and what-nots due to its already-longish history of having to put up with a rather idiotic "protocol" + all sorts of changes. I guess a little bit of history might even give some ideas what these are:

At any rate, it’s meant to be changed and beaten into useful shape, so keep at it!

Mocky - 2018-05-19 12:18:13

Oh hey, thank you.

wyrdmantis - 2018-05-27 11:14:26

Hi Mocky, many thanks for this. But for me it’s not working. i’m getting:

src/client/foxybot/botactivity.cpp: In member function ‘void ExploreActivity::DoUseCombine()’:
src/client/foxybot/botactivity.cpp:569:39: error: no matching function for call to ‘csHash<EID, EID>::Put(EID&, csVector3&)’
src/client/foxybot/botactivity.cpp:569:39: note: candidate is:
In file included from /home/wyrdmantis/dev/cs-forupload/include/csutil/strhash.h:23:0,
                 from /home/wyrdmantis/dev/cs-forupload/include/csutil/strhashr.h:23,
                 from ./src/client/psengine.h:23,
                 from ./src/client/globals.h:26,
                 from src/client/foxybot/botactivity.cpp:10:

Maybe it’s a trivial error but i know nothing about C++, also i’m on Ubuntu.

Mocky - 2018-05-28 00:25:46


i think this comment was meant for Foxybot Enhancements Part 1 since there’s no spentClaims in this post.

In that post:

  1. spentClaims.Put does not have markerPos as an argument. Perhaps you typed it in wrong.

  2. spentClaims.Put is not within 100 lines of where your compiler error is. Perhaps you put things in a different place.

Maybe have a closer look at those things.

Also, don’t let the fact that you know nothing about C++ stop you, I don’t.

wyrdmantis - 2018-05-30 15:23:26

LOL markerPOS instead of markerID. My damn eyes…​ Anyway, now works! Thanks, mate!

Mocky - 2018-06-01 04:04:03

Hey, nice to see it works for you.

Building Eulora on Windows 10

Wednesday, May 9th, 2018

Having decided to fix a bug, I took a look at the Eulora wiki page for Windows.

This is not a guide to a correct Eulora build on Windows. It’s the story of how someone did it while knowing virtually nothing about the tools, language or project. For all I know, it’s the worst way to do it that ends up working.

I followed all of the wiki instructions, which are quite detailed, as closely as I could manage. I’ve never used Visual C++ before so it was difficult to know when I was making mistakes. Once I had done all the things, I ended up with about 800 compile errors that didn’t seem covered by any of the wiki page suggestions.

Visual C++ 2010 Build Output
src/common/paws/pawsmanager.h(657): error C2146: syntax error : missing ';' before identifier 'int64val'

There were hundreds of compile errors like the above. When I looked at the lines being flagged by the compiler, they looked like simple variable declarations with an unrecognized type. For example:

    int64_t int64val;

I did some searching on that error and was led to believe that int64_t is a type used on linux and that if you want to use it on windows you have to add a typedef for it. Ok, well it seemed to me that primitive types ought to be defined once in some central location. Unfortuantely, I don’t know how the project structure or build works so I tried adding the prescribed typedef to the 'problem' file, right before the error:

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

The result: ~108 fewer compiler errors. Yay! I considered this solid progress and continued to attempt fixes for whichever compile error would appear first in the build output because, with that many compile errors, they are obviously cascading.

The next 'first' compile error turned out to be for that same missing type. That bugged me because I knew for a fact this thing can get fixed once rather than in multiple places and who knows how many times it will turn up. I made an attempt at that single fix, encouraged by:

/* config.h files are created by autoconf/automake in the gnu world...
 * So You have to set up your own for visualc, which is done here
 * This version is currently set up for windows (VC6/7/8)

Defining it there as a stab in the dark failed to fix it though. Undeterred, I returned to inserting my "solution" into every src the build presented:

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

And in four shakes of a lamb’s tail all teh int64s are satisfied. On to the next:

Additional Visual C++ 2010 Build Output
src/common/rpgrules/psmoney.cpp(57): error C2146: syntax error : missing ')' before identifier 'SCNd64'

The offending code looks like:

    if (sscanf(moneyString,"%"SCNd64",%"SCNd64",%"SCNd64",%"SCNd64"",&bitcents,&denarius,&argents,&coppers) != 4)
        bitcents = denarius = argents = 0;
        if (sscanf(moneyString,"%"SCNd64"",&coppers) != 1)
            coppers = 0;

This one took me longer to figure out. I was thrown off by the nested quotes, because I didn’t know that quotes could nest. And how does nesting quotes like that even make any sense? Anyway, I tried several things and I got several clients that would build but then crash after login (presumably during the initial parse of money). Eventually I discovered that SCNd64 is a thing. Maybe M$ didn’t know about it either and I ought to have defined it.

src/common/rpgrules/psmoney.h line 34
#define SCNd64    "lld" // <-- Mocky's clueless hackery for M$ compile

I put it in the header file because that’s where the other #defines were located. That worked but I wasn’t done yet. Seems I had to deal with one more complaint:

Yet More Visual C++ 2010 Build Output
src/client/gui/pawsslot.cpp(393): error C3861: 'atoll': identifier not found

Pointing me to:

PlaceItem( icon, mesh, material, atoll(  count.GetData() ), atoll(quality.GetData() ) );

Some poking around in that same file reveals this clue near the top:

#include <stdlib.h>	//atoll//

A quick perusal of stdlib.h yields a handful of ato functions and, as expected, no atoll. A few of them even feature the return of our good buddy __int64. I unearthed some stackoverflow dude named nos posting that MSVC has _atoi64 instead of atoll. Lo and behold, _atoi64 is right there in stdlib.h, so I made my edit:

// On the following line, Mocky renamed `atoll` to `_atoi64` for M$ compile
PlaceItem( icon, mesh, material, _atoi64(  count.GetData() ), _atoi64(quality.GetData() ) );

With that done, the build succeeds and the client runs without crashing. HUZZAH!

Well, it crashes sometimes. It crashes anytime the number picker shows up when you want to move some number of items in your inventory. I can move just one, or the whole stack no problem. But if I pop up the number picker, when I subsequently click Ok or Cancel it crashes. I spent an hour on that one. I couldn’t get it to run in the VC++ debugger but I was able to attach a sysinternals debugger and even looked at my first core dump file. Those were no help. I couldn’t find the cause.

I let that issue be because I have a work around and I didn’t come this far to shave a yak, I came to build foxybot. And it was time to get started.

mihi - 2018-05-19 10:52:59

You probably figured it out by yourself, but for the other readers of the blog: In C/C quotes cannot nest either. What you are seeing here is the C/C way of (compile time) concatenating string literals, combined with a creative way of (not) using whitespace.

When you have

#define FOO "123"
#define BAR "456"
#define BAZ "890"

you can write


to get "1234567890" (as a single string literal).

In Java you would use the + operator for that (as you do for runtime concatenation of strings).

Mocky - 2018-05-19 12:16:16

Oh man, that makes so much more sense that what I was thinking. Also explains some other things I’ve seen. Thanks.

Prelude to Hacking on Eulora

Sunday, May 6th, 2018

I’m posting some notes regarding my recent hacking activities on the Eulora client. This hacking has mainly been bot stuff: some fixes and enhancements. As a prelude to some detailed bot surgery posts, consider this the story of how I found myself on this road.

I read about this game called Eulora which purportedly sports a bitcoin economy. Intrigued, I set about to see this for myself. The Eulora wiki has an install guide for Windows so I decided to use a Windows machine I’ve used for previous games. The guide has instructions for compiling the Eulora client from source, but also points to a binary distribution which is what I went with. I have no comments about installing the binaries other than to say it was quick and problem free.

Having installed Eulora 0.1.2, I logged in and set about figuring what’s what. From what I saw, figuring things out seemed central to the game. I figured out how to do some digging quickly enough. But it took me a big longer to figure out how to actually extract anything from my dig. Once that puzzle was cracked, I set about walking the territory digging here and there to see what could be found.

A helpful player gave me a noob quest and after its completion offered to buy a quantity of some specific type of reed I may happen to dig up. It took me some time to find a good dig location for these reeds but once found, I did a large number of these digs manually. It seemed there was a bot built into the client that would grunt out those digs for me, but I decided to make sure I had a good grasp on the situations the bot would be required to handle before trying to activate that machinery. After all that clicky-clicky, I was well ready to test drive that bot.

Once I figured out the parameters to make Foxy’s Bot dig, I was off to the races. Except not quite. The bot would dig, but then immediately lock the claim and move on instead of extracting the resources. I spent a while trying different parameters and reading the help. In short order I decided to go to the source. The wiki helpfully had a link to download the client source code.

A little investigation revealed the following

else if (text.StartsWith(CLAIM_PLACED))     (1)
        exploreFinished = true;
        noBuild = false;
        size_t end = text.FindLast('!');    (2)
        size_t start = CLAIM_PLACED.Length();
        csString thingName = text.Slice(start, end-start);
        if (thingName.StartsWith("Tiny"))
                claimType = csString("Tiny");
        else if (thingName.StartsWith("Small"))
                claimType = csString("Small");
        else claimType = csString("Unknown");

1 Parsing the beginning of the line (where CLAIM_PLACED = "You placed an ").
2 Parsing the end of the line.

The above code snippet is a chunk of the bot’s message parsing code. Below, the message being parsed:

Eulora Dig Message
You placed an Tiny Rickety Reeds Exploration Marker.

So then the problem was clearly that the bot was expecting the line to end with '!' when the actual server message end with a '.' That made the bot unable to recognize my tiny claim, instead falling though to the "Unknown" claimType. Since the bot didn’t know know how to deal with that type of claim, it just locked it and moved on.

Granted, I do not know C++. However, replacing a single character and re-compiling sounded trivial.

Thus began my Eulora hacking journey.

Daniel P. Barron - 2018-05-19 01:54:18

Seriously?? It was a single punctuation!? Bleh.

Diana Coman - 2018-05-19 07:04:59

Ahaha, well done! That ! must have morphed into a . at some cleanup.

You might find the posts on Foxybot helpful to figure out a bit what goes on and how. This for instance:

As to C: you can certainly write the client in whatever you want. And for that matter Ada would make for a much cleaner and saner code for sure.

Mocky - 2018-05-19 12:34:58

Great link re bundling activity, thanks. OMG I wish I had seen it last week before I wrote a loot activity for all the keys / lbn I had been dropping.

I need to go though your archive more closely.