*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

суббота, 9 января 2010 г.

Инструментальное скоростное прохождение игр

Когда-то я играл в Дум, особенно в Дум 2. Ночью по модему с постоянными обрывами связи, потом по локальной сети, потом через интернет. Да и сейчас люблю порой оттянуться c друзьями на старых "клаcсических" картах Дума, например через Doom Legacy.

Но сейчас не об этом. Дум сразу имел классную особенность — записывать игровые сессии для последующего просмотра. Это порой очень увлекательное зрелище, особенно когда играет мастер или мастера. А самая главная штука — это способ записи. При записи игровой сессии записываются не кадры видеоизображения, а просто последовательность действий игрока — зажатия на клавиатуру и движения мыши или джойстика. Во-первых, такая запись занимает очень мало места, во-вторых — это "чистая" запись, исключащая видеомонтаж, так как для проигрывания можно использовать свою копию игры, которая заведомо нормальная.

Едем дальше. В любой игре подобного толка есть новички (они же "мясо"), есть сильные игроки (я!), а есть мега-монстры (в случае с Думом — "дум-годы"). Очевидно, что сессии игры, записанные такими спецами смотрятся как увлекательное кино. Уровень, который ты проходишь минут за 5 он проходит за 5 секунд. Всю игру, на прохождение всех уровней которой у тебя могут уйти недели, он проходит за 15 минут на максимальной сложности. Наблюдать за этим просто сказка, особенно когда еще такие спецы рубятся друг против друга.

Но сейчас снова не об этом.

Что я познал недавно?

Оказывается с развитием мощностей компьютеров и, как следствие, эмуляторов старых платформ, появилось такое движение как TAS — Tool assisted-speedrun (инструментальное скоростное прохождение). В двух словах — это показательное прохождение игры до победного конца за рекордное время.

Как это делается. Берется старая "классическая" игра. Запускается на эмуляторе. Работа на эмуляторе позволяет делать с игрой все что угодно — замедлять время, дизассемблировать исходный код, делать временные сохранения достигнутых результатов даже если сама игра такого не позволяет, анализировать недостатки и внутренние особенности "движка" игры, пробовать разные маршруты и т.д. Море всяких трюков. Очевидно, что игра живого игрока во многом ориентирована на безопасность, нежели на время прохождения. "Автоматизированный" же игрок может делать то, что живой никогда делать не будет — может подойти к врагу очень близко, так как заведомо знает, что из-за особенностей движка игры при расстоянии, например, в 2 пикселя, враг тебя никогда не убьет. А живой игрой может даже и 20 пикселей не рискнет, так как ему "на глаз" так проще. И "автоматизированный" игрок может уже не бежать за здоровьем, имея только 1% жизни, так как точно известно, что ему этого хватит до конца уровня.

В общем, шаг за шагом, уровень за уровнем создается и записывается в виде действий "игрока" оптимальный сценарий прохождения игры. После этого найденный оптимальный сценарий подсовывается оригинальной игре (или оригинальной игровой приставке) — либо через механизм проигрывания демо-сессий (если игра поддерживает таковой), либо изготавливается для игры специальный игровой контроллер (клавиатура, мышь или джойстик), который уже управляется не человеком, а компьютером по найденному оптимальному сценарию. И игра проходится, проходится вся и очень быстро. Так например, был пройден классический "Супер Марио" на Ниндендо чуть ли не за 5 минут.

Например, вот один из так называемых speedrun'ов в Дум 2:

и Супер Марио:

Понятно, что такая "игра" далека от получения удовольствия от реальной игры, но это просто другой, но также очень увлекательный жанр.

среда, 6 января 2010 г.

Больше коммитов, хороших и разных

Как часто у вас бывает, когда после часов работы выясняется, что все беспробудно сломано и уже не поддается никакой отладке. И причем уже непонятно, где новый код, а где старый. И в этом случае надо доставать вчерашний бэкап и как-то выяснять, что вы тут напрограммировали.

А все было бы заметно проще, если бы в процессе любой длинной и сложной работы делались бы промежуточные коммиты в систему контроля версий — своеобразные реперные точки, по которым можно пошагово отследить изменения.

Когда же используется централизованная система контроля версий (SCM) многие люди не коммитят незаконченный код, ибо в подавляющем числе случаев работа ведется в ветке, которой пользуется еще кто-то. Закоммитишь сломанный код — услышишь слова радости в свой адрес из другого конца комнаты.

