No more version history, now we have just the contents of the current version.
Editing a definition no longer changes the order in which definitions load.
This should make repos easier to browse, and more amenable to modify. You don't need driver.love anymore. And a stable order eliminates some gotchas. For example:
using driver.love, define Foo = 3
in a definition
define Bar = Foo + 1
edit and redefine Foo = 4
Before this commit, you'd get an error when you restart the app. Definitions used to be loaded in version order, and editing a definition would move it to the end of the load order, potentially after definitions using it. I mostly avoided this by keeping top-level definitions independent. It's fine to refer to any definition inside a function body, we only need to be careful with initializers for global variables which run immediately while loading.
After this commit you can still end up in a weird state if you modify a definition that other later definitions use. In the above example, you will now see Foo = 4 and Bar = 4. But when you restart, Foo = 4 and Bar = 5. But that's no more confusing than Emacs's C-x C-e. It's still a good idea to keep top-level definitions order-independent. It's just confusing in a similar way to existing tools if you fail to do so. And your tools won't tend to break as badly.
Why did I ever do my weird version history thing? I think it's my deep aversion to risking losing any data entered. (Even though the app currently will seem to lose data in those situations. You'd need to leave your tools to find the data.) Now I rely on driver.love's undo to avoid data loss, but once you shut it down you're stuck with what you have on disk. Or in git.
I also wasn't aware for a long time of any primitives for deleting files. This might have colored my choices a lot.
EP5R7WRBMFV7CFIVIWWOUUCB3E4HMNTJGJPKMHE6YH3XMERQXCGQC
U4O3INOFIJQJSUHZ43BSV3PXMBB2C7CNJCGAOOKFYYSSIDWTZANAC
GAOTNMBJGXMED675ZULUSZESGBWGDEYCMNLBTXZHINBLGHMQSRSQC
HDD64J5QDTWETRV656DZF4DOI4ID2W7R6O6OW4GPYN2ISTVVH4AQC
AQUUQRKNXHQXQ25KM47HHUOBXWKAAU7CWY4ZMTS75TCK3SHTYU4AC
KA3ZPGPDAVTHBPZKWRWKPEVDL3W3LWEPAAPEI6X25EJPYK2KVR3QC
L46GUB3GKR7CU6GHJ4256NAGSTWOZL2THAPQ46VC4DD7GVRMNKNQC
AZVVTFLUICXDW6KC57NFDGCPEQHAYCMZD772ZZEUGLUGHK7O6X2AC
3T4OMAPQBS6TPV2CJNCK3PXWTELMOYS2ZKJXMG4RELNME3ZNQWFQC
NFCHPKVTV3BZ5DPALD7SH22BDQYRRBJ54MOFQLG3QXHSHC24PUXQC
R4PMTRF75RCAYGFCEPWKF6YE73YCHW5S36F76O3FWIQVNBKTTNSAC
ZJPFAJVMVVKNZCQPQPCHIPCLMG5VRNVUMG5ZY3VR5B57PRNFJAOAC
W64KNGQ7BUJCWSB674W2K6H7PMLEILX6YT7UAHCH7KZZYBD23Y2AC
ZSQHOD3FLEKS2QK5YN2JFVJXECDTVVPHYQ7Z6JQNRPMP4ZI3YM6AC
NETD7AIQRAUJANR6STEZ4VMJ2ZAFURE5EPYYTJSS2K4ZG7SKGCNAC
P5VRKGUWJYP25PPLTK4FXW3NTFNEFN35URSWWZ4TKJQIFXX56VQAC
WX25KJRVEV5WLTV2AVIMEWEAQ5LJ2DFJIKF33APXNN46L5URDO3AC
C6AT7PEUHQMNRTF2EJOGDDULKPZRF3SRUXTNUSIAKTWFIN4ILZEQC
TR7NG6RNU7ITYZVTUJ62HEOJHTL3G26QTCUEI6S4AQLKTVU76ITQC
json = require 'json'
function main(args)
local infile = io.open(args[1])
local manifest_s = infile:read('*a')
infile:close()
local manifest = json.decode(manifest_s)
local core_filenames = {}
for k,v in pairs(manifest) do
if not starts_with(k, 'fw_') then
table.insert(core_filenames, k)
end
end
table.sort(core_filenames)
for _,core in ipairs(core_filenames) do
local filename = ('%04d'):format(manifest[core])..'-'..core
local f = io.open(filename)
if f then
print(f:read('*a'))
print('')
end
end
end
function starts_with(s, prefix)
if #s < #prefix then
return false
end
for i=1,#prefix do
if s:sub(i,i) ~= prefix:sub(i,i) then
return false
end
end
return true
end
main(arg)
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 600 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 10 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
# The on-disk representation of freewheeling apps
When you start up a freewheeling app, you'll see a directory printed out in
the parent terminal (always launch it from a terminal window):
```
new edits will go to /home/...
```
When editing such an app using the driver (see [README.md](README.md)), new
definitions will go into this directory. Let's call it `$SAVE_DIR` in the rest
of this doc.
It is always safe to move such definitions into this repo. (We'll call it `.`
in the rest of this doc.) You'll want to do this if you're sharing them with
others, and it's also helpful if the driver crashes on your app. Moving
definitions will never, ever change app behavior.
```sh
$ mv -i $SAVE_DIR/[0-9]* . # should never clobber any existing files
$ mv $SAVE_DIR/head . # expected to clobber the existing file
```
Try looking inside the `head` file with a text editor. It'll contain a number,
the current version of the _manifest_ for this app. For example:
```
478
```
This means the current state of the app is in a file called `0478-fwmanifest`.
If you moved the files you should see such a file in `.`. If you open this
file, you'll see a JSON table from definition names to version ids. For
example:
```
{ "a": 273, "b": 478}
```
This means the current definition of `a` is in `0273-a` and of `b` in
`0478-b`.
Poking around these files gets repetitive, so there's a tool to streamline
things:
```
lua tools/stitch-live.lua 0478-fwmanifest
```
`stitch-live.lua` takes a manifest file as its argument, and prints out all
the definitions that make up the app at that version.
To compare two versions of the app, use `stitch-live.lua` to copy the
definitions in each into a separate file, and use a file comparison tool (e.g.
`diff`) to compare the two files.
# Scenarios considered in designing this representation
* Capture history of changes.
- Though it is perhaps too fine-grained and noisy.
* Merge changes from non-live forks to live ones.
- New files in repo can't hide changes in save dir, because filenames are
always disjoint between the two.
- This doesn't apply yet to live updates. Two forks of a single live app
will likely have unnecessary merge conflicts.
* No special tools required to publish changes to others.
- Just move files from save dir to repo.
# Scenarios I _would_ like to take into consideration in the future
* Cleaner commits; it's clear what changed.
* merge changes between live forks.
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
draw_debug()
end
on.update = function(dt)
local P = 600 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 10 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 10 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
-- love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 5 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 30 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
-- love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
line(0,300,0,-300)
line(400,0,-400,0)
-- circ('fill', 100, 0, 4)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi/P
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
-- line(0,300,0,-300)
-- line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.update = function(dt)
local P = 6 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
Angle = t*2*math.pi
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*2*math.pi)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*4*math.pi)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*2*math.pi)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*2*math.pi)
--line(0,300,0,-300)
--line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*math.pi)
--line(0,300,0,-300)
--line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*2*math.pi)
--line(0,300,0,-300)
--line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Night_blue*2*math.pi)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 4)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 100, 0, 2)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
line(0,300,0,-300)
line(400,0,-400,0)
circ('fill', 10, 0, 2)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
line(0,300,0,-300)
line(400,0,-400,0)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.push()
love.graphics.translate(400,300)
line(0,300,0,-300)
love.graphics.pop()
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
--draw_debug()
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
--if x%100 == 0 then
--love.graphics.print(('%.2f'):format(d), x, d*600)
--else
circ('fill', x, d*600, 2)
--end
end
end
on.update = function(dt)
local P = 6 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
if d*600 > 590 then
line(x,0, x,600)
end
end
end
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
draw_debug()
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 60 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
--draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
draw_debug()
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 10 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
-- t = 0.8
-- t = 0.9
-- t = 1.1 => Night_blue = (2-1.1) = 0.9
-- t = 1.2 => 2-1.2 = 0.8
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
--draw_debug()
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
-- t = 0.8
-- t = 0.9
-- t = 1.1 => Night_blue = (2-1.1) = 0.9
-- t = 1.2 => 2-1.2 = 0.8
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
local t = (app.Current_time - math.floor(app.Current_time/P)*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
-- t = 0.8
-- t = 0.9
-- t = 1.1 => Night_blue = (2-1.1) = 0.9
-- t = 1.2 => 2-1.2 = 0.8
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
local t = (app.Current_time - math.floor(app.Current_time)/P*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
local t = (app.Current_time - math.floor(app.Current_time)/P*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
-- local t = (app.Current_time - math.floor(app.Current_time)/P*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - math.floor(app.Current_time))
-- local t = (app.Current_time - math.floor(app.Current_time)/P*P)
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = (P-t)/(P/2)
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t/(P/2)
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2/P
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2/P
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= 1)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2/P
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
love.graphics.print(#Debug_state, 700, 100)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
if d*600 > 590 then
line(x,0, x,600)
end
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
love.graphics.print(#Debug_state, 700, 100)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
if d*600 > 750 then
line(x,0, x,600)
end
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
love.graphics.print(#Debug_state, 700, 100)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
if d*600 > 790 then
line(x,0, x,600)
end
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
love.graphics.print(#Debug_state, 700, 100)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
if d*600 < 790 then
line(x,0, x,600)
end
end
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2/P
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
assert(0 <= t)
assert(t <= P)
if t > P/2 then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
if t > 0.5*P then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
if t > 0.5*P then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
-- t is between 0 and P
if t > 0.5*P then
Night_blue = ((P-t)*2)/P
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
assert(0 >= t)
assert(t <= 1)
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
love.graphics.print(#Debug_state, 700, 100)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
end
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(('%.2f'):format(d), x, d*600)
else
circ('fill', x, d*600, 2)
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(d, x, d*600)
else
circ('fill', x, d*600, 2)
end
end
end
draw_debug = function()
love.graphics.setColor(1,1,1)
love.graphics.line(0,300, 800,300)
for x,d in ipairs(Debug_state) do
if x%100 == 0 then
love.graphics.print(x, x, d*600)
else
circ('fill', x, d*600, 2)
end
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, t)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (P-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 2 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.update = function(dt)
local P = 1 -- Period in seconds
local t = (app.Current_time - (math.floor(app.Current_time)/P*P))/P
if t > 0.5 then
Night_blue = (1-t)*2
else
Night_blue = t*2
end
table.insert(Debug_state, Night_blue)
if #Debug_state > 800 then
table.remove(Debug_state, 1)
end
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
draw_debug()
end
on.draw = function()
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.3)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.5)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*3})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.5)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*4})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.6)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*4})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.8)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*4})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.8)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600, color=love.math.random(), radius=love.math.random()*2})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
end
on.draw = function()
love.graphics.clear(0,0,0.7)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(1,1,0)
love.graphics.circle('fill', star.x,star.y, 4)
end
end
on.draw = function()
love.graphics.clear(0,0,0.7)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800, y=love.math.random()*600})
end
end
for _,star in ipairs(Stars) do
love.graphics.setColor(1,1,0)
love.graphics.circle('fill', star.x,star.y, 4)
end
end
end
on.draw = function()
love.graphics.clear(0,0,0.7)
if #Stars == 0 then
for i=1,100 do
love.graphics.setColor(1,1,0)
love.graphics.circle('fill', love.math.random()*800, love.math.random()*600, 4)
end
end
end
-- on incoming messages to a specific file, however, the app must:
-- save the message's value to a new, smallest unused numeric prefix
-- on incoming messages to a specific file, the app must:
-- determine the definition name from the first word
-- look up the filename for the definition or define a new filename for it
-- save the message's value to the filename
-- version control
app.Head = 0
app.Next_version = 1
app.History = {} -- array of filename roots corresponding to each numeric prefix
app.Manifest = {} -- mapping from roots to numeric prefixes as of version app.Head
app.freeze_all_existing_definitions()
app.Filenames_to_load = {} -- filenames in order of numeric prefix
app.Filename = {} -- map from definition name to filename (including numeric prefix)
app.Final_prefix = 0
function app.load_files_so_far()
print('new edits will go to ' .. love.filesystem.getSaveDirectory())
local files = {}
app.append_files_with_numeric_prefix('', files)
table.sort(files)
app.check_integrity(files)
app.append_files_with_numeric_prefix(love.filesystem.getSaveDirectory(), files)
table.sort(files)
app.check_integrity(files)
app.History = app.load_history(files)
app.Next_version = #app.History + 1
local head_string = love.filesystem.read('head')
app.Head = tonumber(head_string)
if app.Head > 0 then
app.Manifest = json.decode(love.filesystem.read(app.versioned_manifest(app.Head)))
-- Everything that exists before we start loading the live files is frozen and
-- can't be edited live.
function app.freeze_all_existing_definitions()
app.Frozen_definitions = {on=true} -- special case for version 1
local done = {}
done[app.Frozen_definitions]=true
app.freeze_all_existing_definitions_in(_G, {}, done)
end
function app.freeze_all_existing_definitions_in(tab, scopes, done)
-- track duplicates to avoid cycles like _G._G, _G._G._G, etc.
if done[tab] then return end
done[tab] = true
for name,binding in pairs(tab) do
local full_name = app.full_name(scopes, name)
--? print(full_name)
app.Frozen_definitions[full_name] = true
if type(binding) == 'table' and full_name ~= 'package' then -- var 'package' contains copies of all modules, but not the best name; rely on people to not modify package.loaded.io.open, etc.
table.insert(scopes, name)
app.freeze_all_existing_definitions_in(binding, scopes, done)
table.remove(scopes)
end
function app.append_files_with_numeric_prefix(dir, files)
for _,file in ipairs(love.filesystem.getDirectoryItems(dir)) do
table.insert(files, file)
end
function app.full_name(scopes, name)
local ns = table.concat(scopes, '.')
if #ns == 0 then return name end
return ns..'.'..name
function app.check_integrity(files)
local manifest_found, file_found = false, false
local expected_index = 1
for _,file in ipairs(files) do
for numeric_prefix, root in file:gmatch('(%d+)-(.+)') do
-- only runs once
local index = tonumber(numeric_prefix)
-- skip files without numeric prefixes
if index ~= nil then
if index < expected_index then
print(index, expected_index)
end
assert(index >= expected_index)
if index > expected_index then
assert(index == expected_index+1)
assert(manifest_found and file_found)
expected_index = index
manifest_found, file_found = false, false
end
assert(index == expected_index)
if root == 'fwmanifest' then
assert(not manifest_found)
manifest_found = true
else
assert(not file_found)
file_found = true
end
function app.load_files_so_far()
print('new edits will go to ' .. love.filesystem.getSaveDirectory())
-- if necessary, copy files from repo to save dir
if io.open(love.filesystem.getSaveDirectory()..'/0000-freewheeling-start') == nil then
print('copying all definitions from repo to save dir')
for _,filename in ipairs(love.filesystem.getDirectoryItems('')) do
for numeric_prefix, root in filename:gmatch('(%d+)-(.+)') do
-- only runs once
local buf = love.filesystem.read(filename)
print('copying', filename)
love.filesystem.write(filename, buf)
end
function app.load_history(files)
local result = {}
for _,file in ipairs(files) do
for numeric_prefix, root in file:gmatch('(%d+)-(.+)') do
-- load files from save dir
for _,filename in ipairs(love.filesystem.getDirectoryItems('')) do
for numeric_prefix, root in filename:gmatch('(%d+)-(.+)') do
local index = tonumber(numeric_prefix)
-- skip
if index ~= nil then
if root ~= 'fwmanifest' then
assert(index == #result+1)
table.insert(result, root)
end
if tonumber(numeric_prefix) > 0 then -- skip 0000
app.Filename[root] = filename
table.insert(app.Filenames_to_load, filename)
app.Final_prefix = math.max(app.Final_prefix, tonumber(numeric_prefix))
-- return any error encountered, or nil if all well
function app.load_everything_in_manifest()
local files_to_load = {}
for k,v in pairs(app.Manifest) do
if not starts_with(k, 'fw_') then
local root, index = k, v
local filename = app.versioned_filename(index, root)
table.insert(files_to_load, filename)
end
end
table.sort(files_to_load)
for _,filename in ipairs(files_to_load) do
function app.load_all()
for _,filename in ipairs(app.Filenames_to_load) do
--? print('loading', filename)
app.Manifest[APP] = love.filesystem.getIdentity() -- doesn't need to be persisted, but no harm if it does..
app.send(json.encode(app.Manifest))
app.Filename[APP] = love.filesystem.getIdentity()
app.send(json.encode(app.Filename))
local binding = buf:match('^%S+%s+(%S+)')
app.Manifest[binding] = nil
app.eval(binding..' = nil') -- ignore errors which will likely be from keywords like `function = nil`
local next_filename = app.versioned_filename(app.Next_version, binding)
love.filesystem.write(next_filename, '')
table.insert(app.History, binding)
app.roll_forward()
local definition_name = buf:match('^%s*%S+%s+(%S+)')
if app.Filename[definition_name] then
local index = table.find(app.Filenames_to_load, app.Filename[definition_name])
print('index')
table.remove(app.Filenames_to_load, index)
for i,v in ipairs(app.Filenames_to_load) do
print(i, v)
end
app.eval(definition_name..' = nil') -- ignore errors which will likely be from keywords like `function = nil`
print(_G[definition_name])
love.filesystem.remove(app.Filename[definition_name])
print('deleted')
app.Filename[definition_name] = nil
end
local binding = cmd
local next_filename = app.versioned_filename(app.Next_version, binding)
love.filesystem.write(next_filename, buf)
table.insert(app.History, binding)
app.Manifest[binding] = app.Next_version
app.roll_forward()
local definition_name = cmd
if app.Frozen_definitions[definition_name] then
app.send('ERROR definition '..definition_name..' is part of Freewheeling infrastructure and cannot be safely edited live.')
return
end
-- eval succeeded without errors; persist the definition
local filename = app.Filename[definition_name]
if filename == nil then
app.Final_prefix = app.Final_prefix+1
filename = ('%04d-%s'):format(app.Final_prefix, definition_name)
table.insert(app.Filenames_to_load, filename)
app.Filename[definition_name] = filename
end
love.filesystem.write(filename, buf)
-- update app.Head and record the new app.Manifest (which caller has already modified)
function app.roll_forward()
app.Manifest[PARENT] = app.Head
local manifest_filename = app.versioned_manifest(app.Next_version)
love.filesystem.write(manifest_filename, json.encode(app.Manifest))
app.Head = app.Next_version
love.filesystem.write('head', tostring(app.Head))
app.Next_version = app.Next_version + 1
end
-- update app.Head and reload app.Manifest appropriately
function app.roll_back()
app.Head = app.Manifest[PARENT]
love.filesystem.write('head', tostring(app.Head))
local previous_manifest_filename = app.versioned_manifest(app.Head)
app.Manifest = json.decode(love.filesystem.read(previous_manifest_filename))
function table.find(h, x)
for k,v in pairs(h) do
if v == x then
return k
end
end
* This app encourages a style of development that requires top-level
definitions to be decoupled from each other. No live functions load until
all definitions have been run. However top-level globals are initialized as
they're loaded. This makes a definition like this a very bad idea, assuming
`Foo` and `Bar` are top-level variables:
on.initialize = function()
love.window.setTitle('night')
local rand = love.math.random
for i=1,100 do
table.insert(Stars, {
x=rand()*800-400,
y=rand()*600-300,
color=rand(),
radius=rand()*3
})
end
end
love.graphics.clear(0,0,0.7)
love.graphics.clear(0,0,Night_blue)
if #Stars == 0 then
for i=1,100 do
table.insert(Stars, {x=love.math.random()*800-400, y=love.math.random()*600-300, color=love.math.random(), radius=love.math.random()*3})
end
end
love.graphics.push()
love.graphics.translate(400,300)
love.graphics.rotate(Angle)
for _,star in ipairs(Stars) do
love.graphics.setColor(star.color, star.color, 0)
love.graphics.circle('fill', star.x,star.y, star.radius)
end
love.graphics.pop()
--draw_debug()
Debug_state = {} -- put anything you want here
Angle = 0
This file contains no definition, but is used as a marker in the save dir to indicate all definitions have been copied from the repo to the save dir.