Rozproszenie gry c++

Rozproszenie gry c++
C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Witam, napisałem prosty zarys gry piłkarzyki w c++, w której jest dwóch graczy i jeden przemieszcza piłkarzykami WASD a drugi strzałkami i na jednym kompie to działa. Mam pytanie, jakich użyć tchnologii, żeby rozproszyć to na dwa komputery, tzn jeden operator na swoim drugi na swoim i żeby grali między sobą? Tak jakąś najprostszą techniką, nie musi być najbardziej efektywna. Ktoś może ma jakiś pomysł?

M1
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

Musisz stworzyć serwer. Przez, który dane będą przesyłane. Powinieneś zainteresować się TCP. I wtedy, każdy ruch musisz przesłać do serwera, a ten przekazuje to wszystkich, którzy są połączeni z danym serwerem.

@Ps. Przykładowe dane : Piłkarz1 -> pozycja(122,333)

edytowany 1x, ostatnio: maniek1310
ShookTea
A ja wiem, czy serwer taki konieczny? Czemu nie przesyłać danych bezpośrednio?
ŁF
@ShookTea: Wystarczy, że jeden gracz będzie za NAT i już masz problem, a jeśli obaj będą schowani w sieciach lokalnych, to nie pograją w ogóle.
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Zależy gdzie chcesz mieć tą "prostotę". Możesz to zrobić socketami co jest niskopoziomowe i przez to "proste", a możesz przez CORBA i wtedy prostota będzie w samej implemenatacji gry ale technologia prosta nie będzie.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
M1
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

@ShookTea Jeżeli przysłanie danych będzie bezpośrednie to przeważnie da się grać tylko po sieci LAN, gdyż większość dostawców internetowych blokuje porty i trudno bd wtedy wysłać dane.

C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Prostota, to chodzi o to żeby było łatwo napisać lub jakiś wzór żebym znalazł. W zasadzie zależy mi na czasie, jak najszybciej to ogarnąć więc pomijam detale wydajności, efektywności czy zabezpieczeń.
Moze być bezpośrednio lub nie, obojętne, ważne żebym jak miał dwa kompa swoje to żeby taka gierka działała mi. Dlatego zastanawiam się jakby mi to było najłatwiej rozwiązać, pisząc pod c++. Lapki podłączone do jednej sieci przez wifi wystarczą czy musze kabelkiem jakoś?

M1
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

Może być przez wifi jak i przez kabel, jest to obojętne. Nie napisałeś o jakie biblioteki się opierasz. Bo najprościej według mnie byś miał korzystając z framework-a Qt i bibliotekę QTcpSocket.

Ps. Znalazłem poradnik, jak ktoś to robi w tym framework-u.
http://blog.matthew.org.pl/2010/03/13/kurs-qt-czesc-7-tcp/

edytowany 2x, ostatnio: maniek1310
spartanPAGE
A co, jeśli jest podłączony kablem? :O
M1
To jest bez różnicy czy są podłączone kablem czy bezprzewodowe, bo przecież i tak będą mieli ten sam numer IP (w tej samej sieci).
spartanPAGE
"Może być przez wifi"
C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Miałem dwie opcje zrobić to jakoś przez WinSock lub użyć MPI, jednak poczytam o tym Qt. Bo w sumie musze wysylać tylko pozycje z macierzy (nowe pozycje) do drugiego uzytkownika zeby mu sie zaktualizowało boisko na ekranie.

M1
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
1

Możesz też zrobić to prościej np. poprzez bazę SQL :) Tworzysz sobie serwer MySQL np. programem WampServer i potem w programie przesyłasz do bazy wszystkie potrzebne dane a druga osoba odczytuje i nawzajem.

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
6
maniek1310 napisał(a):

Możesz też zrobić to prościej np. poprzez bazę SQL :) Tworzysz sobie serwer MySQL np. programem WampServer i potem w programie przesyłasz do bazy wszystkie potrzebne dane a druga osoba odczytuje i nawzajem.