Создание же ветки (нужно, например, для отслеживания изменений при отладки конкретного бага) в централизованной SCM более менее событие. Многие конторы имеют свои правила и процедуры создания веток (именование, причины создания, порядок их удаления и т.д.). Все это можно понять, так как внесения изменений в любой ресурс общего пользования (коим являтся репозиторий централизованной SCM) должны подчиняться каким-то правилам, а иначе будет хаос, и никто не сможет работать.

Что делать если у вас используется централизованная SCM? Просто начните использовать любую из современных распределенных систем параллельно с основной централизованной. Для начала можно вообще не вдаваться в детали хитрой интеграции локальной распределенной SCM и централизованной для автоматизированного переноса коммитов туда-сюда (например, как p4-git для Git и Perforce), а делать все просто: просто коммитить процесс работы в вашу собственную локальную распределенную систему для удобства отслеживания микро изменений, а когда все готово — делать большой коммит на сервер.

Мне приходится работать параллельно с разными SCM, и они преимущественно централизованные (SVN, Perforce, ClearCase), и преимущественно правила коммитов и слияний между ветками очень жесткие и детально прописанные. А про создание собственных веток я уж и не говорю. Но это не мешает мне локально использовать git, в котором в дополнение к официальным веткам сидит десяток моих собственных, коммиты и слияние в которых я делаю десятки раз в день.

Я стараюсь коммитить как можно чаще. Например, добавил новый target в Makefile — коммит, добил новый тест (пусть даже он пока не компилируется толком) — коммит, заставил тест компилироваться — точно коммит, ну а заставил тест работать — стопудово коммит. Решил попробовать новый метод линковки проекта и для этого подкорячить Makefile — создал новую ветку, поигрался, слил результаты с основной веткой и удалил временную. Конец рабочего дня и пора лететь на купание дочки — коммит, даже если исходники представляют собой поле боя, так как завтра тебя с утра могут неожиданно перебросить на Умань чинить срочный баг, и потом уже точно не вспомнить, что там к чему.

Также желательно, чтобы коммиты были логически изолированы. Например, в запале ты исправил сетевую подсистему и добавил кнопку в UI — не стоит объединять все это в один коммит, так как может случиться, что вы заходите эту новую кнопку в параллельной версии, и если это отдельный коммит, то перенести его можно будет простым слиянием или cherry-pick'ом. Наличие staging area (индекса) в git позволяет легко коммитить выборочно (причем даже файл по кускам). Для Mercurial я нашел более менее похожую возможность в TortoiseHG, когда при коммите можно отметить файлы, которые в него включаются.

А так как каждый коммит требует словесного описания, то волей неволей это заставляет тебя оглядывать в целом, что ты тут понаписал. Для экстренных коммитов в конце дня, когда все может быть тотально сломано, а коммитить надо, то я обычно ставлю префикс "UNFINISHED: " в описание, по которому с утра сразу видно, что в исходниках может быть засада.

Лирическое отступление. С некоторого времени у меня даже всякие самопальные скрипты в UNIXе (а у кого их нет?) и конфигурационные файлы типа .profile, .Xdefaults или .vimrc живут под контролем git'а. Другой пример: скачал я новый gdb-7.0. Развернул, скомпилил. При работе он начал иногда падать на определенных машинах с ошибкой. Интернет сказал, что это известный баг и есть патч. Так вот: сначала сразу после разворачивания оригинального архива дерево исходников gdb помещается в git (git init && git add * && git commit -m "Original gdb-7.0."), а только затем делается патч и тоже коммитится в git. Для чего? Чтобы понимать, что изменено, когда и почему.

Еще одно лирическое отступление. Ни что так помогает понять, насколько "нужен" тебе некий домашний хлам, как его датирование. Записал DVD с бэкапом — кроме названия диска еще надо надписать дату записи. Собрал документы по сданному проекту в архивую папку — поставил дату. Потом, через N лет, этот стикер с датой однозначно решит судьбу предмета и, возможно, определит его в помойку, освободив место в шкафу. В компьютере все это далается еще проще. Ну а история изменений/версий только приятно автоматизируют процесс.

Культура повсеместного использования контроля версий крайне позитивна. А распределенные системы (типа Git, Mercurial или Bazaar) позволяют приобщиться к прекрасному даже если все вокруг вас не хотят (пока!) принять эту культуру.

Посты по теме:

понедельник, 4 января 2010 г.

Виртуальные машины в быту

