June 26, 2018

Eulora's Own CR50

Filed under: Eulora — DianaComan @ 9:29 p.m.

Possibly similar to the CR50 item Stanislav has been torturing recently, a green "Microchip" of unknown internals and dubious usefulness has finally been teased out of the reluctant and downright hostile Euloran soil. It took only a bit more than 3 years of pounding said soil.

On the plus side, it seems to be quite valuable at somewhere around 110`000 ECu (aka 11`000 satoshi atm) base value. On the more usual *other* side, there is no known use for it at the moment1 and it came out very low quality too, not to mention potentially booby trapped for all one knows:

Eulora's own CR50! Microchip!!1

The floating Microchips!

At any rate, I hereby dedicate this very first lot of Microchips to Stanislav Datskovskiy. May all his quests be successful and take considerably less than it took me to find this item!

  1. It wasn't needed until now, which is of course "no indication of future performance". 

June 10, 2018

Chasing the Elusive Euloran Quality

Filed under: Eulora — DianaComan @ 3:45 p.m.

Quality of items in Eulora is a big thing - it brings in more money for whoever can deliver it and it also gives one better dings. Or at least better chances at better dings1, it would seem. Welcome to the murky shores of Eulora, this land open to all and totally opaque to most2.

The most recent update3 was cheered for finally making it possible to actually do expensive stuff in a few minutes as opposed to a few months. After which there was silence and renewed confusion as to what is what and how much any darned thing is worth. Quite a lot of discussion ensued in the #eulora irc chan although mainly between me and Mircea Popescu as the rest of the veteran players4 seem to either have no clue or have no appetite for talking at this stage. Hopefully they'll find one if not both at some later point before totally sinking out of sight, unknown and unmissed for lack of actually being there, who knows.

While discussions in logs are all fine and good, they tend to be difficult to find and retrieve at a later time. So for my own future needs and potentially for others' use, I'd rather jot down here a few data points on all this. The most recent problem is that apparently *everything* works now as a quality sink: mining eats up crafted items of 4k quality to give back harvestables at 900q while crafting wants also to eat harvestables at 900q to possibly give something back at all (not even clear if >900q, at that; a reported craft that "almost works" brings down q from 90 to 84). After all sorts of experiments with my team of noob and not-so-noob helpers, I suggested that people might simply be approaching the issue here from the wrong end, a sort of trying to dig their way out of the hole instead of making a ladder to climb back up. I know that a big-enough dig can indeed get one out of any hole through the other side, but Eulora's rather short on shovels at this very moment5. So how about that ladder then? It starts with more experimenting and concrete data, such as this, collected over only a few crafting runs of Slag (base value 677):


Tinkering Rank Sortage Rank Blueprint Quality Bundle Quality Output
1265 448 133 664 0 Slag + TPF q401
1265 448 67 664 0 Slag + TPF q285
1265 448 1 664 4-5 Slag + TPF q32
245 77 133 664 2 Slag q213 +TPF
245 77 67 664 3 Slag q151 + TPF
74 67 133 664 2 Slag q198 + TPF
74 67 67 664 4 Slag q141 + TPF

All the runs had remarkably similar results (same quality always, same number of slag items always except where it appears in table as 4-5 i.e. sometimes 4, sometimes 5) so I simply recorded one result for each combination. The bundles there are all identical and made by the highest skilled crafter as she can pack most value into the bundle. Specifically, each bundle is made out of 17 Flotsam q192 and 11 Shiny Rock 187q. For one thing, this suggests that the highest crafter packs the ingredients for almost 4 slags into one single bundle. For the other, it means that any output < 190q is anyway a sink of quality, no matter how one looks at it. And looking at it, there is some support on both points: 4 slags are reliably obtained by highest skilled crafter with a blueprint of lowest quality possible, 1. They are however q32 meaning that quality was severely lost in the process. When quality is not lost by the highest skilled crafter, it is however totally transfered to numina it would seem: all output is numina and no slag at all.

Considering the results of the other two crafters, the most interesting part is that they can actually get Slag of higher quality than the inputs that went in: for the same ~q190 harvestables used as input, they get reliably outputs >q150, even close to q200 in one combination! So for one thing it's certainly NOT true that crafting is a sink of quality, quite on the contrary: it clearly creates quality of output - the only trouble is however to match the sort of output one wants (i.e. product not so much numina at the moment).

The even more interesting bit suggested by this teeny tiny amount of data is with respect to just how much of the actual value going in is then obtained back as Slag rather than numina. The input value is roughly 677*6.64 = 4495 ignoring the value of the blueprint (which is not much at 67*1.33 maximum in there). Highly skilled crafter gets precisely 0 in Slag out of this and all of it in numina unless they go for low quality when they get between 4*677*0.32=866 and 5*677*0.32=1083 so anyway about a quarter maximum. By contrast, middle level crafter gets 2*677*2.13=2884 or 3*677*1.51=3066 at lower quality so about 70% of the input value. And lower level crafter gets even more at their lower quality 4*677*1.41=3818 (or 2*677*1.98=2680 for their higher quality).

Before jumping to any conclusions, I'll add that I'm quite sure that the data captured there (i.e. Tinkering and Sortage skill ranks, blueprint quality, bundle quality, item) is quite unlikely to really capture ALL factors that influence the outcome. For one thing I can tell for instance from long experience with those characters involved that the highest skilled crafter tends to be rather unlucky in everything she does, while the middle skilled crafter tends to be quite the opposite - lucky and then some more.

With the above caveats in mind and other potential limitations quite obvious6, a conclusion is to be drawn and that is that at least on such low base value items beginner and middle level crafters are actually in a very good position to bump up quality and make a killing - if only they do buy the bundles of a highly skilled crafter! In turn, their output is likely to actually help highly skilled crafters as it gives them more quality as input for more valuable crafts presumably.

As for the highly skilled crafter, it would seem to me that she would really need to somehow pack in at least 4 times the value of Slag at her output quality of 401 in order to stand a chance of getting q401 Slag. That means she needs a bundle of 4*677*4.01=10859 so about 3 times more than what she made for this little experiment. Either she gets that from an even higher crafter (who can pack more of same q harvestables into one bundle) or she uses harvestables at quality at least 600 by the looks of it. Good luck with that my lovely, as q600 harvestables will come at a hefty premium at least from my wares - if they even come at all as it's not all that clear at this moment that such stocks can be replenished if used!