Zróbmy plebiscyt: kto wymyśli gorszy i bardziej niedorzeczny sposób komunikacji pomiędzy dwoma klientami gry toczącej się w czasie rzeczywistym... Takie rozwiązanie to nawet dla turowej gry byłoby mega słabe.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
M1
Ale przecież autor tematu napisał, że na razie nie musi być wydajne :)
n0name_l
Mozna tez recznie przenosic dane na pendrive'ie. Nie musi byc przeciez wydajne.
Shalom
Można też przez telefon przekazywać sobie ruchy. W szachy tak ludzie grają czasem. Albo pisać listy :D
gośćabc
rozwiązanie komunikacji przez bazę danych stosuje się w wielu systemach czasu rzeczywistego, zapewnia to gwarancję otrzymania pełnej wiadomości (gdzie jest to bardzo ważne), co nie jest gwarantowane po sockecie; więc nie użyłbym tutaj argumentu "czas rzeczywisty", tylko raczej porywanie się z pistoletem na muchę
Shalom
@gośćabc czemu baza danych zamiast message passing?
gośćabc
nie powiedziałem, że baza danych; jedynie chciałem ubić Twój argument o "czasie rzeczywistym" i bazą danych
n0name_l
zapewnia to gwarancję otrzymania pełnej wiadomości (gdzie jest to bardzo ważne), co nie jest gwarantowane po sockecie;, jest gwarantowane.
Shalom
@gośćabc mylisz pojęcia, jak zwykle zresztą. Nie pisałem tu nic o systemie czasu rzeczywistego, gdzie użyć bazę się da jeśli mamy ustalone odpowiednie limity czasowe (no bo przeciez system czasu rzeczywistego znaczy tyle że mamy pewność wykonania operacji w określonym czasie). A ja pisałem o graniu w grę która toczy się w czasie rzeczywistym i przez to potrzebuje jak najmniejszego narzutu na komunikacje żeby efektywnie synchronizować stan rozgrywki pomiędzy klientami. Jeśli gra byłaby turowa albo miała mocne ograniczenie na ruchy (np. 1 ruch na sekundę) to byłoby inaczej...
gośćabc
@n0name_l jest, ale nie jest gwarantowane, że się nie poszarpie/poskleja; @Shalom miałem 4 linijki tekstu dla Ciebie, ale zdecydowałem, że nie warto, gratuluje kolejne +3 za sarkastyczny hating a tu masz dowód na to, że nie masz pojęcia o wydajności połączenia z bazą danych; to jest moja aplikacja, która komunikuje się z inną aplikacją; obie sterują jednym z magazynów dużej znanej firmy; http://i.imgur.com/Iu6Ppxi.png timestamp jest ustawiany automatycznie przez bazę w momencie umieszczenia tam wiadomości, a timestamp odbioru jest ustawiany przez drugą aplikację;
gośćabc
pamiętam jak byłem dzieckiem to były takie stopery duże, próbowałem w jak najszybszym czasie po starcie zatrzymać stoper, udawało mi się to w 11 setnych sekundy; a w tej grze chłopaki pewnie będą klikać szybciej
Shalom
@gośćabc ale o czym niby ten screen świadczy? o_O Chyba tylko o tym że macie dobrze napisany mechanizm wykrywania nowych wiadomości, nic więcej. Bo przecież te timestampy nijak nie uwzględniają ile czasu potrzeba było na przekazanie komunikatu (abstrahując nawet od tego ze autor tematu chciał komunikować aplikacje na różnych hostach a ty pokazujesz screen zapewne z dwóch aplikacji na tym samym...). Gdyby timestamp1 był ustawiany przez aplikację 1 zaraz przed "wysłaniem" a timestamp2 przez aplikacje2 zaraz po odebraniu to moze i ten obrazek mialby choćby minimalny sens.
gośćabc
no tak no bo w momencie, gdy dane masz w programie to zajmuje sekundy żeby zmienić stan ui, a co do 1 części to czas od momentu wejścia zadania do mnie od jeszcze innego systemu do momentu umieszczenia rozkazu w bazie wynosi 15ms, a mam dużo więcej do zrobienia niż tylko odbić stan aktualny gry; pytający nic nie mówił o tym gdzie będą odpalane aplikacje; jak mówiłem nie masz pojęcia o wydajności bazy danych;
Shalom
Widać pisanie dobrze ci idzie, gorzej z czytaniem żeby rozproszyć to na dwa komputery, tzn jeden operator na swoim drugi na swoim i żeby grali między sobą?
gośćabc
'ważne żebym jak miał dwa kompa swoje to żeby taka gierka działała mi' dla mnie to 1 host sry ale już nie mogę, wygrałeś
gośćabc
i żeby było jasne, JA TUTAJ NIE FORSUJĘ TEGO rozwiązania; to tylko dyskusja o wydajności nic więcej, jego pytanie jest nieważne
Shalom
2 komputery to jest u ciebie jeden host? o_O Ale właśnie jest ważne! Bo jest różnica co piszesz. Jak będziesz chciał napisać grę FPS to nie będziesz robił multiplayera za pomocą komunikatów przekazywanych przez bazę danych...
gośćabc
literówka, zbaczasz z tematu; typowe
gośćabc
skończmy temat, jak dla mnei masz 0 expa w kodowaniu systemów komunikujących się za pomocą bazy danych, coś tam usłyszałeś i hateujesz jak programiści c++ javowców;
gośćabc
"2 komputery to jest u ciebie jeden host? o_O Ale właśnie jest ważne! Bo jest różnica co piszesz. Jak będziesz chciał napisać grę FPS to nie będziesz robił multiplayera za pomocą komunikatów przekazywanych przez bazę danych.." no pewnie że nie, ja nie twierdzę że baza danych jest tutaj super rozwiązaniem, napisałem że to jak strzelanie do much z pistoletu błagam Cię;
n0name_l
ale nie jest gwarantowane, że się nie poszarpie/poskleja; bazy tez tego nie gwarantuja :c
n0name_l
Nie umiem tego prosciej napisac...
Shalom
Słyszeliście kiedyś o TCP i SCTP? :P Gwarantuje że się nie poszarpie ani nie poskleja... ;]
n0name_l
Tez sie po drodze poszarpie i poskleja...
gośćabc
@n0name_l i jak to się ma do poszarpanych/posklejanych komunikatów podanych przez tcp/ip (które lądują bezpośrednio w Tojeje aplikacji)
n0name_l
Tak jak napisalem. Bazy nie gwarantuja, ze sie cos nie poszarpie po drodze czy nie poskleja, bo nie maja zbytnio na to zadnego wplywu. A samo TCP daje mniej-wiecej taka sama gwarancje co do otrzymania/wyslania danych jak baza. Argument, ze baza na pewno dostarczy, a TCP nie jest bzdura... Ba. Bazy uzywaja tego samego TCP -.-'
gośćabc
kto napisał że TCP nie dostarczy, wiecie co ja zmykam z tego tematu, to jest jakieś skakanie z kwiatka na kwiatek, nie wiem jaki jest tego cel, ale zaczynam mieć wrażenie, że nie warto gadać z niektórymi w ogóle, bo oni nie chcą gadać merytorycznie; to jest wymyślanie jakichś tematów, których nie było, a ja się łatwo denerwuję kiedy coś takiego się dzieje
n0name_l
O tutaj: zapewnia to gwarancję otrzymania pełnej wiadomości (gdzie jest to bardzo ważne), co nie jest gwarantowane po sockecie, cale to zdanie jest jedna wielka bzdura, i nastepne 20 komentarzy z niej wynika ;c
gośćabc
wiesz co to znaczy "otrzymanie pełnej wiadomości" a "brak gwarancji na otrzymanie pełnej wiadomości"? czy to znaczy, że wiadomość w ogóle nie przyjdzie? to nie to zdanie tylko Ty i Twoje rozumowanie to jedna wielka bzdura; a i ja w przeciwieństwie do Ciebie lubię poszperać i popytać i już wiem, że są możliwości kiedy TCP nie dostarczy wiadomości, ale to nie jest wiedza przeznaczona dla haterów takich jak Ty, sam sobie poszukaj
n0name_l
A wiesz co napisales, czy wciaz nie bardzo? + Gratuluje nabycia tajemnej wiedzy klasztornej, dostepnej na wikipedii. Sam fakt, ze musiales tego szukac swiadczy tylko o tym, ze nie masz pojecia jak rzeczy dzialaja, o ktorych mowisz...
gośćabc
@Shalom możesz to ukrócić, ten gostek już zaczyna nudzić, to nie jest już dyskusja o cpp tylko wymyślanie czegoś czego nie było; ja nie będę odbijał piłeczek, nie ten poziom
Shalom
Przykro mi, nie da się zablokować komentarzy ;]
n0name_l
Podsumowujac: 1. TCP nie gwarantuje otrzymania pelnej wiadomosci. 2. Baza gwarantuje otrzymanie pelnej wiadomosci. 3. Baza przesyla wiadomosci po TCP. I to niby ja cos wymyslam, eh..
n0name_l
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:2412
1
C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