Лично я плохо представляю себе работу современного программиста сейчас без виртуальных машин. Даже на моем домашнем ноутбуке конфигурация выглядит так: "dark side" в виде Windows 7 в качестве хост-системы и пачка линуксовых виртуальных машин под VMware и VirtualBox.

Windows 7 для iTunes (увы, iPhone иначе толком не синхронизируешь), MS Office (в основном только ради Visio) и Visual Studio разнообразных версий. Все остальное происходит в виртуальных машинах. Благодаря аппаратной виртуализации в современных процессорах производительнось практически такая же (и у кого сейчас меньше двух ядер?). А умелое распределение ресурсов между виртуальными машиными вообще позволяет нивелировать потери.

Большинство современных виртуализаторов умеют очень ловко интегрировать десктоп гостевой системы в основную. Например, у меня окно той же виртуализированной Ubuntu выглядит обычным окном Windows, размер которого можно спокойно менять, при этом виртуальная среда автоматически подстраивает свой десктоп на лету под размер этого окна. Раньше, когда аппаратная поддержка виртуализации не была так распространена, и поэтому виртуальные машины реально тормозили, я долгое время использовал Cooperative Linux, так как он виртуализирует только память, и поэтому работает на полной скорости компьютера. Но coLinux не поддерживает многопроцессорность и требует особого ядра Линукса. С самим ядром уже не поиграешься.

В чем прелесть такого подхода с виртуальными машинами? Для начала — это изолированность сред. Не надо держать на одной системе много конфликтующего хлама, ибо постоянно для разных проектов нужны разные компиляторы, разные библиотеки, может и разные операционные системы. Диски/накопители для виртуальных сред — это просто файлы. Их просто копировать, уменьшать/расширять, сохранять, использовать для разных сред и т.д. И миграция с одного физического компьютера на другой упрощается в разы, так как надо просто слить образы машин.

Захотел подключить новый диск в систему или подменить развернутый Oracle на другую версию — пять минут работы. Захотел вернуть назад — еще две минуты. Да и клиенту дать образ настроенной виртуальной машины проще, чем объяснять, как все настраивать с нуля. А он потом еще все и сломает шаловливыми ручками.

Пока я вижу только один значительный минус при домашнем использовании — дисковое пространство, ибо для каждой системы счет сразу идет на гигабайты, а может и их десятки. 4-5 виртуальных машин, и начинаешь думать, куда бы сбросить временно неиспользуемые.

Но и тут есть выход. Например, у меня юниксовый раздел для домашнего (home) каталога используется в нескольких виртуальных машинах. Раздел с проектами тоже может быть замонтирован в разные машины. Повторюсь — управление дисковыми разделами в виде файлов крайне просто и удобно.

Для серверных решений весьма популярна система виртуальных операционных систем ESXi. Небольшой супервизор грузится в начале, и затем дает возможность управлять виртуализацией гостевых систем (диски, память, процессорное время и т.д.). То есть мой Windows 7 является простецким аналогом такого супервизора.

Подходим к сути. Так сейчас уже стало модно заменять стандартный BIOS на что-нибудь нужное, например Линукс с минимальным набором программ для интернета. Проекты coreboot и Splashtop уже давно существуют. Некоторое время назад лично я был очень впечатлен одним их видео:

Выходит, что логичным продолжением было бы зашить вместо BIOSа супервизор виртуальных машин.

Включаешь компьютер, мгновенно стартует супервизор, который дает тебе возможность управлять витуальными средами. Вот получится все одном флаконе на одном компьютере: и Windows, и Mac, и Linux и все на свете.

Проблемы конечно будут — надо делать драйвера виртуальных устройств под поддерживаемые операционные системы, но многое уже имеется в тех же VMware и VirtualBox.

В общем, в дополнение к модной "облачной" модели домашних компьютеров виртуальная модель однозначно имеет будущее. Для тех, кто любит "по-горячее".

вторник, 22 декабря 2009 г.

Wiki2blog: онлайновый wiki-редактор для Blogspot

Как я уже писал, что из-за неудобства онлайнового редактора Blogspot'а я перешел на использование Wiki на Google Code для написания и хранения постов. То есть я пишу пост, используя язык разметки Wiki, отлаживанию разметку, заливаю картинки и т.д., а затем просто конвертирую wiki-файл с помощью скрипта на php в html. Фишка тут в том, что скрипт должен учитывать некоторые "особенности" Blogspot'а — необходимость убирать разделители строки после блочных тэгов типа blockquote, pre, списков и т.д., чтобы не появлялись ненужные отступы. В результате выходной html становится практически нечитаемым.

