TIC-80 icon indicating copy to clipboard operation
TIC-80 copied to clipboard

Collaboration feature

Open wadetb opened this issue 4 years ago • 16 comments

Hi there.

I'm not sure if there's any interest in this feature. It adds Google Docs-like collaboration to TIC-80, while keeping to the spirit of the overall project, at least to the best of my understanding and ability.

The feature is not finished but is usable in the current state, and I thought it would be a good time to seek feedback.

Some background:

Over the past few years I've been running workshops for groups ages 8 up to college, using a combination of PICO-8 and TIC-80, and it's very difficult for the kids to work together. For instance, one kid makes an awesome animation and the other kids want to grab it, one kid wants to do the characters while another does the backgrounds and another one does the music, or just two or three kids want to collaborate on a project without knowing who does what.

The implementation high level view is that there is a server maintaining a database of "shared carts", and TIC-80 instances can "connect" to a shared cart and push & pull changes. I very intentionally stayed away from source control topics such as conflicts, history, and so on. All pushes to and pulls from the shared cart are manual operations by the TIC-80 user, and if they don't like the result of a pull they can simply undo it. The only automatic part of the system is a realtime display that shows where the local cart differs from the shared cart at a fairly fine-grained level, e.g. the line of code, the sprite, the music track, etc.

The code diff is the only complicated part of the implementation, in that it performs a full text diff with line matching in order to accurately display highlights and to push and pull line diffs.

The server is a simple Python script that ideally should run behind something like Nginx through a proxy. It maintains the state of the shared carts as files in a working directory. While it's possible that a central, official collaboration server be established, I do wonder about security, privacy and so on. It might be easier if individual users just run the server on their own instances. If a central server was desired then I feel like we'd want to establish the ability for users to administer their shared carts in some way.

Here is a video showing a rough demo of an older version, with two instances connected to a shared cart:

https://youtu.be/d_KLZINw6U4

Regarding what's left in the implementation, I think the feature could be wrapped in a define so as to not break ports that might lack threads or networking, and the thread creation needs to be abstracted into the system interface. Additionally, I'd like to move the code diff into a helper thread which will delay the display slightly but ensure that even giant code files continue to update smoothly.

As far as ongoing development goes, I'm happy to continue to support the feature long term, in fact I'm submitting it to the project rather than maintaining the private fork, in the vain hope that it might be released for Android before my next set of workshops in March, which utilize Chromebooks.

If you'd like to chat about this work further or would like to see a demo and have a walk-through review of the code, feel free to contact me as wadeb on TIC-80 Discord.

wadetb avatar Nov 24 '19 01:11 wadetb

Interesting idea. While I'd prefer to use git instead of this, it is nice to have it embedded directly in the application.

I can see how kids would love to collaborate directly through this.

RobLoach avatar Nov 24 '19 16:11 RobLoach

Agreed, interesting idea and it looks very close to being merged to the main branch. Also agreed with your thoughts about wrapping all the Collab code with a define and pls add a CMake option (smth like option(BUILD_COLLAB "Build with collaboration feature" OFF)). Currently, TIC developed as a single-threaded application because it's much easier to port it to other platforms (especially web/wasm) without threading, if you could do run your code in one thread it would be great, but not necessary. Thank you for your work and I'd like to show the feature demo to the Twitter community if you don't mind :)

nesbox avatar Nov 25 '19 08:11 nesbox

Hi there, interesting feature and great implementation! I'm a bit unsure about whether the benefits are worth the added complexity. Your use case is surely valid but the changes so pervasive. Have you perhaps field-tested it with your students? Did the code/sprite/etc snippet sharing worked?

I wonder if something more like "google docs" would be more appropriate, where the state is instantly broadcasted over to all connected clients, instead of the push/pull mechanic.

It surely needs some compiler switch to enable/disable the system.

Anyway, great job!

msx80 avatar Nov 25 '19 15:11 msx80

Thanks for the excellent feedback all! It's very encouraging that you think the feature is interesting and potentially a good addition. @nesbox, feel free to publicize it all you want :) My Twitter handle is @wadetb if you want to tag me.

I'll put the #define in and look into threading. The only place where I'm relying on it is when receiving streaming updates from the HTTP server. But it's possible that libcurl has a polled API? My initial implementation was on top of the old net.c HTTP code, and I just did a quick rewrite after libcurl was checked in.

@msx80 regarding instant Google Docs vs manual push/pull, the first concern that drove me towards manual push/pull is breakage: If one person is actively coding something I want the others to be able to run with the code they have. It also gives people the ability to try stuff out locally without publishing it to others until they're ready.