Other than that: isn't it marvelous how much one can get even from only a few numbers? If only they do bother to get those numbers in the first place, of course...

  1. The term of art in Eulora is "pop" as in "1002mn pop, wow!" i.e. you put in 10mn and got 1002mn out of it, you lucky bastard. 

  2. That post was written in 2015, yes. Not much changed since then in terms of players' understanding of Eulora's actual workings it would seem. Poor Eulora, so totally incomprehensible, so entirely misunderstood... 

  3. 'Tis not even by far the only update Eulora went through so far. And all updates introduce changes that so far seem to mess up players' previous plans something fierce. 

  4. Noobs have yet some other things to figure out before standing much chance with this really. 

  5. And since I'm not that young anymore in Eulora either, I can tell you that I've subsidized this sort of approach at least once before and I don't want to do it again, ever. It was costly, very very costly. 

  6. Very small sample is the most obvious but you really are better off thinking for yourself on this. 

June 5, 2018

The Lack of Dust - A Very Euloran Problem

Filed under: Eulora — DianaComan @ 6:23 p.m.

Collected Dusts in Eulora are a thing - a very useful and currently very much required thing. Consequently, according to the usual Euloran workings, Collected Dusts are also... rather sorely needed and totally missing from the market. In other words, Collected Dusts are hard to get, needed by the ton, while also unknown as to actual value - the usual stuff. And so Foxy set up to... get those1, since she is anyway best at Lapidary2.

At first, the recent update seemed as if it might help for once - first level numina such as Dusts are normally obtained as a byproduct of crafting in the respective line. That would mean that one gets tons of Dusts simply by clicking something in the Bouquinism line. And that is... true of sorts but the trouble is that Bouquinism is a bit special and most of its items give stuff-other-than-numina (blueprints mostly). Moreover, while the recent update seems to have turned skilled crafters' clicks into mainly-numina-producing clicks, this does not really hold for Bouquinism! Click on Maculature and instead of loads of Dusts, one still gets loads of... Little Bits O' Nothing. What do?

Well, whenever the rule doesn't work, one needs to find... the exception, of course. For various definitions of find that might involve workarounds and workthroughs and workaboves and workbeyonds and workinbetweens - more generally speaking: WORK. So work it is then, onwards! In this case the work is mainly to figure out how to make mites in large quantities through lots of smaller clicks since apparently I don't have enough input stuff to get more than a few mites through huge-quality single click sort of thing.

First, I tried all sorts of combination-clicking on Maculature in the vain hope that Bouquinism might still sort-of-work like the rest and spit some Dusts: high q bundle with total noob -> ton of LBN (Little Bits O' Nothing) and nothing else; high q bundle with high q bp (recipe) and Foxy's click -> ton of Nothing just the same; you name it, I tried it -> no, nope and nono.

Second, I made then some Bird's Nest and Gin, poured it over that WPL3 that nobody wanted yesterday but wanted today4. That made the ECV5 in tiny quantities and ...DUSTS! In... some quantities because on one hand I did get a few thousands of them but on the other hand Foxy needs at least 3300 for one single Lapidary click that makes usually only about 20-30 Mites so by this measure... still totally and utterly stuck (and no, making some million of Bird's Nest and Gin is not a useful "solution"). What do?

Third, I got a total noob to look at Foxy's Toil recipes (the ones that make Mites out of Dusts). And what do you know? Noob can make a bundle with one single Dust and one single WOA (Water of Anamnesia - another thing that seems to be rather wanted and in short supply at the moment). So noob was set with the bundling bot to make a few hundred bundles that came out an actually reasonable ~1300 quality because Foxy's Dusts are high quality and Foxy's ancient WOA are ALSO high quality. Wonderful, except for a teeny tiny problem: clicking a 1300 quality bundle with a high quality Toil bp seems to end up for Foxy in... no Mites, only Gem Dusts (Lapidary numina). On the other hand, clicking it with the noob gets Mites, but poor, sickly and stinky ones - frightfully low quality, not to mention basically wasting all that Lapidary experience on the unsuspecting noob. Once again: WHAT do?

Fourth, got the big mixing guns out of Foxybot: blueprint quality doesn't have to be huge if one also has6 quality 1 blueprints of the same type! Some many clicks and 2000 mixings later, there we go, found some sort of combination that works! Foxy reliably gets at least 10 mites per click - not to mention many more when she pops or mini-pops - at a quality above 500 and she has *hundreds* of bundles and blueprints to click right now!

And the cherry on the above delightful cake is that it takes only 2 of those clicks for Foxy to rank up in Lapidary. Combined with the bot's powerful crafting-with-bundle7, she basically got 100 ranks up in one hour today and scooped up the book-prize for being first to reach 600 rank in Lapidary!

Onwards and upwards, let's reach that 800 Lapidary before tomorrow's update 'cause I'll be busy mining: there are new problems to solve, troubles to find and generally millions of coins waiting to be picked up, scooped out, teased away from Eulora! If only, of course... you actually work at knowing how to do such a feat. Do you?

  1. By now I can say I have a thing for... prickly problems let's call them, what can I do. 

  2. The crafting line that works on numina such as Dusts, transforming it from lower levels to higher levels (e.g. from Dusts to Mites and so on). 

  3. Worthless Putrid Leather 

  4. Ha, HA! 

  5. Extremely Creaky Vellum 

  6. by means of previous noob-clicking, at another time, there's nothing totally useless if only done correctly in Eulora, you know? 

  7. No, you don't have this working anymore? Awww. The help and the code have been there for ages, waiting for... you . Where have you been? 

May 24, 2018

A Tiny Stab at a Little Pricing Problem

Filed under: Eulora — DianaComan @ 10:57 p.m.

To start off, here's Foxy making disgusting goop in large quantities1:

Why is she making that? Well, for profit, what else. With each click, she's transforming 2852 ECu worth of rock-and-what-not into 4324 ECu worth of Disgusting Goop. That might not sound like much, except for the fact that it is effectively a 50% added value just like that in a few minutes (and while I sleep, yes, how else).

The above concrete numbers give me added ECu but also a way of approaching the ever-thorny euloran issue of pricing stuff. Only yesterday it would seem I failed at pricing some WPL correctly since the market (that had ASKED for WPL specifically) decided that... it was too expensive to bother buying it! So no sale made and a fee to pay instead2 but also a very clear and concrete thing to point to next time when anyone asks for WPL or complains that they don't have it.

Regardless of the market being there apparently completely lost in terms of what is how much and why would WPL cost more than dirt-cheap, lowest quality basic stuff, it's still worth to look again at some fresh data and see what prices make sense at all. Taking the Disgusting Goop above, let's calculate precisely what went in and what came out:

input: bundle of quality 595 + blueprint of quality 120 = 5.95*470 + 1.2*47 = 2852 ECu (quality adjusted base value3 )

output: 8 DG of quality 115 = 8*1.15*470 = 4324 ECu (quality adjusted base value)

Output / input = 4324/2852 = 1.51 (i.e. 151% or 51% gain).