Удобство же wiki-разметки в том, что исходник поста выглядит красиво и пригоден для последующего редактирования.

Но в таком подходе цикл работы над постом несколько длинноват: редактор, push через Mercurial на Google Code, просмотр как выглядит на Wiki, затем прогон через скрипт, и если все хорошо, то "cut-paste" в онлайн-редактор Blogspot и финальный отсмотр там. А если обнаруживаются шероховатости, что цикл повторяется сначала. И еще меня раздражал сам скрипт — корявый и непонятный.

Хотелось чего-нибудь легкого и более менее WYSIWYG.

Порыскав в сети на наткнулся на wiki2html. И это оказалось то, что нужно. Я немного подкорячил это под свой формат wiki-разметки и, в итоге получилось это: онлайновый редактор с препросмотром для подготовки постов в Blogspot.

Теперь цикл такой: набиваешь пост в этом редакторе, а он автоматически отображает preview по мере набора вместе с htmlем. Затем cut-paste html-я в Blogspot, и с большой вероятностью форматирование должно выглядеть как задумано.

Ни разу не претендую на возможные странности моего диалекта Wiki. Желающие могут изменить под себя, ибо форматировщик крайне простой.

Редактор состоит из одного файла wiki2html.html. Его можно просто сохранить локально и поиграться.

Под занавес привожу поддерживаемые команды wiki-разметки (таблиц пока нет).

Ссылки и картинки

