{"id":13340259,"url":"https://github.com/onien-12/visualnovel","last_synced_at":"2025-03-11T16:33:02.682Z","repository":{"id":37414536,"uuid":"487263537","full_name":"onien-12/visualnovel","owner":"onien-12","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-15T12:04:00.000Z","size":9061,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-24T04:28:14.865Z","etag":null,"topics":["engine","game-development","gameengine","visual-novel","visual-novel-engine","visualnovel"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onien-12.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-30T11:48:56.000Z","updated_at":"2022-12-23T10:17:44.000Z","dependencies_parsed_at":"2024-10-24T00:12:16.815Z","dependency_job_id":"7e2efa7d-7b51-4baf-9209-fc0ed47d30eb","html_url":"https://github.com/onien-12/visualnovel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onien-12%2Fvisualnovel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onien-12%2Fvisualnovel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onien-12%2Fvisualnovel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onien-12%2Fvisualnovel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onien-12","download_url":"https://codeload.github.com/onien-12/visualnovel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243070612,"owners_count":20231484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["engine","game-development","gameengine","visual-novel","visual-novel-engine","visualnovel"],"created_at":"2024-07-29T19:22:18.117Z","updated_at":"2025-03-11T16:32:57.632Z","avatar_url":"https://github.com/onien-12.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# visualnovel\nvisualnovel engine written in js\n\nFully declarative engine\n\nWith this engine you can write visualnovels using JSON!\n\nExample:\n```js\n/** \n * Scenario example\n * @tutorial scenario-example\n */\n\nimport {\n    color\n} from \"./js/utils.js\"\n\n// ┌───────────────────────────────────────────────────────────────────────┐\n// │                                                                       │\n// │ You can see media (video and sound) example in the \"scenario.js\" file │\n// │ Also, in-scene objects (text and blocks) you can find there           │\n// │                                                                       │\n// └───────────────────────────────────────────────────────────────────────┘\n\nexport let scenario = {\n    main: [ // branch name: main\n        {\n            text: \"Hello world!\", // typed text - \"Hello world!\"\n            name: \"test\", // and name - \"test\"\n            background: { // setting background: \"../images/bus.jpg\"\n                src: \"../images/bus.jpg\" // source file\n                // also, here can be transition, it should be so then\n                /*\n                transition: {\n                    name: \"opacity\", // - there's only one transition, but I will add more\n                    time: 1, // - 1 second\n                    easing: \"easeOut\" // - css transition easing. Engine uses css\n                }\n                 */\n            },\n            sprites: { // now sprites section\n                bottle: { // sprite name: bottle\n                    top: \"50%\", // position top \n                    left: \"40%\", // position left\n                    // you also can use css in position\n                    pose: \"sprite\", // default pose\n                    poses: {\n                        coke: \"../images/coke.jpeg\", // pose name is coke\n                        sprite: \"../images/sprite.jpg\" // pose name is sprite\n                        // you can add as many poses as you want\n                    },\n                    styles: { // styles for sprite. It sets at the init. of the sprite\n                        opacity: 0\n                    },\n                    transition: { // transition starts after sprite added to the scene\n                        time: 0.5, // time (seconds)\n                        easing: \"ease\", // css easing\n                        styles: { // styles to set\n                            opacity: 1\n                        }\n                    }\n                }\n            },\n            sounds: { // sounds section\n                ambience: { // sound name - ambience. You can set it to everything\n                    src: \"../sounds/forest_ambience.mp3\", // source file\n                    volume: 0.5, // start volume\n                    // loop: true, // will it loop\n                    ended: {\n                        do: {\n                            text: \"sound ended\"\n                        }\n                    }\n                }\n            }\n        },\n        {\n            text: \"test really! WORD!\", // type text\n            name: \"Семён\", // set name\n            events: { // ok, now events. \n                sprites: { // events for sprites. In this event section only sprites will be changed\n                    bottle: { // sprite name - bottle\n                        styles: { // set css styles\n                            top: \"30%\",\n                            left: \"30%\"\n                        },\n                        time: 0.5, // time (seconds)\n                        easing: \"linear\" // css easing\n                    }\n                }\n            }\n            /*\n             * we can set branches like this.\n             branch: {\n                set: \"\u003cbranchname\u003e\",\n                // and we can set cursor position (Engine#readingIndex)\n                cursor: \u003ccursorpos\u003e\n             }\n             */\n        },\n        { // if you set \"[w]\" on the start of the text, it will be added to the end of previous text\n            text: \"[w] Так.\"\n        },\n        {\n            text: \"[w] Отсюда надо { text='hello', background='red' }. { \u003cvarible name\u003e }\"\n        },\n        {\n            text: \"[w] Своими соплями ничего не добьюсь!\",\n            choises: [\n                {\n                  name: \"bad\", // just a name for choise. It will not display\n                  text: \"haha\", // text (html)\n                  active: true, // if user can choise if\n                  hidden: false, // if it visible\n                  do: { // do if chosen\n                    process: { // process (Engine#next)\n                      varibles: { // setting variblesd\n                        lp: { // varibles reading action-by-action: if first is set to 5, second is increment by 4 and third is decrement by 7, then result will be = 2 ( 5 + 4 - 7 )\n                          increment: 1, // first action\n                          multiply: 3, // 2-d\n                          divide: 2, // 3-d\n                          increment: 3, // 4-th\n                          decrement: 2 // 5-th\n                        }\n                      },\n                      branch: { // setting branch\n                        set: \"somebranch\" // setting branch\n                      }\n                    },\n                    mouseenter: { // if mouse is over choise element\n                        text: \"mouseover!\",\n                        name: \"mouseover btw\"\n                    }\n                  }\n                },\n                {\n                  name: \"good\",\n                  text: \"hezasd\",\n                  active: true,\n                  hidden: false,\n                  do: {\n                    process: {\n                      text: \"good\",\n                      name: \"good\",\n                      varibles: {\n                        lp: {\n                          increment: 35\n                        }\n                      },\n                      branch: {\n                        set: \"notexists\" // error\n                      }\n                    }\n                  }\n                }\n              ],\n              other: {\n                hideUIAtChoises: true // will text and name ui be hidden at choise\n              }\n        },\n        {\n            text: \"Привет!\", // text\n            name: \"???\", // name\n            sprites: { // sprites\n                coke: { // new sprite. Coke\n                    top: \"50%\", // position\n                    left: \"40%\", // also pos\n                    pose: \"coke\",\n                    poses: {\n                        coke: \"../images/coke.jpeg\",\n                        mar: \"../images/marat.png\"\n                    },\n                    styles: { // start styles\n                        opacity: 0 // setting start opacity\n                    },\n                    transition: { // transition \n                        time: 0.5, // time (seconds)\n                        easing: \"ease\", // css easing\n                        styles: { // and styles to set\n                            opacity: 1,\n                            top: \"40%\"\n                        }\n                    }\n                }\n            },\n            events: { // events section\n                sprites: {\n                    bottle: { // applying to the \"bottle\"\n                        styles: {\n                            opacity: 0 // before removing, setting styles. So, it will start changing opacity to 0 and remove\n                        }, //                        │\n                        remove: true, //   ←─────────┘ Remove sprite after transition. You can set time:0 and it can be instantly\n                        time: 0.5, // time\n                        easing: \"ease\" // css easing\n                    }\n                }\n            },\n            sounds: { // sounds section\n                ambience: { // we will change \"ambience\" sound\n                    // we dont need \"src\" because \"ambience\" alredy exists\n                    stop: true, // stop after transition \n                    transition: { // sound transition\n                        from: 0.9, // start volume\n                        to: 0, // end volume\n                        step: 0.01, // step\n                        time: 10 // time\n                    }\n                }\n            }, // other dialog settings\n            other: { // after every dialog change, engine clears all sprites if \"sprite\" section is exists in the dialog. \"sprites\" section describes sprites that exist\n                clearSprites: false // but we disable it by setting this thing\n            }\n        },\n        {\n            text: \"Меня Славей зовут! И ты тоже зови!\", // typed\n            name: \"Славя\", // name\n            sounds: { // sounds section\n                ambience: { // we removed \"ambience\", so we need to load it\n                    src: \"../sounds/forest_ambience.mp3\", // loading file\n                    loop: true, // loop\n                    transition: { // and start transition\n                        from: 0,\n                        to: 0.8,\n                        step: 0.01,\n                        time: 100\n                    }\n                }\n            }\n        },\n        {\n            text: \"Зову.\",\n            name: \"Семён\"\n        },\n        {\n            text: \"Пошли\",\n            name: \"Славя\",\n            next: true // dont wait next Engine#next call, just process next dialog\n        },\n        {\n            timeout: 200, // start processing this dialog after 200 ms\n            text: \"[w] туда\" // and typing after delay\n        },\n        {\n            text: \"Куда?!\",\n            name: \"Семён\",\n            events: {\n                effects: [ // effects section\n                    { // you can add as many effects as you want\n                        name: \"dim\", // what effect will be handled\n                        time: 1, // effect time\n                        easing: \"ease\", // easing \n                        timeout: 1000, // timeout before return transiiton is started\n                        styles: {}\n                    }\n                ]\n            }\n        },\n        {\n            timeout: 2000,\n            text: \"\",\n            name: \"\"\n        }\n    ],\n    somebranch: [\n        {\n            text: \"hello from new branch\"\n        }\n    ]\n}\n```\n\n\nYou can get documentation from \"out\" folder. Also, you can get it at https://onien-12.github.io/visualnovel/ \u003cbr\u003e\nTemplate scenario you can find in root directory \"scenariotemplate.js\" \u003cbr\u003e\u003cbr\u003e\n\n## Todo:\n- [X] Choises\n- [X] Varibles\n- [ ] Finish the builder\n- [X] Scenario branches\n- [ ] Conditions\n- [X] In-scene objects (like text or blocks)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonien-12%2Fvisualnovel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonien-12%2Fvisualnovel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonien-12%2Fvisualnovel/lists"}