Considering that the DG bundle is made only from harvestables4 it follows that Foxy simply can NOT sell those harvestables (rf, cr and sm) at anything less than 150% because at anything less than that she'd be better off using them as input to craft!  Notice also that the basic resources there (rf+cr) make only 2 thirds of the bundle, with sm the other third. For this little exercise I ignored the distinction between basic and non-basic harvestable but mining experience screams loud and clear that non-basic resources ARE harder to get in same quantities and same qualities. Which is not at all surprising given that they have higher value, doh.

As usual, in practice things are indeed a bit murkier, as all sorts of considerations quickly come stomping in: this 50% increase might be obtainable only at this specific sweet spot or only for this specific combination etc. Nevertheless, it IS some concrete data point in a sea of unknowns, so I'll stick to it for now. I'll add also that Foxy is a very skilled crafter (possibly even the top crafter at the moment) and it is for this reason that she *has this option* to make a significant profit just by crafting. Other players might find that the highest profit they can make out of harvestables really is by selling them at less than 150%, why not?

As Foxy's rather busy earning about 1500 ECu every couple of minutes for now, let's leave her aside for a moment and ask simply: what are *you* earning every couple of minutes and what are *your* options really?

  1. Yes, the red messages are all there one on top of the other because the bot is firing requests at the server without pause for clicking, eating, thinking or any of the other human-vices. 

  2. There is a fee for auctions without sale to discourage spam of useless auctions. 

  3. Also known as qabv and in any case the de facto *minimum* value of something in Eulora since that's what you can always get if you sell the item to the merchant NPC (i.e. to S.MG directly). 

  4. harvestables are obtained directly from euloran soil as a result of "mining" activity aka /explore + build; by contrast, craftables are items crafted as above, possibly from harvestables or other craftables 

April 17, 2018

RFC: Eulora's Communication Protocol (EuComms)

Filed under: Eulora — DianaComan @ 2:59 p.m.

This is a request for public comment (questions, critique, discussion etc) on the current version of Eulora's protocol for client-server communications that has been in works for a while now. Once this public discussion phase ends, the most significant aspects of this protocol will be effectively set in stone, since the procotol is central to any working client for Eulora. Consequently, your chance at having any significant input on it is *now* and only now. Any questions or feedback on it as well as any suggestions or requests related to it are most welcome, warmly appreciated and thoroughly considered *now*. By contrast, any whining and bitching over it at a later time will likely have at most some entertainment value - my entertainment that is. In fewer words: speak now or suffer later, your choice.

1. EuComms: Overall Goals:
1.1. All communications between clients and server to be encrypted.
1.2. Clients to be able to receive from server any data they lack (including maps, skins, sound or video content etcetera), on demand.
1.3. Clients to be able to choose and adjust both the level of security and their volume of communications with the server, as they will ultimately have to pay for the load that they generate.

2. EuComms relies on:
2.1. RSA with Keccak-based OAEP (via EuCrypt) for initial communication of OTPs (Serpent keys).
2.2. Serpent (via EuCrypt) for general communications.

3. Structure:
All communications between server and client will consist of packets up to 4096 bits in length, encrypted either via eucrypt.RSA or eucrypt.Serpent. The complete list of all such packets is included below.