[http://example.com/test] — ссылка: http://example.com/test

[http://example.com/test ссылка с текстом] — ссылка с текстом

[http://github.com http://github.com/images/icons/public.png] — картинка со ссылкой

[http://github.com/images/icons/public.png] — картинка

[http://github.com/images/icons/public.png картинка по ссылке] — картинка по ссылке

Текст

'''bold''' — bold

''italic'' — italic

@@[http://google.com]@@ — экранирование любой wiki-разметки

моно`ширин`ный текст — моноширинный текст

Заголовки

= Заголовок1 =

== Заголовок2 ==

=== Заголовок3 ===

==== Заголовок4 ====

===== Заголовок5 =====

Цитирование

Цитата начинается с двух пробелов.

Разделитель

---


Ненумерованный список

Код:

* это
** ненумерованный
* список

Как выглядит:

  • это
    • ненумерованный
  • список

Нумерованный список

Код:

# это
## нумерованный
# список

Как выглядит:

  1. это
    1. нумерованный
  2. список

Исходники

Код:

{{{

#include <io.h>

int main() {

  int a = 1;

  return a;

}

}}}

Как выглядит:

#include <io.h>
int main() {
  int a = 1;
  return a;
}

Видео

[http://www.youtube.com/watch?v=FrufJFBSoQY]

Собственно, этот пост я подготовил по описанной технологии. Можно посмотреть как его исходник выглядит в wiki-формате.

Посты по теме:

среда, 16 декабря 2009 г.

Тренинг Steve Dewhurst'а "C++ Common Knowledge"

Побывал на тренинге Steve Dewhurst'а "C++ Common Knowledge". У меня уже давно есть его книга:



и в целом конкретно этот тренинг посвящен темам из нее.

Очень прикольный дядька. Нескучно, разбавлено подколами аудитории и шутками типа что ребята из Boost'a не иначе как курят шаблоны и т.д. Мне очень понравилось.

Стив сказал, что С++ - это практически все, что делал и делает в жизни. Писал компиляторы, утилиты, разбирался в стандартах, а сейчас вот дает тренинги.

Не могу сказать, что я узнал что-то особенно новое — это было бы странно, так как его книжку (см. выше) читал от корки до корки и периодически к ней возвращаюсь. Хотя, пожалуй, одна мысль меня зацепила: правильное написание конструктора копирования или оператора присваивания для класса, в иерархии которого есть виртуальный базовый класс с данными является весьма запутанной задачей. Тут однозначно нарушается принцип логической независимости уровней иерархии наследования, так как надо точно знать, от каких классов ты унаследован и как их правильно инициализировать при множественном наследовании.

Рекомендация такая: сначала задаешь себе вопрос: а нужно ли мне тут множественное наследование? а нужно ли мне виртуальное множественное наследование?? а нужно ли мне виртуальное множественное наследование с данными в базовом виртуальном классе??? И даже после долгого раздумья лучше сказать "нет". Лично я не имею ничего против множественного наследования. Но мне не очень нравится как это сделано в С++. И мне не очень нравится как это сделано в Java. Мне очень нравится, как сделано в Go. А именно: в Go полностью разнесены понятия структур данных и интерфейсов. Структуры данных не могут быть унаследованы. Они могут только реализовывать интерфейсы. А наследовать можно только интерфейсы. Поэтому в принципе нельзя при наследовании подцепить чужие данные, а только методы. А нет данных, не и проблемы их инициализации.

Итак, могу просто собрать общие рекомендации от Стива:
  • стараться использовать виртуальные функции и полиморфизм в целом вместо "if" и "case"
  • стараться использовать алгоритмы STL/Boost и функторы вместо циклов
  • использовать только "умные" указатели при работе с динамической памятью
  • не использовать классические массивы, а контейнеры STL (так как, например, std::vector гарантирует линейное размещение элементов, то можно смешивать "старый" код, работающий с указателями, с использованием контейнеров)
  • тщательно продумывать операции копирования сложных классов (лучше всего реализовать конструктор копирования и метод swap, а оператор присваивания реализовать через них)
  • всегда объявлять в коде класса конструктор копирования и оператор присваивания, и даже если они не используются, то просто закомментировать их объявление с пояснением, почему они не нужны
  • никогда не использовать приведения типов в стиле С, только С++ (static_cast, const_cast и т.д.), так как они длинные, их нудно набивать и они уродуют вид программы - в общем, все, что нужно для минимизации их наличия
  • помнить, что наследование - это re-use интерфейсов, а не кода как такового
  • не слишком верить компилятору ;-) (Стив их писал и знает, что они могут и подставить)

вторник, 15 декабря 2009 г.

Peter Seibel, "Coders at Work"

Неспешно дочитал "Coders at Work".

Peter Seibel, Coders at Work



Книга состоит из интервью с десятком известных программистов. Тут есть создатели UNIX, Netscape, JavaScript, Smalltalk, Haskell, Erland, Ghostscript, ЖЖ и также есть просто Дональд Кнут. В общем, не самые последние люди.

Автор задает всем похожие вопросы: когда и почему вы начали программировать, как вы обычно работаете, где и над чем вы работали и работаете сейчас, что вы думаете о развитии языков программирования за последние десятилетия, что вы можете посоветовать молодым и т.д. Около мемуарная тема опасна тем, что можно элементарно скатиться в старческое брюзжание типа "а вот в наши годы..." или "вы в машинных кодах пишите, и будет вам наука...", но у всех оказался очень взвешенный взгляд на действительность. Конечно, есть радикальное разделение на функциональщиков и императистов, но уже вопрос религии, нежели возраста.

Многие ссылаются на разные книги - я значительно пополнил свой список на "прочитать".

Забавно, что почти никто не отозвался однозначно положительно о С++. Либо было однозначное нет типа "очень перегружено, сложно и т.д.", либо "ну раз уж более ничего пока лучше нет для создания native кода промышленной сложности, то пусть будет".
Лирическое отступление. Я тут покуриваю Go, и чем дальше, тем больше меня прет. Могу сказать, что я почти для всех своих плюсовых привычек нашел альтернативу в Go. Ну а его врожденная мультипотоковость и ультра быстрая компиляция довершают все.
Также интересно мнение на тему обязательно ли для всем уважающим себя программистам прочитать "Искусство программирования" Кнута или хотя бы иметь в своей библиотеке. Многие признали, что не читали от корки до корки, но как справочник используют.

Как всегда убедился, что я даже и не слышал о некоторых крайне известных вещах. Например, Literate programming от Дональда Кнута или фильтр Блума.

В общем, я нашел книгу очень интересной. Если вас накрывает тоска типа "а можно или всю карьеру программировать?..." или "надо таки подаваться в менеджмент или в архитекторы, а то тут молодые наседают...". Тут дается отличный, но скрытый ответ: любой из этих путей может принести и удовлетворение и, что важно, достаток. В этом прелесть нашей профессии. Просто делай то, от чего хочется работать до ночи, смотри по сторонам, интересуйся, что происходит вокруг, и не переживай, что можешь оказаться ненужным - это не так.

суббота, 28 ноября 2009 г.

Электронная записная книга TiddlyWiki

Лично я очень люблю задавать вопросы, но я не люблю задавать один и тот же вопрос дважды. А иногда случается, что неожиданно сваливается большой поток новой информации (например, начинается проект), и голове все не удержать. Естественно, обычный бумажный блокнот позволяет производить начальную фиксацию информации, но когда объем записей, к которым необходимо часто возвращаться, переваливает за 8-10 исписанных страниц, то начинается каша.

Какой логичный выход? Использовать для записей компьютер.

Долгое время я использовал просто текстовый файл, например в Ворде. Например, начался проект или новая работа — сразу валит поток фактов, которые я в этот файл записываю. Обычно где-то раз в неделю я вбиваю записи из блокнота и тонны бумажек.

Так как информации много, то ее хочется как-то логично организовывать - главы, разделы, подразделы и т.д. Но со временем я заметил, что основной способ навигации впоследствии - это ни разу не оглавление, а просто поиск по словам. Например, мне нужно вспомнить, что мне там объясняли на тему как вбивать расходы или где смотреть отчеты по ночным сборкам. Я просто нажимаю CTRL-F и ввожу слово "расходы" или "ночные". Как говориться, "Don't sort. Search!"

Наличие всего в одном файле упрощает техническую сторону вопроса - хочешь в Ворде работай, хочешь в Vi. И бэкапить удобно или в контроль версий засунуть.

Кстати, интересное наблюдение. В случае новой работы по первости обычно приходится фиксировать много рутинных вещей, типа как запускать сборку, как организованы исходники, где находится то или это и т.д. Обычно месяца через два-три поток стихает. Но когда приходит новый человек, и я ему выдаю такой файл, который в свое время создавал сам - обычно люди офигевают от того, получают ответы на почти все вопросы новичка, и говорят спасибо.
Итак, простой текстовый файл как всегда на коне. Но некоторое время назад, я перешел на TiddlyWiki. Я давно знал об этой штуковине, но как-то все не решался полностью на нее перейти. Сомневался в надежности, и способности нормально работать с большим объемом и т.д. Но недавно я перешел на новую работу, все завертелось снова и, я полностью таки начал записи вести в TiddlyWiki.

Что это такое? Поясню кратко, для тех кто не слышал. TiddlyWiki - это Wiki движок, который представляет собой один единственный html-файл. Как это работает: вы просто открываете этот файл в браузере, и движок на JavaScript позволяет создавать записи, редактировать их, ссылать записи друг на друга, удалять и, что важно, искать Но еще этот движок умеет делать самое интересное - сохранять все, что вы ввели в этот же файл. То есть когда вы откроете этот html-файл завтра, в нем будет все, что вы ввели раньше.

Я обычно работаю так: есть закладка в браузере, которая открывает локальный файл с TiddlyWiki. А так как браузера практически всегда открыт - запуск занимает мгновения. Так как этот Wiki, то доступны все удобства Wiki-разметки и взаимных ссылок (кстати, сам сайт www.tiddlywiki.com построен на TiddlyWiki). Создание новой заметки (tiddler'а) происходит мгновенно. Для навигации можно сделать удобное меню слева, но просто пользуюсь поиском. Когда данных много - это единственный способ что-то найти.

Что лично мне нравится TiddlyWiki-подходе в целом:

  • Нужен только браузер с установленым плагином Java и малюсенький файл "Saver.jar", который поставляется вместе с TiddlyWiki, и который надо просто положить в тот же каталог. Поэтому с wiki-файлом можно работать хоть в Windows, хоть в UNIX, хоть на Маке. Я лично проверял в Chrome, Firefox и IE).
  • Файл можно выложить на web-сервер, например в интранете, и таким образом публиковать записи. Конечно, для просматривающих его через web файл будет только для чтения.
  • Так как файл по сути своей текстовый (обычный html), то в случае чего, можно выдрать из него данные простым текстовым редактором, хотя у меня такой необходимости еще не было.
  • Движок TiddlyWiki при каждом самосохранении умеет делать копию текущего состояния. Я эти файлы обычно архивирую раз в неделю, и solid-архивация в один архив позволяет хранить всю историю с минимальным увеличением архива при каждом новом сохранении. И всегда можно вернуться к определенной старой версии.
  • И главное: удобный поиск!
Небольшой трюк для пользователей Хрома. Для нормальной работы TiddlyWiki нужно, чтобы были включены cookie. По умолчанию в Хроме при работе с локальными файлами cookie выключены, поэтому Хром следует запускать с ключом --enable-file-cookies.

Не спрашивайте второй раз одно и то же. Лучше запишите ответ в первый раз, а спросите что-нибудь новое.