From e638ea209788c166979ccecfb6990a58916d72d0 Mon Sep 17 00:00:00 2001 From: Sebastian Morr Date: Thu, 22 Oct 2020 14:01:08 +0200 Subject: [PATCH] Write more time-travel levels. Order of chapters in "levels/sequence". --- cardgame.gd | 121 ++++++++++++++++++++--------------- levels.gd | 18 +++++- levels/sequence | 2 + levels/time-machine/branches | 41 ++++++++++++ levels/time-machine/conflict | 32 +++++++++ levels/time-machine/merge | 61 ++++++++++++++++++ levels/time-machine/rebase | 72 +++++++++++++++++++++ levels/time-machine/welcome | 40 ++++++++++++ main.gd | 2 +- shell.gd | 2 +- 10 files changed, 336 insertions(+), 55 deletions(-) create mode 100644 levels/sequence create mode 100644 levels/time-machine/branches create mode 100644 levels/time-machine/conflict create mode 100644 levels/time-machine/merge create mode 100644 levels/time-machine/rebase create mode 100644 levels/time-machine/welcome diff --git a/cardgame.gd b/cardgame.gd index d3d86b5..03f4fdb 100644 --- a/cardgame.gd +++ b/cardgame.gd @@ -1,73 +1,92 @@ extends Control var cards = [ +# { +# "command": 'git add .', +# "arg_number": 0, +# "description": "Add all files in the working directory to the index.", +# "energy": 1 +# }, +# +# { +# "command": 'touch "file$RANDOM"', +# "arg_number": 0, +# "description": "Create a new file.", +# "energy": 2 +# }, +# { +# "command": 'git checkout -b "$RANDOM"', +# "arg_number": 0, +# "description": "Create a new branch and switch to it.", +# "energy": 2 +# }, +# { +# "command": 'git merge', +# "arg_number": 1, +# "description": "Merge specified commit into HEAD.", +# "energy": 1 +# }, +# { +# "command": 'git commit --allow-empty -m "$RANDOM"', +# "arg_number": 0, +# "description": "Add a new commit under HEAD.", +# "energy": 1 +# }, { - "command": 'git add .', - "arg_number": 0, - "description": "Add all files in the working directory to the index.", + "command": 'git checkout', + "arg_number": 1, + "description": "Travel to a commit!", + #"description": "Point HEAD to a branch or commit, and update the index and the working directory.", "energy": 1 }, - { - "command": 'touch "file$RANDOM"', + "command": 'git add .; git commit', "arg_number": 0, - "description": "Create a new file.", - "energy": 2 - }, - { - "command": 'git checkout -b "$RANDOM"', - "arg_number": 0, - "description": "Create a new branch and switch to it.", - "energy": 2 + "description": "Make a new commit!", + "energy": 1 }, { "command": 'git merge', "arg_number": 1, - "description": "Merge specified commit into HEAD.", - "energy": 1 - }, - { - "command": 'git commit --allow-empty -m "$RANDOM"', - "arg_number": 0, - "description": "Add a new commit under HEAD.", - "energy": 1 - }, - { - "command": 'git checkout', - "arg_number": 1, - "description": "Point HEAD to a branch or commit, and update the index and the working directory.", - "energy": 1 - }, - { - "command": 'git update-ref -d', - "arg_number": 1, - "description": "Delete a ref.", - "energy": 1 - }, - { - "command": 'git reflog expire --expire=now --all; git prune', - "arg_number": 0, - "description": "Delete all unreferenced objects.", + "description": "Merge the specified timeline into yours.", "energy": 1 }, { "command": 'git rebase', "arg_number": 1, - "description": "Rebase current branch on top of specified commit.", + "description": "Put the events in your current timeline on top of the specified one.", "energy": 1 }, - { - "command": 'git push -f', - "arg_number": 0, - "description": "Push current branch to the remote, overwriting existing commits. Will make everyone angry.", - "energy": 3 - }, - { - "command": 'git pull', - "arg_number": 0, - "description": "Pull current branch from the remote.", - "energy": 2 - }, +# { +# "command": 'git update-ref -d', +# "arg_number": 1, +# "description": "Delete a ref.", +# "energy": 1 +# }, +# { +# "command": 'git reflog expire --expire=now --all; git prune', +# "arg_number": 0, +# "description": "Delete all unreferenced objects.", +# "energy": 1 +# }, +# { +# "command": 'git rebase', +# "arg_number": 1, +# "description": "Rebase current branch on top of specified commit.", +# "energy": 1 +# }, +# { +# "command": 'git push -f', +# "arg_number": 0, +# "description": "Push current branch to the remote, overwriting existing commits. Will make everyone angry.", +# "energy": 3 +# }, +# { +# "command": 'git pull', +# "arg_number": 0, +# "description": "Pull current branch from the remote.", +# "energy": 2 +# }, ] func _ready(): diff --git a/levels.gd b/levels.gd index 530d741..87b020d 100644 --- a/levels.gd +++ b/levels.gd @@ -18,13 +18,27 @@ func reload(): var file = dir.get_next() if file == "": break - elif not file.begins_with("."): + elif not file.begins_with(".") and file != "sequence": chapter_names.append(file) dir.list_dir_end() chapter_names.sort() - for c in chapter_names: + var final_chapter_sequence = [] + + var chapter_sequence = Array(helpers.read_file("res://levels/sequence", "").split("\n")) + + for chapter in chapter_sequence: + if chapter == "": + continue + if not chapter_names.has(chapter): + helpers.crash("Chapter '%s' is specified in the sequence, but could not be found" % chapter) + chapter_names.erase(chapter) + final_chapter_sequence.push_back(chapter) + + final_chapter_sequence += chapter_names + + for c in final_chapter_sequence: var chapter = Chapter.new() chapter.load("res://levels/%s" % c) chapters.push_back(chapter) diff --git a/levels/sequence b/levels/sequence new file mode 100644 index 0000000..f159582 --- /dev/null +++ b/levels/sequence @@ -0,0 +1,2 @@ +time-machine +low-level diff --git a/levels/time-machine/branches b/levels/time-machine/branches new file mode 100644 index 0000000..ef16e9e --- /dev/null +++ b/levels/time-machine/branches @@ -0,0 +1,41 @@ +[description] + +In this zoo, we found a few parallel timelines. Feel free to travel between the commits to see what's going on! The ends of the timelines have little tags attached. + +But especially the `bad_ending` one needs our attention! Can you travel to the `good_ending` one, and make a new commit that makes everyone happy? + +[setup] + +git checkout -b bad_ending + +mkdir cage +mkdir toy_shop +echo "Looks very hungry." > cage/lion + +echo "A small child. +It really loves cats! +It's holding a lollipop." > child +git add . +git commit -m "The beginning" + +mv child cage +git add . +git commit -m "The child is curious" +git branch good_ending + +git rm cage/child +echo "Looks happy. :)" > cage/lion +git commit -m "Oh no" + +git checkout HEAD~2 +git checkout -b boring_ending +mv child toy_shop +git add . +git commit -m "The child is distracted" + +git checkout bad_ending + +[win] + +# Is the child still there, and do we have a commit that's not in bad_ending? +{ git ls-tree --name-only -r good_ending | grep child; } && { test "$(git log good_ending ^bad_ending --oneline | wc -l)" -gt 0; } diff --git a/levels/time-machine/conflict b/levels/time-machine/conflict new file mode 100644 index 0000000..1d66b54 --- /dev/null +++ b/levels/time-machine/conflict @@ -0,0 +1,32 @@ +[description] + +Sometimes, merging timelines will not be as simple, because they contradict each other. + +For example, in this case, one of our clients wants these timelines merged, but they ate different things for breakfast in both timelines. + +Try to merge them together! You'll notice that there will be a conflict! The time machine will leave it up to you how to proceed: you can edit the problematic item, it will show you the conflicting sections. You can keep either of the two versions - or create a combination of them! Remove the >>>, <<<, and === markers, and make a new commit to finalize the merge! + +Again, let your finalized timeline be the "main" one. + +[setup] + +echo "Just woke up. Is hungry." > tom +git add . +git commit -m "The beginning" + +git checkout -b pancakes +echo "Had blueberry pancakes with maple syrup for breakfast." > tom +git add . +git commit -m "Pancakes!" + +git checkout -b muesli main +echo "Had muesli with oats and strawberries for breakfast." > tom +git add . +git commit -m "Muesli!" + +git checkout main + +[win] + +# main has a parent, and the parent of both its first and child parents are the same commit: +git rev-parse main^ && test "$(git rev-parse main^1~)" = "$(git rev-parse main^2~)" diff --git a/levels/time-machine/merge b/levels/time-machine/merge new file mode 100644 index 0000000..2e464ae --- /dev/null +++ b/levels/time-machine/merge @@ -0,0 +1,61 @@ +[description] + +Didn't get enouth sleep last night? Here's a trick so that you can sleep a bit longer: just do all your morning activities in parallel universes, and then at the end, merge them together! + +There are already timelines where you get a baguette and coffee. Can you make a third one where you get a donut? Drag the "branch" card to a commit to make a new branch there. + +And then, use the "merge" card to join the specified timeline together with your current one. If you merge everything into "main" in the end, into a reality where you have a baguette, a coffee, and a dount, and are outside of all shops, you can still make it to work on time! + +[setup] + +mkdir bakery coffee_shop donut_shop + +echo "A friendly old lady. +Sells delicious baguettes for 5 coins each." > bakery/mary + +echo "A rebellious teenager. +Sells good coffee for 2 coins each." > coffee_shop/larry + +echo "A snail. Literally a snail. +Sells donuts with an unspecified, slimy filling - for 3 coins each." > donut_shop/gary + +echo "You do not have a baguette. + +You do not have coffee. + +You do not have a donut." > you + +git add . +git commit -m "The Beginning" + +git checkout -b baguette +echo "You have a baguette. + +You do not have coffee. + +You do not have a donut." > you +git mv you bakery +git add . +git commit -m "You get a baguette" +git mv bakery/you . +git add . +git commit -m "You leave the bakery" + +git checkout -b coffee main +echo "You do not have a baguette. + +You have coffee. + +You do not have a donut." > you +git mv you coffee_shop +git add . +git commit -m "You get some coffee" +git mv coffee_shop/you . +git add . +git commit -m "You leave the coffee_shop" + +git checkout main + +[win] + +{ git show main:you | grep "You have a baguette"; } && { git show main:you | grep "You have coffee"; } && { git show main:you | grep "You have a donut"; } diff --git a/levels/time-machine/rebase b/levels/time-machine/rebase new file mode 100644 index 0000000..5f190ee --- /dev/null +++ b/levels/time-machine/rebase @@ -0,0 +1,72 @@ +[description] + +Okay - turns out that saving time in the morning by utilizing parallel universes is against the regulations of the International Time Travel Association. You'll have to do your tasks in sequence after all. + +See the "rebase" card? It takes a specified commit, and puts the events in your current timeline on top of the specified one! This way, make a clean, linear timeline where you visit all three shops. + +[setup] + +mkdir bakery coffee_shop donut_shop + +echo "A friendly old lady. +Sells delicious baguettes for 5 coins each." > bakery/mary + +echo "A rebellious teenager. +Sells good coffee for 2 coins each." > coffee_shop/larry + +echo "A snail. Literally a snail. +Sells donuts with an unspecified, slimy filling - for 3 coins each." > donut_shop/gary + +echo "You do not have a baguette. + +You do not have coffee. + +You do not have a donut." > you + +git add . +git commit -m "The Beginning" + +git checkout -b baguette +echo "You have a baguette. + +You do not have coffee. + +You do not have a donut." > you +git mv you bakery +git add . +git commit -m "You get a baguette" +git mv bakery/you . +git add . +git commit -m "You leave the bakery" + +git checkout -b coffee main +echo "You do not have a baguette. + +You have coffee. + +You do not have a donut." > you +git mv you coffee_shop +git add . +git commit -m "You get some coffee" +git mv coffee_shop/you . +git add . +git commit -m "You leave the coffee shop" + +git checkout -b donut main +echo "You do not have a baguette. + +You do not have coffee. + +You have a donut." > you +git mv you donut_shop +git add . +git commit -m "You get a donut" +git mv donut_shop/you . +git add . +git commit -m "You leave the donut shop" + +git checkout baguette + +[win] + +{ git show main:you | grep "You have a baguette"; } && { git show main:you | grep "You have coffee"; } && { git show main:you | grep "You have a donut"; } && { test "$(git log main --oneline | wc -l)" -eq 7; } diff --git a/levels/time-machine/welcome b/levels/time-machine/welcome new file mode 100644 index 0000000..cadb3f0 --- /dev/null +++ b/levels/time-machine/welcome @@ -0,0 +1,40 @@ +[description] + +Welcome, time agent! Good to see you - we could really use your help with fixing some temporal paradoxes! + +First, let's make you familiar with the time machine you'll be using: each yellow box you see is a frozen point in time, we call them "commits"! You can travel to one by dragging the "checkout" card to it, and you can go back to the present by dragging it on the blue "main" node! + +The grey panel to the left shows your current environment - click on an object to inspect or modify it! + +Can you find out what happened here? Then, come back to the present, fix the problem, and make a new commit! + +[setup] + +mkdir room1 room2 +echo "A young girl with brown, curly hair." > room1/little_sister +echo "This piggy bank belongs to the big sister. +It contains 10 coins." > room2/piggy_bank +git add . +git commit -m "The beginning" + +mv room1/little_sister room2 +git add . +git commit -m "Little sister walks over" + +echo "Has 10 coins." >> room2/little_sister +echo "This piggy bank belongs to the big sister. +It is empty." > room2/piggy_bank +git add . +git commit -m "Little sister does something" + +mv room2/little_sister room1 +git add . +git commit -m "Little sister walks back" + +[win] + +{ git show refs/heads/main:room2/piggy_bank | grep "10 coins"; } && { git show refs/heads/main:room1/little_sister | grep -v "10 coins"; } + +[congrats] + +Wonderful! Now that you're familiar with the time machine, let's look at some more complicated situations... diff --git a/main.gd b/main.gd index af15e1b..db14e6f 100644 --- a/main.gd +++ b/main.gd @@ -27,7 +27,7 @@ func _ready(): helpers.crash("Could not change to sandbox scene") return - current_chapter = 1 + current_chapter = 0 current_level = 0 # Initialize level select. diff --git a/shell.gd b/shell.gd index db9d7ba..66d1b4a 100644 --- a/shell.gd +++ b/shell.gd @@ -15,7 +15,7 @@ func cd(dir): # Run a shell command given as a string. Run this if you're interested in the # output of the command. func run(command, crash_on_fail=true): - var debug = false + var debug = true if debug: print("$ %s" % command)