Packets the client may send to the server:
3.1. Initial connection to server : client encrypts with the server's public key and sends to the server a hello message; constructed as follows : following conversation in #trilema log, this hello message would actually end up multi-packet as it has to include the client's public key (n,e so that's currently 4096+2048 bits) instead of the id at 3.1.5 in the structure below:
3.1.1. Octet 0 - the length of the message in octets (43 or 76);
3.1.2. Octets 1 to 8 - the string "EuLoRa";
3.1.3. Octets 9 to 10 - the major and minor versions of the communications protocol that the client wants to use;
3.1.4. Octets 11 to 42 - the client ID string, which will be equal to the eucrypt.keccak hash of the client binary. All client providers will be required to register all their ID strings with Minigame ; connections from clients with unknown ID strings will be rejected. Players will be notified of and helped to identify changes in their client software.
3.1.5. Octets 43 to 75 - the account ID string. If this field is omitted the server will create a new game account for the client.

3.2. Data (client sent)
3.2.1. Octet 0 - the length of the message in octets (multiple of 16 octets);
3.2.2. Octet 1 to 2 - descriptor of the type of data being sent (see annex A for datatypes);
3.2.3. Octet 3 to 5 - three octets ID of the item being sent;
3.2.4. Octet 6 to n - payload.

Packets the server may send to the client:
4.3. Data (server originated)
4.3.1. Octet 0 to 4 - the length of the message in octets (multiple of 16 octets, in principle limited to 65536 altogether and practically in the kbs anyway);
4.3.2. Octet 5 to 6 - descriptor of the type of data being sent (see annex A for datatypes);
4.3.3. Octet 7 to 10 - four octets ID of the item being sent;
4.3.4. Octet 11 to 16 - six octets counter of the chunk being sent (this limits downloadable items somewhat);
4.3.5. Octet 17 to n - payload.

Annex A -- datatypes in client-server communication

NB: all data types below can in principle be sent by both client and server; however, data sent by the client is essentially a request to the server (i.e. it’s up to the server to decide whether it is valid and/or has any effect and/or what effect in game) while same data sent by the server is feedback/information (i.e. it reflects something that *has happened/exists already*).

In fewer words: client proposes, server disposes.

A.0 Basic types (used throughout the rest of sections in this Annex A)
A.0.0. char - character value on 1 octet
A.0.1. text - n*char where n will ALWAYS be specified clearly, right next to each and every text variable passed around
A.0.2. int8 - integer value on 1 octet
A.0.3. int16 - integer value on 2 octets
A.0.4. int32 - integer value on 4 octets
A.0.5. int64 - integer value on 8 octets
A.0.6. float - real value on 4 octets

A.1 Connection
A.1.1 Set of Serpent Keys

  • int8 - number of keys in this set, n;
  • n*(4*int64 + int32) octets - n Serpent keys (32 octets each + 4 octets ID for each, calculated as keccak hash of the 32 octets);
  • int8 - 1 for server use, 2 for client use, anything else undefined currently.

A.1.2 Request Serpent Keys --> response is a "Set of Serpent Keys" (A.1.1)

  • int8 - number of keys requested;
  • int8 - value 1 for server use, 2 for client use, anything else undefined currently.

A.1.3 Choose Serpent Key

  • int32 - ID of the key that will be used for communications from now on (depending on the key's set, it'll be used for server's or client's messages).

A.1.4 Burn & Choose Serpent Key

  • int32 - ID of the key to remove from usable sets;
  • int32 - ID of the key to use for future comms;

A.1.5 Unknown/Malformed Message received

  • int64 - id of message that was not understood.

A.2 File Transfer
A.2.1 File Information

  • int8 - length of file name in octets, n
  • n*char - file name (string)
  • int8 - file type
  • int64 - octets per unit
  • int64 - file size in unit given above
  • int32 - file hash (keccak)

A.2.2 File Content

  • int32 - file hash (keccak)
  • int64 - octets per unit
  • int64 - file size in unit given above
  • unit*file_size*int8 - file content

A.2.3 Request File Information --> response is a "File Information" (A.2.1)

  • int8 - length of file name in octets, n
  • n*char - file name (string)

A.2.4 Request File Content --> response is a "File Content" (A.2.2)

  • int8 - length of file name in octets, n
  • n*char - file name (string)

A.2.5 Request File Information --> response is a "File Information" (A.2.1)

  • int32 - file hash (keccak)

A.2.6 Request File Content --> response is a "File Content" (A.2.2)

  • int32 - file hash (keccak)

A.3 Chat
A.3.1 Chat Public

  • int64 - id of speaker
  • int16 - length of string being said
  • n*char - string being said

A.3.2 Chat Private

  • int64 - id of target for this chat
  • int64 - id of speaker
  • int16 - length of string being said
  • n*char - string being said

A.4 Character Actions & Activities
A.4.1 Basic action

  • int64 - id of subject
  • int64 - id of object
  • int32 - id of action attempted (client-sent)/performed (server-sent) --> see Annex B for list of current basic actions

A.4.2 Item movement

  • int64 - id of subject
  • int64 - id of object
  • int64 - quantity (stack count) to be moved
  • int64 - id of destination object (i.e. own char's id for "pickup", container ID for move to container, sector id for "drop" or move from container to world, other char's id for "trade" or "store" etc.)

A.4.3 Item movement with specified slot

  • int64 - id of subject
  • int64 - id of object
  • int64 - quantity (stack count) to be moved
  • int64 - id of destination object (i.e. own char's id for "pickup", container ID for move to container, sector id for "drop" or move from container to "world", other char's id for "trade" or "store" etc.)
  • int64 - slot id

A.4.4 Activity --> this is meant to be sent by the server;

  • int64 - id of activity
  • int64 - duration (in seconds)
  • int64 - start time (unix format)
  • int8 - status: 0 -> finished/success; >0 -> ongoing / scheduled; <0 -> failed / aborted

A.4.5 Request Activity Information --> response is "Activity" above (A.4.4)

  • int64 - id of requested activity

A.4.6 Train

  • int64 - id of character
  • int64 - id of skill to train

A.5 Environment & Graphics
NB: "requests" here are not actions of the character in the game as such but rather supporting raw API for the client; for instance, requests here include obtaining the id of own character or available maps.

A.5.1 List of Sectors

  • int64 - number of sectors, n
  • n*int64 - list with ids of available sector

A.5.2 Request list of sectors --> response will be "List of Sectors" above (A.5.1)

  • int64 - character ID

A.5.3 Sector Map

  • int64 - id of sector
  • int8 - length of map filename (sector's name)
  • n*char - map filename (sector's name)

A.5.4 Request sector map --> response will be "Sector Map" type above (A.5.3)

  • int64 - id of sector

A.5.5 Item in sector (actor/character or object)

  • int64 - id of item
  • int64 - id of sector in which the item is located
  • float - position of item: x coordinate
  • float - position of item: y coordinate
  • float - position of item: z coordinate
  • int64 - id of graphics profile --> graphics profiles are so that the client can request and choose from alternative/equivalent actual files/meshes/icons/animations for this particular graphics profile
  • int8 - length of name/label of item
  • n*char - name/label of item

A.5.6 Request own char --> no payload here really since it's accepted only from authenticated client so unambiguous anyway; response will be a "Item in sector" type above - it includes id of sector + id of char etc. (A.5.5)

A.5.7 Item in container

  • int64 - id of item
  • int64 - count
  • int64 - parent item/actor id (i.e. inventory is simply actor-as-container)
  • int64 - slot id
  • int64 - id of graphics profile --> same story as at A.5.5 above
  • int8 - length of name/label of item
  • n*char - name/label of item

A.5.8 Request item --> response will be "Item in sector" or "Item in container" types above (A.5.6, A.5.7)

  • int64 - id of item

A.5.9 Item Text Description (returned in response to a "view" basic action)

  • int64 - id of item
  • int64 - length of description
  • n*char - text description

A.5.10 Item Text Content --> sent in response to "read" basic action

  • int64 - id of item
  • int64 - length of text content
  • n*char - text content

A.5.11 Item List of Characteristics

  • int64 - id of item
  • int16 - number of characteristics
  • n*int64- the ids of relevant characteristics for this item

A.5.12 Item Characteristic

  • int64 - id of item
  • int64 - id of characteristic
  • int64(/float/int32/int16/char) - value of characteristic --> type here would depend on characteristic according to definition at A.5.13 below

A.5.13 Characteristic

  • int64 - id of characteristic
  • int8 - type of value of this characteristic (see A.0 above for the ids of data types that can appear here)
  • int64 - length of name of characteristic, n
  • n*char - name of characteristic
  • int64 - length of name of category, c
  • c*char - name of category

5.14 Request Characteristic --> response is "Characteristic" above (A.5.13)

  • int64 - id of requested characteristic

A.5.15 Skill

  • int64 - id of skill
  • int64 - length of skill name
  • n*char - skill name
  • int64 - length of skill's category name
  • c*char - category name

A.5.16 Skill List

  • int 64 - number of skills in this list
  • n*int64- ids of skills in this list

A.5.17 Character's Skill

  • int64 - id of character
  • int64 - id of skill
  • int64 - current rank
  • int64 - current knowledge points
  • int64 - current practice points
  • int64 - cost of knowledge to next rank
  • int64 - cost of practice to next rank

A.5.18 Request Skill Information --> response will be Skill above (A.5.15)

  • int64 - skill id

A.5.19 Request List of Skills --> response will be Skill List above (A.5.16)

  • int64 - id of character whose skills are requested

A.5.20 Request Character's Skill --> response will be Character's Skill above (A.5.17)

  • int64 - id of character whose current skill values are requested
  • int64 - id of skill requested

A.5.21 Time of day (game time)

  • int8 - hour
  • int8 - minute

A.5.22 Request time of day (game time) --> no payload, response is Time of day above (A.5.21)

A.5.23 Movement Type

  • int64 - id of this movement type
  • int64 - id of graphic profile for this movement type
  • float - x change
  • float - y change
  • float - z change
  • float - x rotation
  • float - y rotation
  • float - z rotation
  • int64 - length of name
  • n*char - name of this movement type

A.5.24 Request movement type --> response will be "Movement Type" above (A.5.23)

  • int64 - id of requested movement type

A.5.25 List of movement types

  • int64 - number of available movement types
  • n*int64- list of ids of available movement types

A.5.26 Request list of movements --> response will be a "List of movement types" above (A.5.25)

  • int64 - id of item for which available movement types are requested

A.5.27 Set Movement Type

  • int64 - id of item for which movement type is set
  • int64 - id of movement type to set

A.5.28 Destroy Item

  • int64 - id of item that is destroyed/vanishes

A.5.29 Set Item Position

  • int64 - id of item
  • int64 - id of sector in which the item is located
  • int8 - position of item: x coordinate
  • int8 - position of item: y coordinate
  • int8 - position of item: z coordinate

A.5.30 Neutral message --> mainly for feedback e.g. "X killed himself", "That tool is not useful anymore", "You ranked up.", "You got loot"

  • int64 - length of text in characters, n
  • n*int8 - text

A.5.31 Error message (in game)

  • int64 - length of text in characters, n
  • n*int8 - text

A.5.32 Success message (in game)

  • int64 - length of text in characters, n
  • n*int8 - text

A.5.33 Message of the day

  • int64 - length of text in characters, n
  • n*int8 - text

A.5.34 Request message of the day --> no payload here; answer will be "Message of the day" above (A.5.33)

A.5.35 Top

  • int64 - duration in days from game's "today" (i.e. 0 for today's top, 30 for past months' top etc.)
  • int64 - length of text in characters, n
  • n*int8 - text

A.5.36 Request Top --> answer will be "Top" above (A.5.35)

  • int64 - duration in days from game's "today" (i.e. 0 for today's top, 30 for past months' top etc.)

A.5.37 Graphics Profile

  • int64 - id of this graphics profile
  • float - width
  • float - height
  • float - depth
  • int64 - number of contained slots with their own graphics profiles
  • int8 - length of filename for icon
  • m*int8 - icon filename
  • int8 - length of filename for mesh
  • n*int8 - mesh filename
  • int8 - length of filename for texture
  • p*int8 - texture filename
  • int8 - length of filename for animation
  • q*int8 - animation filename
  • int8 - length of filename for sound
  • r*int8 - sound filename

A.5.38 Request Top-Level Graphics Profile --> response is "Graphics Profile" above (A.5.37)

  • int64 - id of requested graphics profile

A.5.39 Request Child Graphics Profile --> response is "Graphics Profile" above (A.5.37)

  • int64 - length of path (i.e. how deep in the hierarchy is the graphics profile of interest)
  • n*int64- ids forming the path to the desired graphics profile (e.g. 2,1,15 means the 15th slot of the 1st slot of top graphics profile number 2).

Annex B - List of currently available basic actions

B.1 Target --> this is less than View at B.2. below; character targets the object.

B.2 View --> this is a generic view and can be applied to anything (objects, actors, world included).

B.3 Read

B.4 Lock/unlock

B.5 Use/Combine/Sacrifice

B.6 Explore (current /explore, with target sector id)

B.7 Repair

B.8 Exchange --> this would be used for at least 3 currently distinct parts: trade, store, bank. As everywhere else, its exact effect depends on context.

B.9 Complete --> for actions that require explicit "accept" confirmation from player (e.g. trade)

B.10 Abort --> aborts what the character is doing (if the abort is possible, permitted and meaningful in the given context).

B.11 Attack --> for current "/die" simply use this with subject and object the same, namely own character.

Use the comment form below for any questions, comments, suggestions or desires you have regarding this communications protocol.

May 3, 2017

Quest for the Crafty Noob

Filed under: Eulora — admin @ 5:19 p.m.

Eulora is this game where players get to actually do... everything. Even give quests to other players, when they want to and as (or if!) they like it. No more "bring me 7 rats' tails and I'll give you a rat's ass" a la every other RPG out there but good old fashioned elder talking1: here son, take ye olde blueprint and craft yourself a table first if you are serious about actually doing something in this life!

The table in question is not any table but the very useful and extremely versatile craft-table that Foxybot uses to carry stuff around when one doesn't use it to craft or to store or to expand one's inventory. And so the quest goes like this:

Find Foxy in game and ask her for the Crafty Noob's first quest. Ask her nicely for she is under no obligation to give the quest to you! If she is however of a nice enough disposition to give you a helping hand, she'll give you a few items, including a craft-table blueprint that reads like this:


She'll also give you a bit of advice: take those items and go find the public crafting table that is close to one NPC called Electron Spirover, up a rocky hill. Once there, figure out how to use the things she gave you (as well as other bits that you might need but can find yourself with a bit of /explore) and make yourself your very own Craft-table!

As a bonus, you might even get some numina in the process. Or at least find out that you... could have gotten some numina such as Petrified Feelings. If only you knew how and why or when one gets such things...

  1. Do you even still find this in *real* life around you? Did you ever look for it? 

April 13, 2017

Bundling with Foxybot

Filed under: Eulora — admin @ 3:04 p.m.

The ever useful Foxybot got shot a bit in one of its many legs at the last euloran update - previously fixed and reliable lists of ingredients turned all flighty and fickle, with ingredient numbers changing even as one crafts. As a result, automated craft runs can turn into a bit of a pain to both plan for (how many ingredients does one even NEED if each click potentially requires a different amount??) and to execute flawlessly and tirelessly over days and weeks, all foxybot-style. Still, people found a way around this trouble: just bundle stuff upfront and then ...craft it, build it, eat it or whatever else you want to do to it, changing blueprint or not. And if bundling is the new planning and the new pre-requisite to successful crafting for a useful bot, let's teach Foxybot to bundle, shall we?

You'll need all of half an hour time and a bit of thinking - hopefully that's something you *can* find around your house if not about your person at any given time. Grab your current version of the Foxybot and open its botactivity.h file. We'll make bundling a new activity for the bot so simply plonk in there the declaration of this new activity, similar to the other ones you'll see in the file. Since code is really the place for precision, not imaginary friends and flourishes, we'll call it simply:

class BundleActivity: public BotActivity, iTimerEvent

The above lines declared the new BundleActiviy as a refined version of the generic BotActivity and of iTimerEvent. Basically so far it just brings those two together and it does nothing more than that. Clearly that's not enough, so let's add some useful methods and fields between those two curly brackets where the body of our new activity is to be defined:

	BundleActivity();	//constructor
	~BundleActivity();	//destructor
	void HandleMessage(MsgEntry* message );	//this will react when server says something we care about!
	void ScheduleNewPerform(int delay);	//this is like an alarm clock - wake up lazy bones and do the next step
	bool Perform(iTimerEvent *ev);		//this IS the next step, called each time the alarm clock rings

	//for iBase			//those are the price of using crystal space; don't get me started.
	void IncRef(){}
	void DecRef(){}
	int GetRefCount() {return 0;}
	void* QueryInterface(scfInterfaceID i, int a) {}
	void AddRefOwner(void **, CS::Threading::Mutex*) {}
	void RemoveRefOwner(void**){}
	scfInterfaceMetadataList* GetInterfaceMetadata() {return NULL;}

	void StartWork();	//this is starting point, gotta start from somewhere, no?
	void WrapUp();		//at the end of each cycle one has to tidy up and this is just the code to do it
	void DoInit();		//at the start of each cycle one has to get all tools out and get everything ready

  recipe rcp;		//this is the blueprint saying WHAT and HOW we are to bundle; can't do without it
  bool bundleReady;	//logic here is so simple that we can get away with just a few flags: is bundle ready?
  bool recipeReady;	//is recipe ready/read?
  bool bundlingStarted;	//has bundling even started?
  int containerID;	//id of container used for mixing; needed to filter view container messages for the correct one
  EID containerEID;	//this is Planeshit idea of ids: making at least 2 for each thing and several more to spare.
  int percent;	//used for choosing number of ingredients	- if only it would be percent...

Save botactivity.h and close it. Open botactivity.cpp and let's now actually write all those things we just promised in the .h file. Ain't no code working on empty promises and fancy headers, you know? So there we go, plonk in botactivity.cpp:

  name = csString("bundle");		//we need this to react to /bot bundle
  textcolour = TEXT_COLOUR;		//what colour foxybot speaks in for this activity.

{//nothing to destruct really!

void BundleActivity::HandleMessage(MsgEntry* message )
	if (!IsOngoing())	//if I'm not working, then I don't care what server says!
	//only if we are actually looking for bundle
	if (!bundleReady && message->GetType() == MSGTYPE_VIEW_CONTAINER)
	{//did things change in that container?
		psViewContainerDescription mesg(message, psengine->GetNetManager()->GetConnection()->GetAccessPointers());
		if (mesg.containerID == containerID)	//this is for the container we are working with, check if there is a bundle
		{//kind of lulzy if we were to look in the WRONG container, so check id, yeah

			if (mesg.contents.GetSize()>0 && mesg.contents[0].name.Find("Bundle") < mesg.contents[0].name.Length()) //it is a bundle { bundleReady = true; //hey, we've got a bundle, we can go ahead! } } } else if (!recipeReady && message->GetType() == MSGTYPE_CRAFT_INFO)
	{	//this is when we need to read the recipe/blueprint that is equipped
		psMsgCraftingInfo incoming(message);
		csString itemDescription(incoming.craftInfo);

		rcp.ParseRecipe(itemDescription, percent>50);
		worldHandler::CloseOpenWindow(csString("Read Book"));
		OutputMsg(csString("Done reading recipe."));
		recipeReady = true;

void BundleActivity::ScheduleNewPerform(int delay)
	csRef<iEventTimer> timer = worldHandler::GetStandardTimer();
	timer->AddTimerEvent(this, delay);	//set alarm clock

bool BundleActivity::Perform(iTimerEvent *ev)
	if (!IsOngoing() && !IsFinished())	//if I ain't working, I ain't performing.
		return false;

	if (timesDone >= timesToRepeat)		//done is done
	{	//nothing more to do here.
		return false;	//this means DON'T set up that alarm anymore!

	if (!recipeReady)	//reading comprehension trouble? Just ask to read again. And again and ...
		//ask for it again and wait another round
		return true;	//re-schedule
	else 	//recipeReady - we READ it, hooray
		if (!bundlingStarted)	//if it's not started, then...we start it now; simple!

			OutputMsg(csString("Bundling action combining..."));
			char out[200];
			sprintf(out, "Done %d items, %d left to do.", timesDone, timesToRepeat-timesDone);

			if (!worldHandler::TargetEID(containerEID))
				OutputMsg(csString("Could not find container within reach!"));
				return false;

			if (!worldHandler::OpenTarget())
				OutputMsg(csString("Could not open the container!"));
				return false;
			OutputMsg(csString("Moving ingredients to container for bundling"));
			//move ingredients from inventory to container
			//first check for any bundles

			int toContainer = containerEID.Unbox();

			csHash<int, csString>::GlobalIterator iterIngredients(rcp.GetIngredientsList()->GetIterator());

			int nextEmptySlot = 0;
			if (!iterIngredients.HasNext())
				OutputMsg(csString("Empty ingredients list!"));
				return false;
			while (iterIngredients.HasNext())
				csString itemName;
				int quantity = iterIngredients.Next(itemName);

				char out[1000];
				sprintf(out, "Ingredient %s: %d", itemName.GetData(), quantity);

				psInventoryCache::CachedItemDescription* from = worldHandler::FindItemSlot(itemName, false);
				if (!from || from->stackCount < quantity) { OutputMsg(csString("Not enough ingredients for bundling! Bot stopping.")); Error(); return false; } else { worldHandler::MoveItems(from->containerID, from->slot, toContainer, nextEmptySlot, quantity);

				nextEmptySlot = nextEmptySlot + 1;
			OutputMsg(csString("Done with ingredients. Starting to combine."));


			bundlingStarted = true;
			return true;	//re-schedule
		else if (!bundleReady)	//we know bundling has started but..no bundle yet
			if (csGetTicks() - startTime >= timeout)	//we have SOME patience; but no more than timeout
				OutputMsg("Timedout, moving on.");
				//take items, ask for unstick + start over
				worldHandler::ExecCmd(csString("/unstick"));	//this is so that ongoing actions are cancelled as otherwise everything is jammed afterwards
				DoInit();	//start all over again;
			{//maybe it IS done, but we...missed the memo; ask for it again
				//ask for container contents, maybe this got lost somehow
			return true;	//simply reschedule here anyway, either way
		else //all of them are true, so we're done, grab bundle + start again
			//take items
			if (timesDone < timesToRepeat) //if we are not done, go ahead
                          return true;
                        else return false; //done, yay

void BundleActivity::StartWork()
  OutputMsg(csString("Bundle activity started."));

void BundleActivity::WrapUp()
  bundleReady = false; //at the end of a step, bundle is not ready!
  char msg[1000];
  sprintf(msg, "%d bundles done, %d potential bundles left.", timesDone, timesToRepeat-timesDone);

void BundleActivity::DoInit()
  bundleReady = false;
  recipeReady = false;
  bundlingStarted = false;
  if (timesDone == 0)
  { //get parameter if any
    WordArray words(cmd,false);
    if (words.GetCount()>0)	//it has a percent, so let's get this; default it is 100%
	percent = words.GetInt(0);
    else percent = 100;	//default

   //get setup
   csString recipeName = worldHandler::GetBrainItemName();
   if (recipeName.CompareNoCase(""))
      OutputMsg(csString("No blueprint equipped, please equip the bp for what you want to bundle and /bot bundle again."));

  containerEID = worldHandler::GetTargetEID();
  if (containerEID == -1)
	//actionToDo = CRAFTING_NONE;
	OutputMsg(csString("Kindly target (open) the container you want used for this craft run and then /bot craft again."));
  containerID = containerEID.Unbox();

  //read recipe = EVERY TIME!
  OutputMsg(csString("Reading the recipe..."));

Now we only need to actually add this new activiy to Foxybot so that we can call it. Save botactivity.cpp and close it. Open foxybot.cpp and add the following line in the constructor below the other similar ones (it's line 40 in my file):

activities[3] = new BundleActivity();	//adding the new activity to foxybot's "can do" list

Notice how Foxybot will know to delete it safely anyway since it deletes ALL the activities in its list in the destructor. But for that to work well we still need to let it know we increased the number of its activities. So save foxybot.cpp and then open foxybot.h and change:

static const int activitiesCount = 3;


static const int activitiesCount = 4;

That's it. Save foxybot.h and close it. Then simply re-compile the whole thing:

jam -aq client

Get yourself a drink while the thing compiles and then launch the client again. Simply drop a table or something, equip the bp you want, target (open/examine) the table and type:

/bot bundle 2000

Bot should start work on making 2000 bundles of whatever you have equipped in your character's mind. Drink that drink fast, for it won't take long!

February 24, 2017

Basic toolchain for Blender - Cal3d - Crystal Space

Filed under: Eulora — admin @ 1:20 a.m.

Only 2 days ago I was cobbling together a basic Cal3d+Crystal Space viewer of sorts for people to be able to test their Cal3d exported work to see if it's of any use for Eulora. Well, 2 days around here turns out to be a very long time indeed, as meanwhile it seems that we got not one but even two Blender to cal3d exporters actually working as well as at least one new animated sprite that could well wiggle its way on Euloran soil. To help along any artists who think they could contribute but feel that they don't have any sort of tools to support them, here's a basic toolchain in its first iteration. You'll need (DO mind the versions and don't update/innovate on this topic):

  1. Blender 2.66 - you are best off downloading sources and compiling them on your own system. If you are not enough of an artist to do that, at least get your binaries from the official Blender site and CHECK their checksum.
  2. Exporter from Blender 2.66 to cal3d:
    1. I tested Julien Valentin's exporter and it worked fine on a XUbuntu 12.04 64bits. So I'm hosting here the part you really need, check the sources page.
    2. To install it: simply drop the folder from that archive into the addons folder of your Blender 2.66 installation (you should find it if you go to your Blender folder and then further into 2.66/scripts/addons). Start Blender and go to User Preferences/Addons: either search for it or look in the Import/Export category. Activate the addon, save the preferences, enjoy. If all went fine, you'll find it as an option from File->Export->Cal3d Model (.cfg)
    3. To use it: load your .blend file in Blender; go to Object mode; select both main Armature AND the mesh (you can do this in a view of the object if you use "a" for "select all" OR you can do it from the Outliner). Go to File->Export->Cal3d Model (.cfg) and choose where you want it to spit out everything. The exporter itself says that there should be a second step as it allows you to prune bones that are not needed - in my experience it rushes through it all in one go (admittedly my test model had only 4 bones so nothing to prune for sure), but here it is mentioned, just in case you experience this second step. Go and admire your multiple xml files with funny extensions (.xaf, .xrf, .xmf, .xsf)
    4. Alternatively, give a go to a different (if similar) exporter that was tested and found working on Debian 8.
  3. Crystal Space and Cal3d: download and install according to instructions on Eulorum. NB: do NOT use any other versions of Cal3d and/or Crystal Space or your work will probably be useless for Eulora if you do.
  4. Bash script xml2bincal3d.sh to help you bridge the gap between what the exporter spits out and what cal3d+cs actually need. Note that it can help you best when it has in the same place a header.cal3d and a footer.cal3d files that it uses to assemble a working .cal3d file for your use with the cally3d viewer (see 5. below).
    1. To use it simply download it, make it executable and run it: ./xml2bincal3d.sh inputFolder [outputFolder] [pathToCal3D] . By default, the output folder is same as input folder and the path to cal3D is taken from environment variable CAL3DHOME (so just set that one if you don't want to use that last argument). Note that the path to cal3d IS NEEDED in order to actually run the converter between xml and binary cal3d formats. While you CAN run a similar converter that comes with your distribution, it will most likely NOT match the cal3d version that the exporter uses and it will miserably die on you.
    2. The script goes through all the .xsf, .xrf, .xmf and .xaf files in the inputFolder, calls the cal3d converter on them and stores the results in outputFolder/modelfiles. It also creates a file outputFolder/test.cal3d that includes all the exported skeletons, meshes and animations. NB: while this IS a valid file in general, you might want to check it and/or adjust values in there to match your needs!
  5. Viewer cally3d_args based on Cal3d+Crystal Space so that you can check your work. For sha512sum and more detailed instructions see the sources page.
    1. To use this, you'll need to compile it. A simple "make all" will do, provided you have already cal3d and Crystal Space installed.
    2. Once compiled, run as ./cally3d [file.cal3d] [animationName] The default values here are "test.cal3d" and "strut" respectively. To use your previously exported model you can:
      1. run the script at 4 above with the folder of this viewer as outputFolder OR
      2. manually copy the output from 4 to this folder
      3. give as argument to cally3d the full path to your .cal3d file. NB: in this case you WILL likely have to update manually the .cal3d file as well so that cally3d can find the skeleton/animation files.

When you finally run cally3d, you should be looking at your model performing whatever animation you asked it to perform. Note that the bash script gives animations their name based on the name of the .xaf file, so you might really want to follow the convention and name your animations in Blender as modelname_animationname rather than myAnimation sort of thing. If your animation is for instance wormOfDoom_knotting, then you'll be able to ask cally3d to show you the "knotting" animation of your worm of doom. Otherwise you can of course ask for anything you wish and get a load of errors.

As previously mentioned, this is a very basic toolchain cobbled together more as a prototype / starting point rather than a definitive reference. The most glaring current limitation (by no means the only one) is the lack of material support - whatever your worm of doom was wearing as its skin will be quite bluntly ignored by the viewer (though not by the exporter).

Enjoy! And if you complain, do it with concrete and precise descriptions of what hurts, where and what you did when it started. Unless you want it to hurt even more, that is.

January 23, 2017

Ordinary trouble of an Euloran explorer

Filed under: Eulora — admin @ 10:57 a.m.

(This could certainly be a whole category of troubles Foxy's bloody diary, if only there were categories to all the trouble.)
As a seasoned explorer of Eulora, maker of maps and of bots and of whatnots, Foxy knows where to search to find troublePetrified Bubbles, Dead Molluscs or other things of that sort. In a word, things that are worth 100+ times more than the basic stuff that can be found almost anywhere. For the naive explorer of words-other-than-Eulora, this might seem as the very opposite of trouble - the light, the profit, the happiness, the printing of money - in a word heaven without hell and earnings without losses or something of the sort. However, Eulora just doesn't work like that - it simply doesn't do all this "there shall be no trouble" thing and most probably it will never do it, not even when pigs1 fly all the way to the moon.

To illustrate this interesting2 lack of unbalanced happiness on Euloran soil let's consider for a second that you've got - as Foxy did - not only the rare knowledge of where Petrified Bubbles or Microgoats are, but also the concrete keys to corresponding claims3 for such resources. Such claims come in various sizes and increasing cost of building4:

Tiny claims take 1 Little Bit O' Nothing to build and so they cost 11 coppers.

Small Claims take anything between 1 and 7 Coarse Frangible Threads and so they cost between 180 and 1260 coppers.

Ordinary Claims take all sorts really, but adding them at base value reveals that they simply take about 15000 coppers, give or take some change. More precisely:

Ordinary claim of Petrified Bubble is 6*262+11*67+4*59+5*399+5*1963=14355.

Ordinary claim of Microgoat is 2*5439+2*1096+11*79+1484+73=15496

On the bright side, those two ordinary claims don't even require anything really rare - the PB claim takes some molluscs, but that's not a terrible issue. And the microgoat one takes one pacademia nut and otherwise plain and simple oil, almost as boring as it gets5. So then: what's the trouble?

The trouble is of course on the less-than-bright side, namely output and value and the likes. Out of the tiniest of claims (and thus for as little as 11 coppers), one will get at least one item. So one PB perhaps, meaning a whopping 43000 coppers and change. Or one microgoat with its rather macrovalue of about 86000 coppers. And that is only base value, as one can easily (sort of) get higher quality and therefore multiply those values by a factor of 2 or more. Small claims are especially good for this seeing how they easily allow overbuilding - the use of 7 threads instead of 1, thus pumping up the cost of building the claim but also the quality (hence, value) of output. For most resources *other* than those 2 discussed here, ordinary claims also quite imply overbuilding, since the 15000 coppers going in are certainly more than the 73 cost of one crumbly rock or even the more considerable 1963 cost of mollusc. However, for PB and Microgoats, ordinary claims are suddenly quite a pain to truly overbuild - at 86000 the microgoat and 15500 the ordinary bundle one needs 5.54 times the base value of the bundle (hence 554 quality points) to only match the smallest output at base value.

Sure, the above means that one is at least quite guaranteed a profit out of building an existing tiny/small/ordinary claim of PB or Microgoat. Assuming of course that there was no accumulated loss in *getting* such claim - quite a naive assumption. Nevertheless, the weirdness and trouble starts when one considers what quality of bundle should one make to build an ordinary PB or Microgoat. Should it be the lowest quality possible? That would mean apparently high profit as one PB is one PB and one Microgoat is really no smaller than another. However, a bundle of quality 1 will ALSO lower the quality (and therefore the value) of the output. Similarly, a high quality bundle will increase the quality of the output and given that each quality point of a PB is in fact worth 431 coppers and each quality point of Microgoat is worth 859 coppers, that's arguably not such a small matter. Adding to that the markup incurred on different ingredients required for the ordinary bundle, the whole thing suddenly becomes rather difficult to clearly decide on - and then one wonders simply why the ever loving fuck one got an ordinary instead of a plain old uncomplicated tiny or small - the result would STILL be 1 PB or 1 Microgoat, overbuilding the hell out of it would be waaaay simpler and more straightforward, underbuilding it would give no qualms and the trouble overall would be quite non-existent.

So then, can anyone come with any idea as to the actual usefulness of ordinary claims6 for high value items such as PB and Microgoat? Other than providing trouble, I mean. And perhaps the cuteness of an Ordinary Microgoat:


  1. They are called Multifunctional Samovars in Eulora for some reason 

  2. Some might call it painful, by another name. 

  3. Basically they would be the equivalent of veins I suppose - they mark the place where you need to build something to extract the actual resource - in unknown quantities, mostly small quantities, sometimes large and at rare times huge. 

  4. Will use base value throughout, to keep things simple at least for starters. 

  5. Boring IS good on Eulora - you don't want the sort of excitement that happens there 

  6. It's unclear - due to lack of data on the matter - whether the next size up for claims, namely Sizable would even do, but one can always hope it does and then go and dig. 

December 5, 2016

The Sentiments of Grass

Filed under: Eulora — admin @ 11:50 p.m.

(This could be - but nobody knows for sure anymore - another page out of that half-eaten Diary that Foxy used to keep. It all starts with pains and names and all that.)

Since its early days of broken Maths and painful cooking, Eulora has certainly grown up in leaps and bounds - or rather limps and hobbles. It grew up in fact so much that one might say it started quite developing - for starters it developed its own feelings and sentiments, dusts and mites, lint and horrors and all sorts that it calls with one word - numina.

Feelings1 in Eulora are quite abundant and totally worthless. At least the low quality, 100 a dime feelings that anyone can easily get - for Eulora's advances most pointedly include some rather ruthless Mathematics that apply to all that shiny new and totally petrified sentimental numina. Feelings of superior quality - superior in Euloran sense, aka "slightly less horrible than the usual" - though have recently been shown to be - of course - quite difficult to get. How difficult? Well, difficult enough that you'd spend about 200% their base-value2 worth to even get some, it would seem. Difficult enough that you'd first use all your 10 thoes to dig up some shiny, slinky, silky grass that WAS actually happy to be alive, then burn up the increasingly-rarer-and-hard-to-get coarse frangible thread blueprints, spend your days and nights hunched over a craft-table threading grass and then - only then - you'd hope to get some such lofty - despite being petrified really - feelings. As well as a hefty loss in terms of base value, of course - remember that ruthless Mathematics? It counts feelings with a big fat minus in front!

Perhaps feelings being so worthless in Eulora is hardly surprising given that people found before and in other parts that feelings are downright evil and out to get you when you aren't looking - at least when you aren't looking in all the right places, at the right thing and in your right mind that is. But even after discarding therefore those feelings in the dust where they can do least damage (to your finances at least), there surely are - there MUST be - the more valuable sort of numina, the Sentiments3. Oh, they certainly are more valuable - about 100 times more valuable. And almost impossible to get out of all that shiny, luscious grass that you've been... threading last night, full of feelings and what not.

Almost impossible, but... not quite. Rare indeed or rather worse than rare - meaning at a huge loss - sentiments it would seem can be had even of the grass variety. Welcome therefore to Eulora, this most sentimental island - tread with care for the grass itself is full of...feelings!4


  1. Tinkerer's Petrified Feelings, to be precise. 

  2. At least 200%! 

  3. By their full and very imaginative name - Tinkerer's Petrified Sentiments  

  4. And I don't know about your own feelings and all that, but if they are the usual Euloran type, they surely ARE out to get you, yeah. 

Older Posts »

Theme and content by Diana Coman