Overview
Comment: | add primitive thermal hazard LEDs; further documentation |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
511814aace3b6e9dd57ec362b2f17c70 |
User & Date: | lexi on 2024-05-03 21:00:04 |
Other Links: | manifest | tags |
Context
2024-05-04
| ||
02:18 | fix colors, add grass check-in: 9d4ddb7701 user: lexi tags: trunk | |
2024-05-03
| ||
21:00 | add primitive thermal hazard LEDs; further documentation check-in: 511814aace user: lexi tags: trunk | |
15:31 | genericize impacts check-in: 467a75e0dc user: lexi tags: trunk | |
Changes
Modified mods/starlit/init.lua from [435c654ad9] to [d6e7e6c59c].
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
brightest = 14; -- only sun and growlights }; heat = { -- celsius freezing = 0; safe = 4; overheat = 32; boiling = 100; }; rad = { }; }; activeUsers = { -- map of username -> user object |
> |
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
brightest = 14; -- only sun and growlights
};
heat = { -- celsius
freezing = 0;
safe = 4;
overheat = 32;
boiling = 100;
thermalConductivity = 0.05; -- κ
};
rad = {
};
};
activeUsers = {
-- map of username -> user object
|
Modified mods/starlit/user.lua from [788077fd8e] to [7074af2318].
37 38 39 40 41 42 43 44 45 46 47 48 49 50 .. 59 60 61 62 63 64 65 66 67 68 69 70 71 72 ... 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 ... 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 ... 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 ... 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 ... 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 ... 499 500 501 502 503 504 505 506 507 508 509 510 511 512 ... 872 873 874 875 876 877 878 879 880 881 882 883 884 885 ... 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
end return { entity = luser; name = name; hud = { elt = {}; bar = {}; }; tree = {}; action = { bits = 0; -- for control deltas prog = {}; -- for recording action progress on a node; reset on refocus tgt = {type='nothing'}; sfx = {}; ................................................................................ }; pref = { calendar = 'commune'; }; overlays = {}; cooldownTimes = { stamina = 0; }; } end; __index = { -------------- -- overlays -- -------------- ................................................................................ end; --------- -- HUD -- --------- attachImage = function(self, def) local user = self.entity local img = {} img.id = user:hud_add { type = 'image'; text = def.tex; scale = def.scale; alignment = def.align; position = def.pos; offset = def.ofs; ................................................................................ end, def) end end return img end; attachMeter = function(self, def) local luser = self.entity local m = {} local w = def.size or 80 local szf = w / 80 local h = szf * 260 m.meter = luser:hud_add { type = 'image'; scale = {x = szf, y = szf}; alignment = def.align; ................................................................................ luser:hud_change(m.readout, 'number', txtcolor:hex()) end end return m end; attachTextBox = function(self, def) local luser = self.entity local box = {} box.id = luser:hud_add { type = 'text'; text = ''; alignment = def.align; number = def.color and def.color:int24() or 0xFFffFF; scale = def.bound; size = {x = def.size, y=0}; ................................................................................ luser:hud_change(box.id, 'number', color:int24()) end end return box end; attachStatBar = function(self, def) local luser = self.entity local bar = {} local img = lib.image 'starlit-ui-bar.png' local colorized = img if type(def.color) ~= 'function' then colorized = colorized:shift(def.color) end bar.id = luser:hud_add { ................................................................................ set('text', hudAdjustBacklight(hudCenterBG):render()) end; }; self:updateHUD() end; deleteHUD = function(self) for name, e in pairs(self.hud.elt) do self:hud_delete(e.id) end end; updateHUD = function(self) for name, e in pairs(self.hud.elt) do if e.update then e.update() end end end; ................................................................................ -- intel-gathering -- --------------------- clientInfo = function(self) return minetest.get_player_information(self.name) end; species = function(self) return starlit.world.species.index[self.persona.species] end; -------------------- -- event handlers -- -------------------- onSignup = function(self) local meta = self.entity:get_meta() ................................................................................ end if run then run(self, ctx) return true end return false end; ------------- -- weather -- ------------- updateWeather = function(self) end; ................................................................................ local clockInterval = 1.0 starlit.startJob('starlit:clock', clockInterval, function(delta) for id, u in pairs(starlit.activeUsers) do u.hud.elt.time:update() end end) local biointerval = 1.0 starlit.startJob('starlit:bio', biointerval, function(delta) for id, u in pairs(starlit.activeUsers) do if u:effectiveStat 'health' ~= 0 then local bmr = u:phenoTrait 'metabolism' * biointerval -- TODO apply modifiers |
> > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 .. 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 ... 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 ... 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 ... 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 ... 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 ... 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 ... 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 ... 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 ... 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 |
end return { entity = luser; name = name; hud = { elt = {}; bar = {}; alarm = {}; }; tree = {}; action = { bits = 0; -- for control deltas prog = {}; -- for recording action progress on a node; reset on refocus tgt = {type='nothing'}; sfx = {}; ................................................................................ }; pref = { calendar = 'commune'; }; overlays = {}; cooldownTimes = { stamina = 0; alarm = 0; }; } end; __index = { -------------- -- overlays -- -------------- ................................................................................ end; --------- -- HUD -- --------- attachImage = function(self, def) local user = self.entity local img = {def = def} img.id = user:hud_add { type = 'image'; text = def.tex; scale = def.scale; alignment = def.align; position = def.pos; offset = def.ofs; ................................................................................ end, def) end end return img end; attachMeter = function(self, def) local luser = self.entity local m = {def = def} local w = def.size or 80 local szf = w / 80 local h = szf * 260 m.meter = luser:hud_add { type = 'image'; scale = {x = szf, y = szf}; alignment = def.align; ................................................................................ luser:hud_change(m.readout, 'number', txtcolor:hex()) end end return m end; attachTextBox = function(self, def) local luser = self.entity local box = {def = def} box.id = luser:hud_add { type = 'text'; text = ''; alignment = def.align; number = def.color and def.color:int24() or 0xFFffFF; scale = def.bound; size = {x = def.size, y=0}; ................................................................................ luser:hud_change(box.id, 'number', color:int24()) end end return box end; attachStatBar = function(self, def) local luser = self.entity local bar = {def = def} local img = lib.image 'starlit-ui-bar.png' local colorized = img if type(def.color) ~= 'function' then colorized = colorized:shift(def.color) end bar.id = luser:hud_add { ................................................................................ set('text', hudAdjustBacklight(hudCenterBG):render()) end; }; self:updateHUD() end; deleteHUD = function(self) for name, e in pairs(self.hud.elt) do self.entity:hud_remove(e.id) end end; updateHUD = function(self) for name, e in pairs(self.hud.elt) do if e.update then e.update() end end end; ................................................................................ -- intel-gathering -- --------------------- clientInfo = function(self) return minetest.get_player_information(self.name) end; species = function(self) return starlit.world.species.index[self.persona.species] end; -- can the suit heater sustain its current internal temperature in an area of t°C tempCanSustain = function(self, t) if self:naked() then return false end local s = self:getSuit() if s:powerState() == 'off' then return false end local sd = s:def() local w = self:effectiveStat 'warmth' local kappa = starlit.constant.heat.thermalConductivity local insul = sd.temp.insulation local dt = (kappa * (1-insul)) * (t - w) print('dt', dt, dump(sd.temp)) if (dt > 0 and dt > sd.temp.maxCool) or (dt < 0 and math.abs(dt) > sd.temp.maxHeat) then return false end return true end; -- will exposure to temperature t cause the player eventual harm tempHazard = function(self, t) local tr = self:species().tempRange.survivable if t >= tr[1] and t <= tr[2] then return nil end if self:tempCanSustain(t) then return nil end if t < tr[1] then return 'cold' end return 'hot' end; -------------------- -- event handlers -- -------------------- onSignup = function(self) local meta = self.entity:get_meta() ................................................................................ end if run then run(self, ctx) return true end return false end; alarm = function(self, urgency, kind, freq, where) freq = freq or 3 local urgencies = { [1] = {sound = 'starlit-alarm'}; [2] = {sound = 'starlit-alarm-urgent'}; } local gt = minetest.get_gametime() local urg = urgencies[urgency] or urgencies[#urgencies] if gt - self.cooldownTimes.alarm < freq then return end self.cooldownTimes.alarm = gt self:suitSound(urg.sound) if where then local elt = { tex = where.tex or 'starlit-ui-alert.png'; scale = {x=1, y=1}; align = table.copy(where.elt.def.align); pos = table.copy(where.elt.def.pos); ofs = table.copy(where.elt.def.ofs); } elt.ofs.x = elt.ofs.x + where.ofs.x elt.ofs.y = elt.ofs.y + where.ofs.y local attached = self:attachImage(elt) table.insert(self.hud.alarm, attached) -- HATE. HATE. HAAAAAAAAAAATE minetest.after(freq/2, function() for k,v in pairs(self.hud.alarm) do self.entity:hud_remove(v.id) end self.hud.alarm={} end) end end; ------------- -- weather -- ------------- updateWeather = function(self) end; ................................................................................ local clockInterval = 1.0 starlit.startJob('starlit:clock', clockInterval, function(delta) for id, u in pairs(starlit.activeUsers) do u.hud.elt.time:update() end end) -- performs a general HUD refresh, mainly to update the HUD backlight brightness local hudInterval = 10 starlit.startJob('starlit:hud-refresh', hudInterval, function(delta) for id, u in pairs(starlit.activeUsers) do u:updateHUD() end end) local biointerval = 1.0 starlit.startJob('starlit:bio', biointerval, function(delta) for id, u in pairs(starlit.activeUsers) do if u:effectiveStat 'health' ~= 0 then local bmr = u:phenoTrait 'metabolism' * biointerval -- TODO apply modifiers |
Modified mods/starlit/world.lua from [d79dc9efc2] to [a2ac450e1c].
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
-- player is in -30°C weather, and has an internal temperature of -- 10°C. then: -- κ = .1°C/C/s (which is apparently 100mHz) -- Tₚ = 10°C -- Tₑ = -30°C -- d = Tₑ − Tₚ = -40°C -- ΔT = κ×d = -.4°C/s -- our final change in temperature is computed as tΔC where t is time local kappa = .05 for name,user in pairs(starlit.activeUsers) do local tr = user:species().tempRange local t = starlit.world.climate.temp(user.entity:get_pos()) local insul = 0 local naked = user:naked() local suitDef if not naked then suitDef = user:suitStack():get_definition() insul = suitDef._starlit.suit.temp.insulation end ................................................................................ end end user:statDelta('warmth', tgt - warm) -- dopey but w/e warm = tgt -- for the sake of readable code if warm < tSafeMin or warm > tSafeMax then local dv if warm < tSafeMin then dv = math.abs(warm - tSafeMin) else dv = math.abs(warm - tSafeMax) end |
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
-- player is in -30°C weather, and has an internal temperature of -- 10°C. then: -- κ = .1°C/C/s (which is apparently 100mHz) -- Tₚ = 10°C -- Tₑ = -30°C -- d = Tₑ − Tₚ = -40°C -- ΔT = κ×d = -.4°C/s -- too cold: -- x = beginning of danger zone -- κ × (x - Tₚ) = y where y < Tₚ -- our final change in temperature is computed as tΔC where t is time local kappa = starlit.constant.heat.thermalConductivity for name,user in pairs(starlit.activeUsers) do local tr = user:species().tempRange local t = starlit.world.climate.temp(user.entity:get_pos()) do -- this bit probably belongs in starlit:bio but we do it here in order -- to spare ourselves another call into the dark swamp of climate.temp local urg = 1 local function alarm(kind) user:alarm(urg, kind, nil, { elt = user.hud.elt.temp, ofs = {x=100,y=0}; tex = 'starlit-ui-alert-'..kind..'.png'; }) end local hz = user:tempHazard(t) local tr = user:species().tempRange.survivable if hz == 'cold' then if tr[1] - t > 7 then urg = 2 end alarm 'temp-cold' elseif hz == 'hot' then if t - tr[2] > 7 then urg = 2 end alarm 'temp-hot' end end local insul = 0 local naked = user:naked() local suitDef if not naked then suitDef = user:suitStack():get_definition() insul = suitDef._starlit.suit.temp.insulation end ................................................................................ end end user:statDelta('warmth', tgt - warm) -- dopey but w/e warm = tgt -- for the sake of readable code -- does this belong in starlit:bio? unsure tbh if warm < tSafeMin or warm > tSafeMax then local dv if warm < tSafeMin then dv = math.abs(warm - tSafeMin) else dv = math.abs(warm - tSafeMax) end |
Modified starlit.ct from [415d01ad10] to [8d6b5074b6].
1 2 3 4 5 6 7 8 9 10 11 12 .. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 .. 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# starlit [*starlit] is a sci-fi survival game. you play the survivor of a disaster in space, stranded on a just-barely-habitable world with nothing but your escape pod, your survival suit, and some handy new psionic powers that the accident seems to have unlocked in you. scavenge resources, search alien ruins, and build a base where you can survive indefinitely, but be careful: winter approaches, and your starting suit heater is already struggling to keep you alive in the comparatively warm days of "summer". ## story ### "Imperial Expat" background about a month ago, you woke up to unexpected good news. your application to join the new Commune colony at Thousand Petal, submitted in a moment of utter existential weariness and almost in jest, was actually accepted. your skillset was a "perfect match" for the budding colony's needs, claimed the Population Control Authority, and you'd earned yourself a free trip to your new home -- on a swanky state transport, no less. it took a few discreet threats and bribes from Commune diplomats, but after a week of wrangling with the surly Crown Service for Comings & Goings -- whose bureaucrats seemed outright [!offended] that you actually managed to find a way off that hateful rock -- you secured grudging clearance to depart. you celebrated by telling your slackjawed boss exactly what you thought of him in a meeting room packed with his fellow parasites -- and left House Taladran with a new appreciation for the value of your labor, as the nobs found themselves desperately scrabbling for a replacement on short notice. you almost couldn't believe it when the Commune ship -- a sleek, solid piece of engineering whose graceful descent onto the landing pad seemed to sneer at the lurching rattletraps arrayed all around it -- actually showed up. in a daze you handed over your worldly possessions -- all three of them -- to a valet with impeccable manners, and climbed up out of the wagie nightmare into high orbit around your homeworld. the mercenary psion aboard, a preening Usukwinti with her very own luxury suite, tore a bleeding hole in the spacetime metric, and five hundred hopeful souls dove through towards fancied salvation. "sure," you thought to yourself as you slipped into your sleek new nanotech environment suit, itself worth more than the sum total of your earnings on Flame of Unyielding Purification, "life won't be easy -- but damn it, it'll [!mean] something out there." a free life on the wild frontier with a nation of comrades to have your back, with the best tech humans can make, fresh, clean water that isn't laced with compliance serum, and -- best of all -- never having to worry about paying rent again. it was too good to be true, you mused. ................................................................................ p11143: https://github.com/minetest/minetest/pull/11143.diff ### shadows i was delighted to see dynamic shadows land in minetest, and i hope the implementation will eventually mature. however, as it stands, there are severe issues with shadows that make them essentially incompatible with complex meshes like the Starlit player character meshes. for the sake of those who don't mind these glitches, Starlit does enable shadows, but i unfortunately have to recommend that you disable them until the minetest devs get their act together on this feature. ## gameplay the most important thing to understand about starlit is that is is [*mean], by design. * chance plays an important role. your escape pod might land in the midst of a lush, temperate forest with plenty of nearby shipwrecks to scavenge. or it might land in the exact geographic center of a vast, harsh desert that your suit's cooling systems can't protect you from, ten klicks from anything of value. "unfair", you say? tough. Farthest Shadow doesn't care about your feelings. * death is much worse than a slap on the wrist. when you die, you drop your possessions and your suit, and respawn naked at your spawn point. this is a serious danger, as you might be kilometers away from your spawn point -- and there's no guarantee someone else won't take your suit before you can find your way back to it. good luck crossing long distances without climate control! if you haven't carefully prepared for this eventuality by keeping a spare suit by your spawn point, death can be devastating, to the point of making the game unsurvivable without another player's help. starlit is somewhat unusual in how it uses the minetest engine. it's a voxel game but not of the minecraft variety. ### controls summon your Suit Interface by pressing the [*E] / [*Inventory] key. this will allow you to move items around in your inventory, but more importantly, it also allows you select or configure your Interaction Mode. the top three buttons can be used to select (or deactivate) an Interaction Mode. an Interaction Mode can be configured by pressing the button immediately below. the active Interaction Mode controls the behavior of the mouse buttons when no item is selected in the hotbar. the modes are: ................................................................................ to use a tool, select it in the hotbar. even if an Interaction Mode is active, the tool will take priority. press [*Left Button] / [*Punch] to use the tool on a block; for instance, to break a stone with a jackhammer. to configure a tool or use its secondary functions, if any, press [*Right Button] / [*Place]. hold [*Aux1] to activate your selected Maneuver. by default this is Sprint, which will consume stamina to allow you to run much faster. certain suits offer the Flight ability, which allows slow, mid-range flight. you can also unlock the psionic ability Lift, which allows very rapid flight but consumes psi at a prodigious rate. you can only have one Maneuver active at a time, whether this is a Psi Maneuver (consuming psi), a Suit Maneuver (consuming battery), or a Body Maneuver (consuming stamina). Maneuvers are activated in their respective panel. ### psionics there are four types of psionic abilities: Manual, Maneuver, Ritual, and Contextual. you can assign two Manual abilities at any given time and access them with the mouse buttons in Psionics mode. you can select a Psi Maneuver in the Psionics panel and activate it by holding [*Aux1]. |
| < > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 .. 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 .. 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# starlit [*starlit] is a sci-fi survival game. you play the survivor of a disaster in space, stranded on a just-barely-habitable world with nothing but your escape pod, your survival suit, and some handy new psionic powers that the accident seems to have unlocked in you. scavenge resources, search alien ruins, and build a base where you can survive indefinitely, but be careful: winter approaches, and your starting suit heater is already struggling to keep you alive in the comparatively warm days of "summer". ##story story about a month ago, you woke up to unexpected good news. your application to join the new Commune colony at Thousand Petal, submitted in a moment of utter existential weariness and almost in jest, was actually accepted. your skillset was a "perfect match" for the budding colony's needs, claimed the Population Control Authority, and you'd earned yourself a free trip to your new home -- on a swanky state transport, no less. it took a few discreet threats and bribes from Commune diplomats, but after a week of wrangling with the surly Crown Service for Comings & Goings -- whose bureaucrats seemed outright [!offended] that you actually managed to find a way off that hateful rock -- you secured grudging clearance to depart. you celebrated by telling your slackjawed boss exactly what you thought of him in a meeting room packed with his fellow parasites -- and left House Taladran with a new appreciation for the value of your labor, as the nobs found themselves desperately scrabbling for a replacement on short notice. you almost couldn't believe it when the Commune ship -- a sleek, solid piece of engineering whose graceful descent onto the landing pad seemed to sneer at the lurching rattletraps arrayed all around it -- actually showed up. in a daze you handed over your worldly possessions -- all three of them -- to a valet with impeccable manners, and climbed up out of the wagie nightmare into high orbit around your homeworld. the mercenary psion aboard, a preening Usukwinti with her very own luxury suite, tore a bleeding hole in the spacetime metric, and five hundred hopeful souls dove through towards fancied salvation. "sure," you thought to yourself as you slipped into your sleek new nanotech environment suit, itself worth more than the sum total of your earnings on Flame of Unyielding Purification, "life won't be easy -- but damn it, it'll [!mean] something out there." a free life on the wild frontier with a nation of comrades to have your back, with the best tech humans can make, fresh, clean water that isn't laced with compliance serum, and -- best of all -- never having to worry about paying rent again. it was too good to be true, you mused. ................................................................................ p11143: https://github.com/minetest/minetest/pull/11143.diff ### shadows i was delighted to see dynamic shadows land in minetest, and i hope the implementation will eventually mature. however, as it stands, there are severe issues with shadows that make them essentially incompatible with complex meshes like the Starlit player character meshes. for the sake of those who don't mind these glitches, Starlit does enable shadows, but i unfortunately have to recommend that you disable them until the minetest devs get their act together on this feature. ## gameplay starlit is somewhat unusual in how it uses the minetest engine. it's a voxel game but not of the minecraft variety. the most important thing to understand about starlit is that is is [*mean], by design. * chance plays an important role. your escape pod might land in the midst of a lush, temperate forest with plenty of nearby shipwrecks to scavenge. or it might land in the exact geographic center of a vast, harsh desert that your suit's cooling systems can't protect you from, ten klicks from anything of value. "unfair", you say? tough. Farthest Shadow doesn't care about your feelings. * death is much worse than a slap on the wrist. when you die, you drop your possessions and your suit, and respawn naked at your spawn point. this is a serious danger, as you might be kilometers away from your spawn point -- and there's no guarantee someone else won't take your suit before you can find your way back to it. good luck crossing long distances without climate control! if you haven't carefully prepared for this eventuality by keeping a spare suit by your spawn point, death can be devastating, to the point of making the game unsurvivable without another player's help. ### scenarios your starting character configuration depends on the scenario you select. (right now this is configured in minetest settings, which is intensely awkward, but i don't have a better solution). the scenario controls your species, sex, and starting inventory. [*neither species nor sex is cosmetic]; e.g. human females are physically weaker but psionically stronged than males. the current playable scenarios are: #### Imperial Expat [*phenotype]: human female [*starting gear]: Commune survival kit > Hoping to escape a miserable life deep in the grinding gears of the capitalist machine for the bracing freedom of the frontier, you sought entry as a colonist to the new Commune world of Thousand Petal. Fate -- which is to say, terrorists -- intervened, and you wound up stranded on Farthest Shadow with little more than the nanosuit on your back, ship blown to tatters and your soul thoroughly mauled by the explosion of a twisted alien artifact -- which SOMEONE neglected to inform you your ride would be carrying. > At least you got some handy psionic powers out of this whole clusterfuck. Hopefully they're safe to use. #### Gentleman Adventurer [!(unimplemented)] [*phenotype]: human male [*starting gear]: Imperial survival kit > Tired of the same-old-same-old, sick of your idiot contemporaries, exasperated with the shallow soul-rotting luxury of life as landless lordling, and earnestly eager to enrage your father, you resolved to see the Reach in all her splendor. Deftly evading the usual tourist traps, you finagled your way into the confidence of the Commune ambassador with a few modest infusions of Father's money -- now [!that] should pop his monocle -- and secured yourself a seat on a ride to their brand-new colony at Thousand Petal. How exciting -- a genuine frontier outing! #### Terrorist Tagalong [*phenotype]: human female [*starting gear]: star merc combat kit > It turns out there's a *reason* Crown jobs pay so well. #### Tradebird Bodyguard [!(unimplemented)] [*phenotype]: male Usukwinti [*starting gear]: Usuk survival kit > You've never understood why astropaths of all people [!insist] on bodyguards. This one could probably make hash of a good-sized human batallion, if her feathers were sufficiently ruffled. Perhaps it's a status thing. Whatever the case, it's easy money. > At least, it was supposed to be. ### controls summon your Suit Interface by pressing the [*E] / [*Inventory] key. this will allow you to move items around in your inventory, but more importantly, it also allows you select or configure your Interaction Mode. the top three buttons can be used to select (or deactivate) an Interaction Mode. an Interaction Mode can be configured by pressing the button immediately below. the active Interaction Mode controls the behavior of the mouse buttons when no item is selected in the hotbar. the modes are: ................................................................................ to use a tool, select it in the hotbar. even if an Interaction Mode is active, the tool will take priority. press [*Left Button] / [*Punch] to use the tool on a block; for instance, to break a stone with a jackhammer. to configure a tool or use its secondary functions, if any, press [*Right Button] / [*Place]. hold [*Aux1] to activate your selected Maneuver. by default this is Sprint, which will consume stamina to allow you to run much faster. certain suits offer the Flight ability, which allows slow, mid-range flight. you can also unlock the psionic ability Lift, which allows very rapid flight but consumes psi at a prodigious rate. you can only have one Maneuver active at a time, whether this is a Psi Maneuver (consuming psi), a Suit Maneuver (consuming battery), or a Body Maneuver (consuming stamina). Maneuvers are activated in their respective panel. ### stats to survive and thrive on Farthest Shadow, you need to manage your stats carefully. stats impact gameplay and other stats in various ways. * [*health]: self-explanatory. it hits zero, you die. measured in hit points (hp) ** regenerates very slowly, though nanomedical suites improve this considerably * [*stamina]: how long you can sustain intense physical activity. measured in sprinting meters (m) ** regenerates quickly, depending on [*fatigue] ** consumed by biological abilities such as sprinting or Usuk flight. ** affects [*fatigue]: the lower your stamina bar, the faster your fatigue builds * [*energy]: the amount of electrical power available to your environment suit. measured in joules (J) ** does not regenerate, but empty batteries can be swapped out to replenish energy in the field ** consumed by all suit abilities, including nanotech and weapons systems * [*numina]: a measure of your available psionic power. measured in psi (ψ) ** accumulates slowly, depending on [*morale] * [*nutrition]: how much energy your body has stored. measured in kCal. basal metabolic rate depends on species and sex ** affects [*morale]: if you're starving, you bleed morale more quickly ** affects [*health]: you will die if you do not eat enough * [*hydration]: stay hydrated uwu. measured in liters (L) ** affects [*morale]: if you're parched, you bleed morale much more quickly ** affects [*health]: you will die very quickly if you do not drink enough * [*warmth]: maintaining a healthy body temperature is crucially important on Farthest Shadow, which does not have many places a human can be comfortable without a powered environment suit. if you're outside your species' comfort range, your stamina regen and morale expenditure will be impacted. if you're outside your species' [*survival] range, you will start dying of hypo/hyperthermia. most environment suits have built-in thermoelectrics that will try to keep you at a comfortable (or merely survivable, in power save mode) temperature, but this can drain your suit batteries very quickly at extreme temperatures. ** affects [*morale], [*stamina], [*health] * [*fatigue]: how long you've gone without sleep. ** affects [*stamina] regen: the higher your [*fatigue], the more slowly you regnerate stamina. if you are fully fatigued (exhausted), you do not regenerate stamina * [*morale]: how happy you are. measured in the number of hours you can continue functioning emotionally ** diminishes over time. can be replenished by various activities, such as eating tasty food ** affects [*numina] regen: the lower your morale, the more slowly you accumulate numina. if you are completely out of morale (depressed), you do not accumulate any numina * [*irradation]: how much ionizing radiation you've soaked up. measured in grays (Gy) ** your environment suit provides some protection against environmental radiation. how much depends on your model of suit. ** affects [*health]: slows natural healing. at values over 2Gy, you will start to hemorrhage health, though a capable nanomedical system can compensate up to a point ** affects [*numina]: you accumulate numina more quickly in high-rad areas ** naturally diminishes, but very slowly * [*illness]: not everything on Farthest Shadow's ecosystem is, shall we say, biocompatible. measured in percent ** affects [*morale]: the higher your illness, the more quickly you bleed morale your primary stats are shown on your HUD. ancillary stats can be viewed in the "body" panel. ### psionics there are four types of psionic abilities: Manual, Maneuver, Ritual, and Contextual. you can assign two Manual abilities at any given time and access them with the mouse buttons in Psionics mode. you can select a Psi Maneuver in the Psionics panel and activate it by holding [*Aux1]. |