Also, trolling and just general disagreement: if someone is messing around I don't want them to be able to bring the other kids down, it feels better to leave the control in the individuals hands. Anyone can screw up the shared cart by pushing to it, but it doesn't disrupt the other people automatically (and they can fork to a new collab instance to ditch the annoying person :)).

Finally, undo: If we had instant Google Docs-like edits, I'm not sure what would be undone - others changes or only your own? I guess I'd need to spend some time with Google Docs to try to puzzle that out. As it stands, local undo provides a kind of poor man's history. Each pull from the shared cart adds an Undo entry, so you can pull and see what's new, but then undo to revert it if it's broken somehow. Or undo all the way back to some older revision and push it to a new shared cart, as a kind of fork. It's a bit ugly but it does provide some useful functionality that way.

I have not done any testing with kids yet, but I plan to try some quick jams at my office this week to see how this all works in practice. I kind of made the mistake of implementing it all the way before reaching a minimum viable product.

Regarding the invasiveness of the change to the code, I agree that it's pretty substantial - mostly it's all of the highlighting checks - there might be some way to isolate that further. At least in the UI, there's no visible difference (aside from a slight toolbar reshuffle), until the collab command is actually executed. Note, there are probably places where the highlighting could be improved as well, either aesthetically or functionally. In particular the code diff, the line matching probably breaks down in a bunch of instances.

Anyway, thanks again for the feedback - I'll make the changes requested and work on fixing CI, and feel free to send more comments.

wadetb avatar Nov 25 '19 21:11 wadetb

But it's possible that libcurl has a polled API?

@wadetb Hi, I just accidentally found an example of using Curl with libuv running in a single thread. Maybe you will be interested :)

nesbox avatar Nov 29 '19 11:11 nesbox

Oops, forgot to paste url https://curl.haxx.se/libcurl/c/multi-uv.html

nesbox avatar Nov 29 '19 15:11 nesbox

Nice, thanks for that link, the single threaded curl API works perfectly.

I just pushed an update with the ifdef and no threads, will look at fixing CI next and also do some testing.

wadetb avatar Nov 30 '19 03:11 wadetb

Looks interesting, is there any chance for a separate mode without pulling and pushing? (changes would update immediately), like "collab2"

saranvdev avatar Nov 30 '19 14:11 saranvdev

Sure, I could do that and add collab auto to toggle that. I've already added some extra keywords like collab off. It would be a useful way to spectate on development but you'd have to be careful about your changes being trashed if you made any.

One kind-of-crazy thought I had is to make a HTML "live viewer" that attaches to a shared cart and shows all the editors' contents on one page. You could pop it up on a projector and watch everyone working at the same time, in a jam setting.

Any thoughts about the private vs public server thing? I was thinking about maybe splitting out a collab host to select the server, so that collab <id> doesn't require typing out a full URL. Would it want auth? Now that we have CURL it can be HTTPS... But wondering if there should be a default host, if collab should have more help.

Lots of polish questions to answer. Also, feedback on the visual style of the yellow highlights is welcome. I played around with making it "glint" but am not very good at pixel art. And the map/sprite view outlining could be better.

wadetb avatar Nov 30 '19 14:11 wadetb

I think it will be better to hold up this PR until .80 will be released with the new UI, it will be easier to adopt it later.

nesbox avatar Dec 02 '19 09:12 nesbox

Just to followup, that plan is fine with me of course. I'll keep testing and experimenting with the feature.

Is there a branch with the new UI I can access, to start looking at adapting the code to it?

wadetb avatar Dec 11 '19 15:12 wadetb

We have https://github.com/nesbox/TIC-80/tree/sweetie16 branch where I adapt UI to the new Sweetie16 palette, but there is no much progress because I'm stuck with implementing commands for the music tracker :)

nesbox avatar Dec 12 '19 09:12 nesbox

This is a game changing, concept. there are global area network provider that is free to use. like zerotier-one i always use this to form a peer-to-peer connection to anyone that i allow to connect to my network. also it works great in L4D,L4D2,PPSSPP, and other LAN based games...

revdeluxe avatar Dec 10 '21 06:12 revdeluxe

Sorry for necro-ing, is this dead?

darltrash avatar Jun 23 '22 23:06 darltrash

Yeah, @wadetb is there any chance?

l3td33r avatar Jun 26 '22 13:06 l3td33r

Yeah, @wadetb is there any chance?

Yes, apologies - just been a busy year. Still planning to resurrect and finish.

wadetb avatar Jul 09 '22 03:07 wadetb

This looks amazing! Well done @wadetb !

sthilaid avatar Feb 13 '23 13:02 sthilaid