A jeżeli chciałbym rozproszyć prosto, tzn klient - serwer, gdzie klient przesyła swój ruch (lewo, prawo, przod, tył) i w zaleznosci co dostanie serwer wykonuje swoj ruch, tzn tak jakby gra jednego gracza z komputerem, to przy c++ i zrobieniu osobnego wątku dla gracza (wymagane) najlepiej będzie mi zastosować biblioteke WinSock?

C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Mam takie pytanie, zacząłem robić na socketach więc ok, tylko jak chce połączyć np. serwer na jednym kompie a klienta na drugim, żeby działało na więcej kompach i musze podać adres IP serwera a nie localhost, to jak go wydobyć, żeby się łączyło?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Albo wstukać ręcznie jak w niektórych grach siczowych.
Albo zrobić UDP latarnie.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
M1
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

Ip serwera to będzie takie jakie masz przypisane do tego komputera gdzie masz postawiony serwer.

Dla topornych :)
https://www.youtube.com/watch?v=OeHC73GJsO8

C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Ok już wiem, działa. Mam jeszcze pytanko, działa mi serwer dla jednego klienta, jednak chciałbym zrobić dla przynajmniej dwóch, żeby dwóch sie mogło połączyć lub więcej. (celem i tak będzie żeby klient1 wysyłał coś na serwer i zostało to przekazywane do klienta2 i pozniej klient2 cos wysyła do 1 i takie ruchy w petli).

