s: ['stone axe', 'stone pickaxe'],
createCanvas(window.innerWidth, window.innerHeight);
name: 'Ephemeral-AS-Fork-DB'
textFont("Consolas,Monaco,Lucida Console,Courier New,Courier,monospace");
function windowResized() {
resizeCanvas(window.innerWidth, window.innerHeight);
scaledHeight = height / (width / 1920);
if (frameCount % 7 == 0) {
rect(0, 0, 1920, scaledHeight)
text('Ephemeral' + (gameState ? ' - ' + world.name : ''), 15, 15);
if (!gameUI.help) updatePlayer()
gtime = ((Date.now() / 1000 * 12 / tcycle) + offset) % 24
return keyFirst[a] || keyRepeat[a]
if (keyCode == 9) gameUI.help = 0
} else if (gameUI.settings) {
if (keyCode == 8 && world.name.length > 0) {
world.name = world.name.slice(0, world.name.length - 1)
localforage.removeItem('1413912-' + gameUI.name2);
localforage.removeItem('1413912-norm-' + gameUI.name2)
if (keyCode == UP_ARROW) gameUI.selected = (gameUI.selected - 1 + gameUI.selects) % gameUI.selects
if (keyCode == DOWN_ARROW) gameUI.selected = (gameUI.selected + 1) % gameUI.selects
if (gameUI.selected == 0) {
} else if (gameUI.selected == 1) {
gameUI.name2 = world.name
} else if (gameUI.selected == 2) {
localforage.removeItem('1413912-' + world.name)
localforage.removeItem('1413912-norm-' + world.name)
} else if (gameUI.selected == 3) {
} else if (gameUI.selected == 4) {
} else if (gameUI.craft) {
if (keyCode == UP_ARROW) gameUI.sl = (gameUI.sl - 1 + crafts.length) % crafts.length
if (keyCode == DOWN_ARROW) gameUI.sl = (gameUI.sl + 1) % crafts.length
if (keyIsDown(16)) blocks.makeAll(gameUI.sl)
else blocks.makeItem(gameUI.sl)
let ahead = world.map[player.p[0] + world.size[0] / 2 + player.d[0]][player.p[1] + world.size[1] / 2 + player.d[1]],
q = world.map[player.p[0] + world.size[0] / 2][player.p[1] + world.size[1] / 2]
player.i.i = (player.i.i + (keyIsDown(16) ? -1 : 1) + player.i.s.length) % player.i.s.length
if (ahead.block == null && ahead.item == null) {
log.push('Dropped ' + player.i.s[player.i.i])
ahead.item = player.i.s[player.i.i]
ahead.itemD = player.i.d[player.i.i]
blocks.removeItem(player.i.s[player.i.i])
} else if (ahead.block == null && ahead.item == player.i.s[player.i.i]) {
log.push('Dropped ' + player.i.s[player.i.i])
ahead.itemD = player.i.d[player.i.i]
blocks.removeItem(player.i.s[player.i.i])
log.push('Cannot drop item there.')
if (ahead.block == null && ahead.item == null) {
log.push('Dropped ' + (player.i.n[player.i.i] > 1 ? player.i.n[player.i.i].toString() + ' ' : '') + player.i.s[player.i.i])
ahead.item = player.i.s[player.i.i]
ahead.itemN = player.i.n[player.i.i]
ahead.itemD = player.i.d[player.i.i]
blocks.removeAll(player.i.s[player.i.i])
log.push('Cannot drop item there.')
if (ahead.block == 'telescope ') {
} else if (ahead.block == null && ahead.item == null && player.i.s[player.i.i] == 'telescope') {
ahead.block = 'telescope '
blocks.removeItem('telescope')
if (ahead.block == 'lamp ') {
} else if (ahead.block == null && ahead.item == null && player.i.s[player.i.i] == 'lamp') {
blocks.removeItem('lamp')
if (player.i.s[player.i.i] == 'raft' && ahead.item == null) {
if (ahead.block == null && ahead.item == null && (ahead.ground == 'water' || ahead.ground == 'pwater')) {
blocks.removeItem('raft')
log.push('Cannot place here')
if (player.i.s[player.i.i] == 'ship' && ahead.item == null) {
if (ahead.block == null && ahead.item == null && (ahead.ground == 'dwater' || ahead.ground == 'pwater') && q.item == 'bridge') {
blocks.removeItem('ship')
log.push('Cannot place here')
if (player.i.s[player.i.i] == 'rotten fence' && ahead.item == null) {
if (ahead.block == null && ahead.item == null) {
blocks.removeItem('rotten fence')
ahead.item = 'rotten fence'
log.push('Cannot place here')
if (player.i.s[player.i.i] == 'bridge' && ahead.item == null) {
if (ahead.block == 'rock' || ahead.ground == 'water' || ahead.ground == 'pwater' || ahead.ground == 'dwater') {
blocks.removeItem('bridge')
log.push('You can only bridge over mountains or water')
if (ahead.block == 'sprout' && player.i.s[player.i.i] == 'crystal orb') {
blocks.removeItem('crystal orb')
if (ahead.block == 'seedling' && player.i.s[player.i.i] == 'crystal orb') {
blocks.removeItem('crystal orb')
if (ahead.block == 'haunted sprout' && player.i.s[player.i.i] == 'crystal orb') {
ahead.block = 'haunted seedling'
blocks.removeItem('crystal orb')
if (ahead.block == 'haunted seedling' && player.i.s[player.i.i] == 'crystal orb') {
ahead.block = 'haunted tree'
blocks.removeItem('crystal orb')
if (ahead.block == 'anvil ' && (player.i.s[player.i.i].endsWith('axe') || blocks.tools.includes(player.i.s[player.i.i])) && keyIsDown(16)) {
if (player.i.s.includes('crystal orb')) {
blocks.removeItem('crystal orb')
log.push('Healed ' + player.i.s[player.i.i])
player.i.d[player.i.i] = Math.min(player.i.d[player.i.i] + 1 / 5, 1)
log.push('Not enough crystal orbs')
if (ahead.block == 'whetstone ' && (player.i.s[player.i.i].endsWith(' axe') || ['grappling hook', 'spear'].includes(player.i.s[player.i.i])) && keyIsDown(16)) {
if (player.i.n[player.i.s.indexOf('pebble')] >= 3) {
for (i = 0; i < 3; i++) {
blocks.removeItem('pebble')
log.push('Sharpened ' + player.i.s[player.i.i])
player.i.d[player.i.i] = Math.min(player.i.d[player.i.i] + 1 / 15, 1)
log.push('Not enough pebbles')
if (ahead.block == 'loom ' && keyIsDown(16)) {
if (player.i.s.includes('grass')) {
if (player.i.n[player.i.s.indexOf('grass')] >= 5) {
for (i = 0; i < 5; i++) {
blocks.removeItem('grass')
log.push('Not enough grass')
log.push('Not enough grass')
if (ahead.block == 'rock crusher ' && keyIsDown(16)) {
if (player.i.s.includes('wood')) {
if (player.i.n[player.i.s.indexOf('wood')] >= 5) {
let a = blocks.smelt2('stone')
log.push('Found ' + (a == '' ? 'nothing' : a))
blocks.removeItem('stone')
if (a != '') blocks.addItem({
for (i = 0; i < 5; i++) {
blocks.removeItem('wood')
log.push('Not enough wood')
} else if (player.i.s.includes('crystal shard') && 0) {
let a = blocks.smelt2(player.i.s[player.i.i])
log.push('Smelted ' + player.i.s[player.i.i] + ' and found ' + (a == '' ? 'nothing' : a))
blocks.removeItem(player.i.s[player.i.i])
if (a != '') blocks.addItem({
blocks.removeItem('crystal shard')
log.push('Not enough wood')
if (keyCode == 32 && ahead.block == 'bed ' && keyIsDown(16)) {
if (player.i.s.includes('crystal shard')) {
blocks.removeItem('crystal shard')
if (Math.sin((gtime + 4) / 12 * Math.PI) > 0.5) {
offset = 6.5 - (Date.now() / 1000 * 12 / tcycle) % 24
log.push('Setting spawn...');
log.push('Not enough crystal shards')
if (player.i.s[player.i.i] == 'grappling hook') {
for (a = 1; a < 20; a++) {
let b = world.map[player.p[0] + world.size[0] / 2 + player.d[0] * a][player.p[1] + world.size[1] / 2 + player.d[1] * a]
if (['open fence'].includes(b.block) && ahead !== b) {
ahead = world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a + 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a + 1)]
player.i.d[player.i.i] -= 1 / 10
if (['rotten fence'].includes[b.item] && ahead !== b) {
ahead = world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a + 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a + 1)]
player.i.d[player.i.i] -= 1 / 10
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('grappling hook');
log.push('Your hook broke')
if (player.i.s[player.i.i] == 'spear') {
for (a = 1; a < 10; a++) {
let b = world.map[player.p[0] + world.size[0] / 2 + player.d[0] * a][player.p[1] + world.size[1] / 2 + player.d[1] * a]
if (b.block == null || b.block == 'ghost') {
if (b.block == 'ghost') {
b.item = 'crystal shard';
player.i.d[player.i.i] -= 1 / 10
if (player.i.d[player.i.i] > 0) {
if (world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].item == 'spear') q = 1
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].item = 'spear'
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemN =
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemN + 1 :
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemD = player.i.d[player.i.i]
log.push('You threw a spear')
blocks.removeItem('spear')
blocks.removeItem('spear');
log.push('Your spear broke');
if (world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].item == 'spear') q = 1
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].item = 'spear'
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemN =
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemN + 1 :
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * (a - 1)][player.p[1] + world.size[1] / 2 + player.d[1] * (a - 1)].itemD = player.i.d[player.i.i]
log.push('You threw a spear')
blocks.removeItem('spear')
if (player.i.s[player.i.i] == 'scythe') {
if (player.d[0] != 0 && player.d[1] != 0) {
places.push(world.map[player.p[0] + world.size[0] / 2 + player.d[0]][player.p[1] + world.size[1] / 2])
places.push(world.map[player.p[0] + world.size[0] / 2][player.p[1] + world.size[1] / 2 + player.d[1]])
} else if (player.d[0] == 0) {
places.push(world.map[player.p[0] + world.size[0] / 2 + 1][player.p[1] + world.size[1] / 2 + player.d[1]])
places.push(world.map[player.p[0] + world.size[0] / 2 - 1][player.p[1] + world.size[1] / 2 + player.d[1]])
places.push(world.map[player.p[0] + world.size[0] / 2 + player.d[0]][player.p[1] + world.size[1] / 2 + 1])
places.push(world.map[player.p[0] + world.size[0] / 2 + player.d[0]][player.p[1] + world.size[1] / 2 - 1])
for (i = 0; i < places.length; i++) {
if (places[i].block == null) {
if (places[i].ground == 'grass') {
places[i].ground = 'dirt';
if (places[i].block == 'ghost') {
log.push('You killed a ghost')
ad.item = 'crystal shard'
player.i.d[player.i.i] -= 1 / 20
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('scythe')
log.push('Your scythe broke')
if (player.i.s[player.i.i] == 'stone axe' && ahead.block == 'ghost') {
if (ahead.health == null) ahead.health = 1
log.push('You killed a ghost')
if (Math.random() > 0.7) {
ahead.item = 'crystal shard'
log.push('You hit the ghost')
if (world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block == null) {
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block = 'ghost'
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].health = ahead.health
player.i.d[player.i.i] -= 1 / 30
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('stone axe')
log.push('Your stone axe broke')
if (player.i.s[player.i.i] == 'reinforced axe' && ahead.block == 'ghost') {
if (ahead.health == null) ahead.health = 1
log.push('You killed a ghost')
if (Math.random() > 0.6) {
ahead.item = 'crystal shard'
log.push('You hit the ghost')
if (world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block == null) {
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block = 'ghost'
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].health = ahead.health
player.i.d[player.i.i] -= 1 / 60
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('reinforced axe')
log.push('Your reinforced axe broke')
if (player.i.s[player.i.i] == 'sharp axe' && ahead.block == 'ghost') {
if (ahead.health == null) ahead.health = 1
log.push('You killed the ghost')
if (Math.random() > 0.5) {
ahead.item = 'crystal shard'
log.push('You hit the ghost')
if (world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block == null) {
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].block = 'ghost'
world.map[player.p[0] + world.size[0] / 2 + player.d[0] * 2][player.p[1] + world.size[1] / 2 + player.d[1] * 2].health = ahead.health
player.i.d[player.i.i] -= 1 / 200
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('sharp axe')
log.push('Your sharp axe broke')
if (player.i.s[player.i.i] == 'crystal axe' && ahead.block == 'ghost') {
log.push('You killed the ghost')
if (Math.random() > 0.4) {
ahead.item = 'crystal shard'
player.i.d[player.i.i] -= 1 / 200
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('crystal axe')
log.push('Your crystal axe broke')
if (ahead.block == 'closed gate' && player.i.s[player.i.i] != 'stone axe' && player.i.s[player.i.i] != 'reinforced axe' &&
player.i.s[player.i.i] != 'sharp axe' && player.i.s[player.i.i] != 'crystal axe') {
ahead.block = 'open gate';
if (ahead.block == 'open gate' && player.i.s[player.i.i] != 'stone axe' && player.i.s[player.i.i] != 'reinforced axe' &&
player.i.s[player.i.i] != 'sharp axe' && player.i.s[player.i.i] != 'crystal axe') {
ahead.block = 'closed gate';
if (Math.sin((gtime + 4) / 12 * Math.PI) <= 0.5) {
if (blocks.place.includes(player.i.s[player.i.i])) {
log.push('Cannot place here')
ahead.block = blocks.place2(player.i.s[player.i.i])
log.push('Placed a ' + player.i.s[player.i.i])
blocks.removeItem(player.i.s[player.i.i])
if (player.i.s[player.i.i] == 'stone axe' && blocks.axe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.axe[1][blocks.axe[0].indexOf(ahead.block)]
player.i.d[player.i.i] -= 1 / 30
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('stone axe')
log.push('Your stone axe broke')
log.push('You chopped down a ' + ahead.block)
ahead.item = blocks.axe[3][blocks.axe[0].indexOf(ahead.block)]
ahead.itemN = blocks.axe[2][blocks.axe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'stone pickaxe' && blocks.pickaxe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.pickaxe[1][blocks.pickaxe[0].indexOf(ahead.block)]
player.i.d[player.i.i] -= 1 / 30
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('stone pickaxe')
log.push('Your stone pick broke')
log.push('You mined a ' + ahead.block)
ahead.itemN = blocks.pickaxe[2][blocks.pickaxe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'reinforced axe' && blocks.axe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.axe[1][blocks.axe[0].indexOf(ahead.block)] * 1.5
player.i.d[player.i.i] -= 1 / 60
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('reinforced axe')
log.push('Your reinforced axe broke')
log.push('You chopped down the ' + ahead.block)
ahead.item = blocks.axe[3][blocks.axe[0].indexOf(ahead.block)]
ahead.itemN = blocks.axe[2][blocks.axe[0].indexOf(ahead.block)]
log.push('You hit a ' + ahead.block)
if (player.i.s[player.i.i] == 'reinforced pickaxe' && blocks.pickaxe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.pickaxe[1][blocks.pickaxe[0].indexOf(ahead.block)] * 1.5
player.i.d[player.i.i] -= 1 / 60
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('reinforced pickaxe')
log.push('Your reinforced pick broke')
log.push('You mined the ' + ahead.block)
ahead.itemN = blocks.pickaxe[2][blocks.pickaxe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'sharp axe' && blocks.axe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.axe[1][blocks.axe[0].indexOf(ahead.block)] * 1.5
player.i.d[player.i.i] -= 1 / 200
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('sharp axe')
log.push('Your sharp axe broke')
log.push('You chopped down the ' + ahead.block)
ahead.item = blocks.axe[3][blocks.axe[0].indexOf(ahead.block)]
ahead.itemN = blocks.axe[2][blocks.axe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'sharp pickaxe' && blocks.pickaxe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.pickaxe[1][blocks.pickaxe[0].indexOf(ahead.block)] * 1.5
player.i.d[player.i.i] -= 1 / 200
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('sharp pickaxe')
log.push('Your sharp pick broke')
log.push('You mined the ' + ahead.block)
ahead.itemN = blocks.pickaxe[2][blocks.pickaxe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'crystal axe' && blocks.axe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.axe[1][blocks.axe[0].indexOf(ahead.block)] * 3
player.i.d[player.i.i] -= 1 / 700
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('crystal axe')
log.push('Your crystal axe broke')
log.push('You chopped down the ' + ahead.block)
ahead.item = blocks.axe[3][blocks.axe[0].indexOf(ahead.block)]
ahead.itemN = blocks.axe[2][blocks.axe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
if (player.i.s[player.i.i] == 'crystal pickaxe' && blocks.pickaxe[0].includes(ahead.block)) {
if (ahead.health == null) ahead.health = 1
ahead.health += 1 / blocks.pickaxe[1][blocks.pickaxe[0].indexOf(ahead.block)] * 3
player.i.d[player.i.i] -= 1 / 700
if (player.i.d[player.i.i] <= 0) {
blocks.removeItem('crystal pickaxe')
log.push('Your crystal pick broke')
log.push('You mined the ' + ahead.block)
ahead.itemN = blocks.pickaxe[2][blocks.pickaxe[0].indexOf(ahead.block)]
log.push('You hit the ' + ahead.block)
localforage.getItem('1413912-' + world.name).then((b) => {
startUI.store = world.name;
for (i = 0; i < world.size[0]; i++) {
for (j = 0; j < world.size[1]; j++) {
for (i = 0; i < items.length; i++) {
world.map[items[i][0]][items[i][1]].item = items[i][2]
world.map[items[i][0]][items[i][1]].itemN = items[i][3]
world.map[items[i][0]][items[i][1]].itemD = items[i][4]
offset = b.time - (Date.now() / 1000 * 12 / tcycle) % 24
if (!world.name.startsWith('easy::')) {
if (world.name.startsWith('adventure::')) {
s: ['rotten fence', 'binoculars', 'bridge'],
s: ['stone axe', 'stone pickaxe'],
if (['"', "'", '\\', '/'].includes(key)) return
eval('setTimeout(()=>{if(keyIsDown(' + keyCode.toString() + '))keyRepeat["' + key + '"]=1},repeatLength)')
if (startUI.selected == 0) {
if (keyCode == 8 && world.name.length > 0) {
world.name = world.name.slice(0, world.name.length - 1)
genMap(Math.round(Math.random() * 1000), Math.round(Math.random() * 1000), Math.round(Math.random() * 1000))
for (i = 0; i < 500; i++) {
if ((!world.canWalk(world.map[world.size[0] / 2][world.size[1] / 2]))) {
genMap(Math.round(Math.random() * 1000), Math.round(Math.random() * 1000), Math.round(Math.random() * 1000))
offset = 9 - (Date.now() / 1000 * 12 / tcycle) % 24
} else if (startUI.selected == 1) {
if (keyCode == UP_ARROW) startUI.sel = (startUI.sel - 1 + startUI.selt.length) % startUI.selt.length
if (keyCode == DOWN_ARROW) startUI.sel = (startUI.sel + 1) % startUI.selt.length
world.name = startUI.selt[startUI.sel]
localforage.getItem('1413912-norm-' + world.name).then((b) => {
startUI.store = world.name;
for (i = 0; i < world.size[0]; i++) {
for (j = 0; j < world.size[1]; j++) {
for (i = 0; i < items.length; i++) {
world.map[items[i][0]][items[i][1]].item = items[i][2]
world.map[items[i][0]][items[i][1]].itemN = items[i][3]
world.map[items[i][0]][items[i][1]].itemD = items[i][4]
offset = b.time - (Date.now() / 1000 * 12 / tcycle) % 24
if (keyCode == UP_ARROW) startUI.selected = (startUI.selected - 1 + startUI.selects) % startUI.selects
if (keyCode == DOWN_ARROW) startUI.selected = (startUI.selected + 1) % startUI.selects
if (startUI.selected == 1) {
localforage.iterate((a, b) => {
if (b.startsWith('1413912-norm-')) startUI.selt.push(b.slice(13))