Jednak jak zrobić z połączeniem dla wielu klientów?
Mam coś takiego:

Kopiuj
 SOCKET mainSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); // tworzenie gniazda socket
if( mainSocket == INVALID_SOCKET )
{
    printf( "Error creating socket: %ld\n", WSAGetLastError() );
    WSACleanup();
    return 1;
}

sockaddr_in service;
memset( & service, 0, sizeof( service ) );
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr( "192.168.1.173" ); // zdefiniowanie adresu ip
service.sin_port = htons( 27015 ); // zdefiniowanie portu

if( bind( mainSocket,( SOCKADDR * ) & service, sizeof( service ) ) == SOCKET_ERROR ) // przypisanie do gniazda portu i adresu
{
    printf( "bind() failed.\n" );
    closesocket( mainSocket );
    return 1;
}

if( listen( mainSocket, 1 ) == SOCKET_ERROR ) // nasluchiwanie przez serwer
     printf( "Error listening on socket.\n" );

SOCKET acceptSocket = SOCKET_ERROR;
printf( "Waiting for a client to connect...\n" );

if( acceptSocket == SOCKET_ERROR )
{
    acceptSocket = accept( mainSocket, NULL, NULL );
}
printf( "Client connected.\n" );
mainSocket = acceptSocket;
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Osobne wątki dla każdego klienta.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
C6
  • Rejestracja:około 11 lat
  • Ostatnio:dzień
  • Postów:197
0

Czyli na przykład na serwerze stworzyć dla klienta - wątek, przyjmę że max dwóch klientów to mi i to utworzyć dwa wątki za pomocą process.h i beignthread tylko jak to później sklecić, żeby oczekiwał na połaczenie dwóch klientów(wątków) i jeśli jest są połączenie to jakas tam wymiana danych?

n0name_l
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:2412
0

Uzyj jakiejs biblioteki sensownej jak czlowiek, a nie API systemowego. No chyba, ze tak bardzo kochasz miliony problemow...

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)