[{"data":1,"prerenderedAt":1545},["ShallowReactive",2],{"nav-docs":3,"page-/docs/webspace/examples/realtime-gomoku":880,"surround-/docs/webspace/examples/realtime-gomoku":1539,"raw-/docs/webspace/examples/realtime-gomoku":1542},[4,56,226,546,634,773,806,863],{"title":5,"path":6,"stem":7,"children":8,"page":55},"Space Builder","/getting-started","00.getting-started",[9,13,17,23,29,33,38,42,46,50],{"title":10,"path":11,"stem":12,"children":-1},"Introducing SpaceBuilder","/getting-started/overview","00.getting-started/00.overview",{"title":14,"path":15,"stem":16,"children":-1},"Create a SetFN Account","/getting-started/create-setfn-account","00.getting-started/05.create-setfn-account",{"title":18,"path":19,"stem":20,"tags":21,"children":-1},"Installing on Linux","/getting-started/install-linux","00.getting-started/10.install-linux",[22],"recommended",{"title":24,"path":25,"stem":26,"tags":27,"children":-1},"Installing with Docker","/getting-started/install-docker","00.getting-started/12.install-docker",[28],"preparing",{"title":30,"path":31,"stem":32,"children":-1},"Installing on Windows","/getting-started/install-windows","00.getting-started/14.install-windows",{"title":34,"path":35,"stem":36,"tags":37,"children":-1},"Installing on macOS","/getting-started/install-macos","00.getting-started/16.install-macos",[28],{"title":39,"path":40,"stem":41,"children":-1},"Initial Setup","/getting-started/initial-setup","00.getting-started/20.initial-setup",{"title":43,"path":44,"stem":45,"children":-1},"License Activation","/getting-started/license-activation","00.getting-started/30.license-activation",{"title":47,"path":48,"stem":49,"children":-1},"Checking Your Access Address (Local/Internal Network)","/getting-started/access-url","00.getting-started/35.access-url",{"title":51,"path":52,"stem":53,"tags":54,"children":-1},"Choosing an External Access Method","/getting-started/access-domain","00.getting-started/40.access-domain",[22],false,{"title":57,"path":58,"stem":59,"children":60,"page":55},"Space management","/admin","10.admin",[61,74,107,136,171,184,209],{"title":62,"path":63,"stem":64,"children":65,"page":55},"Admin Home","/admin/home","10.admin/00.home",[66,70],{"title":67,"path":68,"stem":69,"children":-1},"Accessing the Admin Page","/admin/home/admin-page-access","10.admin/00.home/00.admin-page-access",{"title":71,"path":72,"stem":73,"children":-1},"License Management","/admin/home/license","10.admin/00.home/20.license",{"title":75,"path":76,"stem":77,"children":78,"page":55},"User management","/admin/user-management","10.admin/10.user-management",[79,83,87,91,95,99,103],{"title":80,"path":81,"stem":82,"children":-1},"Setting Signup Policy and Default Permissions","/admin/user-management/signup-policy","10.admin/10.user-management/02.signup-policy",{"title":84,"path":85,"stem":86,"children":-1},"Creating a User Account","/admin/user-management/invite-new-member","10.admin/10.user-management/10.invite-new-member",{"title":88,"path":89,"stem":90,"children":-1},"Editing a User Account","/admin/user-management/edit-member","10.admin/10.user-management/11.edit-member",{"title":92,"path":93,"stem":94,"children":-1},"Adding an Admin","/admin/user-management/add-new-admin","10.admin/10.user-management/12.add-new-admin",{"title":96,"path":97,"stem":98,"children":-1},"Team Management","/admin/user-management/team","10.admin/10.user-management/22.team",{"title":100,"path":101,"stem":102,"children":-1},"Level Management","/admin/user-management/level","10.admin/10.user-management/24.level",{"title":104,"path":105,"stem":106,"children":-1},"Checking Access Logs","/admin/user-management/access-log","10.admin/10.user-management/30.access-log",{"title":108,"path":109,"stem":110,"children":111,"page":55},"Service Configuration","/admin/service-config","10.admin/20.service-config",[112,116,120,124,128,132],{"title":113,"path":114,"stem":115,"children":-1},"File Area Settings","/admin/service-config/file-area","10.admin/20.service-config/10.file-area",{"title":117,"path":118,"stem":119,"children":-1},"Webhook Settings","/admin/service-config/webhook-settings","10.admin/20.service-config/16.webhook-settings",{"title":121,"path":122,"stem":123,"children":-1},"Community Settings","/admin/service-config/community-space","10.admin/20.service-config/22.community-space",{"title":125,"path":126,"stem":127,"children":-1},"AI Chatbot Policy Settings","/admin/service-config/community-ai-chatbot","10.admin/20.service-config/24.community-ai-chatbot",{"title":129,"path":130,"stem":131,"children":-1},"Email Settings","/admin/service-config/email-settings","10.admin/20.service-config/30.email-settings",{"title":133,"path":134,"stem":135,"children":-1},"Branding Settings","/admin/service-config/brand","10.admin/20.service-config/40.brand",{"title":137,"path":138,"stem":139,"children":140,"page":55},"Intelligent Service (AI)","/admin/ai","10.admin/30.ai",[141,145,149,153,159,163,167],{"title":142,"path":143,"stem":144,"children":-1},"AI Model Settings","/admin/ai/ai-model-setting","10.admin/30.ai/10.ai-model-setting",{"title":146,"path":147,"stem":148,"children":-1},"AI DB Settings","/admin/ai/ai-db-setting","10.admin/30.ai/20.ai-db-setting",{"title":150,"path":151,"stem":152,"children":-1},"Setting Up a Qdrant Server","/admin/ai/qdrant-server-setup","10.admin/30.ai/25.qdrant-server-setup",{"title":154,"path":155,"stem":156,"children":157},"Knowledge Indexing","/admin/ai/knowledge-indexing","10.admin/30.ai/30.knowledge-indexing",[158],{"title":154,"path":155,"stem":156,"children":-1},{"title":160,"path":161,"stem":162,"children":-1},"AI Integration and Policy Settings","/admin/ai/ai-link","10.admin/30.ai/40.ai-link",{"title":164,"path":165,"stem":166,"children":-1},"MCP Server Management","/admin/ai/mcp-server","10.admin/30.ai/50.mcp-server",{"title":168,"path":169,"stem":170,"children":-1},"Search Management","/admin/ai/search-management","10.admin/30.ai/60.search-management",{"title":172,"path":173,"stem":174,"children":175,"page":55},"plugin","/admin/plugin","10.admin/40.plugin",[176,180],{"title":177,"path":178,"stem":179,"children":-1},"Managing Plugins","/admin/plugin/overview","10.admin/40.plugin/00.overview",{"title":181,"path":182,"stem":183,"children":-1},"Extension Plugin Settings","/admin/plugin/settings","10.admin/40.plugin/10.settings",{"title":185,"path":186,"stem":187,"children":188,"page":55},"Security Management","/admin/security","10.admin/50.security",[189,193,197,201,205],{"title":190,"path":191,"stem":192,"children":-1},"Security Overview","/admin/security/overview","10.admin/50.security/00.overview",{"title":194,"path":195,"stem":196,"children":-1},"Checking the Audit Log","/admin/security/audit-log","10.admin/50.security/05.audit-log",{"title":198,"path":199,"stem":200,"children":-1},"Block Management","/admin/security/block-management","10.admin/50.security/10.block-management",{"title":202,"path":203,"stem":204,"children":-1},"Security Settings","/admin/security/security-setting","10.admin/50.security/12.security-setting",{"title":206,"path":207,"stem":208,"children":-1},"IP Access Restriction","/admin/security/ip-restriction","10.admin/50.security/16.ip-restriction",{"title":210,"path":211,"stem":212,"children":213,"page":55},"System management","/admin/system-admin","10.admin/60.system-admin",[214,218,222],{"title":215,"path":216,"stem":217,"children":-1},"Device Information","/admin/system-admin/device-info","10.admin/60.system-admin/10.device-info",{"title":219,"path":220,"stem":221,"children":-1},"Server Restart and System Maintenance","/admin/system-admin/server-restart","10.admin/60.system-admin/12.server-restart",{"title":223,"path":224,"stem":225,"children":-1},"Background Services","/admin/system-admin/background-service","10.admin/60.system-admin/14.background-service",{"title":227,"path":228,"stem":229,"children":230,"page":55},"Use workspace","/workspace","20.workspace",[231,264,281,337,448,495,527],{"title":232,"path":233,"stem":234,"children":235,"page":55},"menu","/workspace/menu","20.workspace/05.menu",[236,240,244,248,252,256,260],{"title":237,"path":238,"stem":239,"children":-1},"Workspace Overview","/workspace/menu/overview","20.workspace/05.menu/00.overview",{"title":241,"path":242,"stem":243,"children":-1},"Team Space","/workspace/menu/team-space","20.workspace/05.menu/05.team-space",{"title":245,"path":246,"stem":247,"children":-1},"Client Space","/workspace/menu/client-space","20.workspace/05.menu/06.client-space",{"title":249,"path":250,"stem":251,"children":-1},"Favorites","/workspace/menu/favorites","20.workspace/05.menu/10.favorites",{"title":253,"path":254,"stem":255,"children":-1},"Recent Documents","/workspace/menu/recent","20.workspace/05.menu/20.recent",{"title":257,"path":258,"stem":259,"children":-1},"External Share","/workspace/menu/external-share","20.workspace/05.menu/30.external-share",{"title":261,"path":262,"stem":263,"children":-1},"Trash","/workspace/menu/trash","20.workspace/05.menu/40.trash",{"title":265,"path":266,"stem":267,"children":268,"page":55},"Account","/workspace/account","20.workspace/10.account",[269,273,277],{"title":270,"path":271,"stem":272,"children":-1},"Sign Up and Log In","/workspace/account/signup","20.workspace/10.account/10.signup",{"title":274,"path":275,"stem":276,"children":-1},"Resetting Your Password","/workspace/account/reset-password","20.workspace/10.account/20.reset-password",{"title":278,"path":279,"stem":280,"children":-1},"Account Settings","/workspace/account/account-settings","20.workspace/10.account/30.account-settings",{"title":282,"path":283,"stem":284,"children":285,"page":55},"folder","/workspace/folder","20.workspace/20.folder",[286,290,294,298,302,308,312,316,321,325,329,333],{"title":287,"path":288,"stem":289,"children":-1},"Folder Basics","/workspace/folder/basic","20.workspace/20.folder/10.basic",{"title":291,"path":292,"stem":293,"children":-1},"Creating Multiple Folders at Once","/workspace/folder/bulk-folder-creation","20.workspace/20.folder/12.bulk-folder-creation",{"title":295,"path":296,"stem":297,"children":-1},"Filter","/workspace/folder/filter","20.workspace/20.folder/13.filter",{"title":299,"path":300,"stem":301,"children":-1},"Configuring Folder View Options","/workspace/folder/folder-view-options","20.workspace/20.folder/14.folder-view-options",{"title":303,"path":304,"stem":305,"tags":306,"children":-1},"Folder Web View","/workspace/folder/folder-web-view","20.workspace/20.folder/16.folder-web-view",[307],"hot",{"title":309,"path":310,"stem":311,"children":-1},"Folder Organization","/workspace/folder/folder-organize","20.workspace/20.folder/17.folder-organize",{"title":313,"path":314,"stem":315,"children":-1},"Folder Notice (README)","/workspace/folder/folder-readme","20.workspace/20.folder/18.folder-readme",{"title":317,"path":318,"stem":319,"tags":320,"children":-1},"Exporting Folder/File Lists","/workspace/folder/folder-export","20.workspace/20.folder/20.folder-export",[307],{"title":322,"path":323,"stem":324,"children":-1},"Setting Level-Based Access Permissions","/workspace/folder/level-access-permissions","20.workspace/20.folder/24.level-access-permissions",{"title":326,"path":327,"stem":328,"children":-1},"Setting Team-Based Access Permissions","/workspace/folder/team-access-permissions","20.workspace/20.folder/26.team-access-permissions",{"title":330,"path":331,"stem":332,"children":-1},"Folder Webhooks","/workspace/folder/webhook","20.workspace/20.folder/30.webhook",{"title":334,"path":335,"stem":336,"children":-1},"Work Automation Folder","/workspace/folder/automation","20.workspace/20.folder/40.automation",{"title":338,"path":339,"stem":340,"children":341,"page":55},"file","/workspace/file","20.workspace/30.file",[342,346,351,355,359,363,367,371,375,379,384,388,392,396,400,404,408,412,416,420,424,428,432,436,440,444],{"title":343,"path":344,"stem":345,"children":-1},"File Management Basics","/workspace/file/overview","20.workspace/30.file/00.overview",{"title":347,"path":348,"stem":349,"tags":350,"children":-1},"Checking the List While Viewing a File","/workspace/file/list-in-file","20.workspace/30.file/05.list-in-file",[307],{"title":352,"path":353,"stem":354,"children":-1},"Register disk files","/workspace/file/disk-file-registration","20.workspace/30.file/06.disk-file-registration",{"title":356,"path":357,"stem":358,"children":-1},"Viewing and Editing Text Files","/workspace/file/text-file-viewer","20.workspace/30.file/10.text-file-viewer",{"title":360,"path":361,"stem":362,"children":-1},"Viewing HTML Files","/workspace/file/html-viewer","20.workspace/30.file/11.html-viewer",{"title":364,"path":365,"stem":366,"children":-1},"Viewing and Editing CSV Files","/workspace/file/csv-viewer","20.workspace/30.file/12.csv-viewer",{"title":368,"path":369,"stem":370,"children":-1},"Viewing Image/Video Files","/workspace/file/image-file-viewer","20.workspace/30.file/13.image-file-viewer",{"title":372,"path":373,"stem":374,"children":-1},"Viewing Office/PDF Files","/workspace/file/office-viewer","20.workspace/30.file/14.office-viewer",{"title":376,"path":377,"stem":378,"children":-1},"Pasting Web Pages (HTML)","/workspace/file/paste-html","20.workspace/30.file/20.paste-html",{"title":380,"path":381,"stem":382,"tags":383,"children":-1},"Pasting Screenshots","/workspace/file/paste-screenshot","20.workspace/30.file/21.paste-screenshot",[307],{"title":385,"path":386,"stem":387,"children":-1},"Pasting Markdown (MD)","/workspace/file/paste-md","20.workspace/30.file/22.paste-md",{"title":389,"path":390,"stem":391,"children":-1},"Screen Recording","/workspace/file/screen-recording","20.workspace/30.file/23.screen-recording",{"title":393,"path":394,"stem":395,"children":-1},"File Tags","/workspace/file/file-tag","20.workspace/30.file/33.file-tag",{"title":397,"path":398,"stem":399,"children":-1},"Bulk Renaming Files","/workspace/file/bulk-name-revise","20.workspace/30.file/34.bulk-name-revise",{"title":401,"path":402,"stem":403,"children":-1},"File Conversion","/workspace/file/file-convert-overview","20.workspace/30.file/40.file-convert-overview",{"title":405,"path":406,"stem":407,"children":-1},"Template Files","/workspace/file/templates","20.workspace/30.file/41.templates",{"title":409,"path":410,"stem":411,"children":-1},"To-Do List","/workspace/file/template-todo","20.workspace/30.file/42.template-todo",{"title":413,"path":414,"stem":415,"children":-1},"Approval Form","/workspace/file/template-approval","20.workspace/30.file/43.template-approval",{"title":417,"path":418,"stem":419,"children":-1},"Kanban Board","/workspace/file/template-kanban","20.workspace/30.file/44.template-kanban",{"title":421,"path":422,"stem":423,"children":-1},"Timeline","/workspace/file/template-timeline","20.workspace/30.file/45.template-timeline",{"title":425,"path":426,"stem":427,"children":-1},"Memo","/workspace/file/template-memo","20.workspace/30.file/46.template-memo",{"title":429,"path":430,"stem":431,"children":-1},"AI Chat File","/workspace/file/ai-chat-file","20.workspace/30.file/47.ai-chat-file",{"title":433,"path":434,"stem":435,"children":-1},"Checking the File Change History","/workspace/file/audit-trail","20.workspace/30.file/50.audit-trail",{"title":437,"path":438,"stem":439,"children":-1},"File Version Control","/workspace/file/version-trail","20.workspace/30.file/51.version-trail",{"title":441,"path":442,"stem":443,"children":-1},"Edit Lock","/workspace/file/file-lock","20.workspace/30.file/52.file-lock",{"title":445,"path":446,"stem":447,"children":-1},"File Encryption","/workspace/file/file-encrypt","20.workspace/30.file/53.file-encrypt",{"title":449,"path":450,"stem":451,"children":452,"page":55},"Collaboration","/workspace/cooperation","20.workspace/35.cooperation",[453,457,461,465,470,474,478,482,487,491],{"title":454,"path":455,"stem":456,"children":-1},"File/Folder Comments","/workspace/cooperation/file-comments","20.workspace/35.cooperation/00.file-comments",{"title":458,"path":459,"stem":460,"children":-1},"Chat","/workspace/cooperation/chat","20.workspace/35.cooperation/10.chat",{"title":462,"path":463,"stem":464,"children":-1},"Collaboration Chat and Edit Lock","/workspace/cooperation/collaboration-chat","20.workspace/35.cooperation/11.collaboration-chat",{"title":466,"path":467,"stem":468,"tags":469,"children":-1},"Following a Team Member's Location","/workspace/cooperation/follow-team-location","20.workspace/35.cooperation/12.follow-team-location",[307],{"title":471,"path":472,"stem":473,"children":-1},"Mentions","/workspace/cooperation/mention","20.workspace/35.cooperation/14.mention",{"title":475,"path":476,"stem":477,"children":-1},"Direct Messages","/workspace/cooperation/dm","20.workspace/35.cooperation/16.dm",{"title":479,"path":480,"stem":481,"children":-1},"Notification Inbox","/workspace/cooperation/notification-inbox","20.workspace/35.cooperation/18.notification-inbox",{"title":483,"path":484,"stem":485,"tags":486,"children":-1},"Checking Team Activity","/workspace/cooperation/file-activity","20.workspace/35.cooperation/30.file-activity",[307],{"title":488,"path":489,"stem":490,"children":-1},"Creating an External Share Link","/workspace/cooperation/share-link-creation","20.workspace/35.cooperation/40.share-link-creation",{"title":492,"path":493,"stem":494,"children":-1},"Sending an External Share Link by Email","/workspace/cooperation/share-link-email","20.workspace/35.cooperation/42.share-link-email",{"title":496,"path":497,"stem":498,"children":499,"page":55},"Search","/workspace/search","20.workspace/40.search",[500,504,509,515,519,523],{"title":501,"path":502,"stem":503,"children":-1},"File Search","/workspace/search/search","20.workspace/40.search/00.search",{"title":505,"path":506,"stem":507,"tags":508,"children":-1},"Context Search (AI Search)","/workspace/search/context-search","20.workspace/40.search/10.context-search",[307],{"title":510,"path":511,"stem":512,"tags":513,"children":-1},"Image Search","/workspace/search/image-search","20.workspace/40.search/20.image-search",[514],"new",{"title":516,"path":517,"stem":518,"children":-1},"Chat Search","/workspace/search/chat-search","20.workspace/40.search/30.chat-search",{"title":520,"path":521,"stem":522,"children":-1},"Comment Search","/workspace/search/comment-search","20.workspace/40.search/40.comment-search",{"title":524,"path":525,"stem":526,"children":-1},"Synonym Search","/workspace/search/synonym-search","20.workspace/40.search/50.synonym-search",{"title":528,"path":529,"stem":530,"children":531,"page":55},"AI","/workspace/ai","20.workspace/50.ai",[532,536,541],{"title":533,"path":534,"stem":535,"children":-1},"AI Features Summary","/workspace/ai/overview","20.workspace/50.ai/00.overview",{"title":537,"path":538,"stem":539,"tags":540,"children":-1},"Requesting Work from the Local AI","/workspace/ai/ai-work","20.workspace/50.ai/10.ai-work",[307],{"title":542,"path":543,"stem":544,"tags":545,"children":-1},"Using External AI","/workspace/ai/external-ai","20.workspace/50.ai/20.external-ai",[514],{"title":547,"path":548,"stem":549,"children":550,"page":55},"Webspace","/webspace","40.webspace",[551,555,559,563,567,571,576,580,584,588,592,621],{"title":552,"path":553,"stem":554,"children":-1},"What is WebSpace?","/webspace/overview","40.webspace/00.overview",{"title":556,"path":557,"stem":558,"children":-1},"Deploying a Website","/webspace/website-release","40.webspace/10.website-release",{"title":560,"path":561,"stem":562,"children":-1},"Create a schema file (.sfn)","/webspace/create-database","40.webspace/20.create-database",{"title":564,"path":565,"stem":566,"children":-1},"Build APIs and deploy a database","/webspace/api-overview","40.webspace/24.api-overview",{"title":568,"path":569,"stem":570,"children":-1},"Checking the Frontend Sample","/webspace/frontend-example","40.webspace/26.frontend-example",{"title":572,"path":573,"stem":574,"tags":575,"children":-1},"Building an Internal Team Web Service","/webspace/internal-webservice","40.webspace/32.internal-webservice",[307],{"title":577,"path":578,"stem":579,"children":-1},"Building a Publicly Accessible Web Service","/webspace/external-webservice","40.webspace/34.external-webservice",{"title":581,"path":582,"stem":583,"children":-1},"Import and export SQL","/webspace/sql-converter","40.webspace/42.sql-converter",{"title":585,"path":586,"stem":587,"children":-1},"Developer Tip 2: Code Converter","/webspace/code-converter","40.webspace/44.code-converter",{"title":589,"path":590,"stem":591,"children":-1},"Performance and scaling","/webspace/performance","40.webspace/48.performance",{"title":593,"path":594,"stem":595,"children":596,"page":55},"Webspace Management","/webspace/admin","40.webspace/50.admin",[597,601,605,609,613,617],{"title":598,"path":599,"stem":600,"children":-1},"Get started with WebSpace administration","/webspace/admin/overview","40.webspace/50.admin/00.overview",{"title":602,"path":603,"stem":604,"children":-1},"Operations","/webspace/admin/operations","40.webspace/50.admin/10.operations",{"title":606,"path":607,"stem":608,"children":-1},"Workspace access","/webspace/admin/workspace-access","40.webspace/50.admin/20.workspace-access",{"title":610,"path":611,"stem":612,"children":-1},"API & site security","/webspace/admin/api-site-security","40.webspace/50.admin/30.api-site-security",{"title":614,"path":615,"stem":616,"children":-1},"Services and capacity","/webspace/admin/service-capacity","40.webspace/50.admin/40.service-capacity",{"title":618,"path":619,"stem":620,"children":-1},"Deployment management and frontend releases","/webspace/admin/deployments","40.webspace/50.admin/50.deployments",{"title":622,"path":623,"stem":624,"children":625,"page":55},"Try WebSpace","/webspace/examples","40.webspace/60.examples",[626,630],{"title":627,"path":628,"stem":629,"children":-1},"WebSpace examples","/webspace/examples/overview","40.webspace/60.examples/00.overview",{"title":631,"path":632,"stem":633,"children":-1},"Build a real-time Gomoku game","/webspace/examples/realtime-gomoku","40.webspace/60.examples/20.realtime-gomoku",{"title":635,"path":636,"stem":637,"children":638,"page":55},"Using plugin","/plugin","50.plugin",[639,643,660,704,722,752],{"title":640,"path":641,"stem":642,"children":-1},"Plugin Overview","/plugin/overview","50.plugin/00.overview",{"title":644,"path":645,"stem":646,"children":647,"page":55},"Calendar","/plugin/calendar","50.plugin/10.calendar",[648,652,656],{"title":649,"path":650,"stem":651,"children":-1},"Calendar Introduction","/plugin/calendar/overview","50.plugin/10.calendar/00.overview",{"title":653,"path":654,"stem":655,"children":-1},"Creating, Editing, and Deleting Events","/plugin/calendar/create-event","50.plugin/10.calendar/10.create-event",{"title":657,"path":658,"stem":659,"children":-1},"Checking Activity History","/plugin/calendar/file-activity","50.plugin/10.calendar/40.file-activity",{"title":661,"path":662,"stem":663,"children":664,"page":55},"Email","/plugin/email","50.plugin/20.email",[665,669,672,676,680,684,688,692,696,700],{"title":666,"path":667,"stem":668,"children":-1},"Email Introduction","/plugin/email/overview","50.plugin/20.email/00.overview",{"title":129,"path":670,"stem":671,"children":-1},"/plugin/email/setfn-email-setting","50.plugin/20.email/05.setfn-email-setting",{"title":673,"path":674,"stem":675,"children":-1},"Connect an External Email Account","/plugin/email/external-email","50.plugin/20.email/07.external-email",{"title":677,"path":678,"stem":679,"children":-1},"Basic Email Functionality","/plugin/email/email-basic","50.plugin/20.email/10.email-basic",{"title":681,"path":682,"stem":683,"children":-1},"Composing and Sending Email","/plugin/email/email-compose","50.plugin/20.email/20.email-compose",{"title":685,"path":686,"stem":687,"children":-1},"Attaching Files","/plugin/email/email-attachment","50.plugin/20.email/30.email-attachment",{"title":689,"path":690,"stem":691,"children":-1},"Mail Folder Management","/plugin/email/email-folders","50.plugin/20.email/40.email-folders",{"title":693,"path":694,"stem":695,"children":-1},"Automatic Email Classification","/plugin/email/email-auto-classify","50.plugin/20.email/50.email-auto-classify",{"title":697,"path":698,"stem":699,"children":-1},"Email File Archiving and Sharing","/plugin/email/email-open-in-space","50.plugin/20.email/60.email-open-in-space",{"title":701,"path":702,"stem":703,"children":-1},"Email Security","/plugin/email/email-security","50.plugin/20.email/70.email-security",{"title":705,"path":706,"stem":707,"children":708,"page":55},"Workflow","/plugin/workflow","50.plugin/30.workflow",[709,713,718],{"title":710,"path":711,"stem":712,"children":-1},"Workflow Introduction","/plugin/workflow/overview","50.plugin/30.workflow/00.overview",{"title":714,"path":715,"stem":716,"tags":717,"children":-1},"Creating a New Workflow","/plugin/workflow/new-workflow","50.plugin/30.workflow/10.new-workflow",[307],{"title":719,"path":720,"stem":721,"children":-1},"Checking Execution History","/plugin/workflow/execution-history","50.plugin/30.workflow/20.execution-history",{"title":723,"path":724,"stem":725,"children":726,"page":55},"Pinetuning (AI learning)","/plugin/fine-tuning","50.plugin/40.fine-tuning",[727,732,736,740,744,748],{"title":728,"path":729,"stem":730,"tags":731,"children":-1},"Fine-tuning Introduction","/plugin/fine-tuning/overview","50.plugin/40.fine-tuning/00.overview",[307],{"title":733,"path":734,"stem":735,"children":-1},"Preprocessing Training Data","/plugin/fine-tuning/pre-processing","50.plugin/40.fine-tuning/10.pre-processing",{"title":737,"path":738,"stem":739,"children":-1},"Training","/plugin/fine-tuning/training","50.plugin/40.fine-tuning/20.training",{"title":741,"path":742,"stem":743,"children":-1},"Evaluation","/plugin/fine-tuning/evaluation","50.plugin/40.fine-tuning/30.evaluation",{"title":745,"path":746,"stem":747,"children":-1},"Chat Test","/plugin/fine-tuning/chat-test","50.plugin/40.fine-tuning/40.chat-test",{"title":749,"path":750,"stem":751,"children":-1},"Export","/plugin/fine-tuning/export","50.plugin/40.fine-tuning/50.export",{"title":753,"path":754,"stem":755,"children":756,"page":55},"EDC (data collection)","/plugin/edc","50.plugin/50.edc",[757,761,765,769],{"title":758,"path":759,"stem":760,"children":-1},"EDC Introduction","/plugin/edc/overview","50.plugin/50.edc/00.overview",{"title":762,"path":763,"stem":764,"children":-1},"Data Entry, Audit Trail","/plugin/edc/data-entry","50.plugin/50.edc/10.data-entry",{"title":766,"path":767,"stem":768,"children":-1},"Builder","/plugin/edc/builder","50.plugin/50.edc/20.builder",{"title":770,"path":771,"stem":772,"children":-1},"User/Site Settings","/plugin/edc/account","50.plugin/50.edc/30.account",{"title":774,"path":775,"stem":776,"children":777,"page":55},"FAQ","/faq","99.FAQ",[778,782,786,790,794,798,802],{"title":779,"path":780,"stem":781,"children":-1},"SetFN vs Cloud Services Comparison","/faq/comparison-cloud","99.FAQ/10.comparison-cloud",{"title":783,"path":784,"stem":785,"children":-1},"SetFN vs NAS Comparison","/faq/comparison-nas","99.FAQ/20.comparison-nas",{"title":787,"path":788,"stem":789,"children":-1},"Security Policy","/faq/security-policy","99.FAQ/30.security-policy",{"title":791,"path":792,"stem":793,"children":-1},"Why Is SetFN Fast","/faq/why-fast","99.FAQ/40.why-fast",{"title":795,"path":796,"stem":797,"children":-1},"License FAQ","/faq/license-faq","99.FAQ/50.license-faq",{"title":799,"path":800,"stem":801,"children":-1},"AI Features FAQ","/faq/ai-faq","99.FAQ/60.ai-faq",{"title":803,"path":804,"stem":805,"children":-1},"Troubleshooting Guide","/faq/troubleshooting","99.FAQ/70.troubleshooting",{"title":807,"path":808,"stem":809,"children":810,"page":55},"Applied (draft)","/draft","draft",[811,815,819,823,827,831,835,839,843,847,851,855,859],{"title":812,"path":813,"stem":814,"children":-1},"Example 1. Building an Introduction Page","/draft/static-intro","draft/05.static-intro",{"title":816,"path":817,"stem":818,"children":-1},"Example 2. Building a Notice Board","/draft/public-notice-board","draft/07.public-notice-board",{"title":820,"path":821,"stem":822,"children":-1},"Example 3. Building a Coffee Chat Booking System","/draft/coffee-chat-booking","draft/08.coffee-chat-booking",{"title":824,"path":825,"stem":826,"children":-1},"Example 4. Building a Leave Request System","/draft/leave-request","draft/09.leave-request",{"title":828,"path":829,"stem":830,"children":-1},"Example 5. Building Real-Time Team Chat","/draft/team-chat","draft/10.team-chat",{"title":832,"path":833,"stem":834,"children":-1},"Example 6. Building a Job Application Intake","/draft/client-submission","draft/11.client-submission",{"title":836,"path":837,"stem":838,"children":-1},"Example 7. Building an Issue Tracker with Team and Level Conditions","/draft/crm-basic","draft/12.crm-basic",{"title":840,"path":841,"stem":842,"children":-1},"Example 8. Building a Status Filter and Stats Summary Screen","/draft/crm-search-filter","draft/13.crm-search-filter",{"title":844,"path":845,"stem":846,"children":-1},"Example 9. Building Real-Time Community Chat with Moderation","/draft/community-moderation","draft/14.community-moderation",{"title":848,"path":849,"stem":850,"children":-1},"Example 10. Building a Real-Time Attendance Check / Poll","/draft/attendance-poll","draft/15.attendance-poll",{"title":852,"path":853,"stem":854,"children":-1},"Example 11. Building a Debate Battle","/draft/debate-battle","draft/16.debate-battle",{"title":856,"path":857,"stem":858,"children":-1},"Example 13. Building an Announcement Read Receipt","/draft/announcement-read","draft/18.announcement-read",{"title":860,"path":861,"stem":862,"children":-1},"Example 14. Building an Inventory Management System","/draft/inventory-management","draft/19.inventory-management",{"title":864,"path":865,"stem":866,"children":867,"page":55},"SJAUTO","/sjauto","sjauto",[868,872,876],{"title":869,"path":870,"stem":871,"children":-1},"Access the Administrator Page","/sjauto/admin-page-access","sjauto/00.admin-page-access",{"title":873,"path":874,"stem":875,"children":-1},"Sign Up and Sign In","/sjauto/signup","sjauto/10.signup",{"title":877,"path":878,"stem":879,"children":-1},"AI Chat Files","/sjauto/ai-chat-file","sjauto/ai-chat-file",{"id":881,"title":631,"body":882,"cover":1519,"description":1520,"extension":1521,"image":1519,"meta":1522,"navigation":1524,"path":632,"seo":1525,"stem":633,"tags":1519,"thumbnail":1519,"__hash__":1538},"docs_en/40.webspace/60.examples/20.realtime-gomoku.md",{"type":883,"value":884,"toc":1503},"minimal",[885,889,893,896,903,906,911,919,950,953,970,973,977,1044,1047,1051,1054,1064,1071,1115,1118,1122,1129,1159,1162,1166,1173,1180,1186,1193,1197,1208,1218,1231,1235,1265,1268,1274,1278,1281,1287,1294,1298,1303,1399,1402,1405,1409,1474,1478,1481,1485],[886,887,631],"h1",{"id":888},"build-a-real-time-gomoku-game",[890,891,892],"p",{},"Upload the files, deploy the schema, and open two browsers. A friend can join the room created in one browser, and every move appears immediately in the other. The server records results and rankings.",[890,894,895],{},"No separate frontend build tool is required. Play one match with the completed sample first, then modify the data structure, real-time behavior, and game rules.",[890,897,898],{},[899,900],"img",{"alt":901,"src":902},"19×19 board, live match feed, and player rankings","/img/docs/webspace/gomoku/realtime-gomoku-board.png",[904,905],"hr",{},[907,908,910],"h2",{"id":909},"_1-play-a-match-first","1. Play a match first",[890,912,913,914,918],{},"The fastest way to begin is with the ",[915,916,917],"strong",{},"complete sample ZIP",". Upload the schema and interface files to the same folder and deploy the schema.",[920,921,922,943],"ul",{},[923,924,925,930,931,935,936,935,939,942],"li",{},[926,927,929],"a",{"href":928},"/examples/webspace/gomoku/setfn-realtime-gomoku-sample.zip","Download the complete real-time Gomoku sample ZIP",": Includes the schema, ",[932,933,934],"code",{},"index.html",", ",[932,937,938],{},"style.css",[932,940,941],{},"app.js",", and README",[923,944,945,949],{},[926,946,948],{"href":947},"/examples/webspace/gomoku/gomoku-realtime.sfn","Download the Gomoku schema file (.sfn)",": Use it to inspect only the backend or connect your own interface",[890,951,952],{},"The sample demonstrates:",[920,954,955,958,961,964,967],{},[923,956,957],{},"A two-user match using a room code",[923,959,960],{},"The last move, your stones, and the current turn",[923,962,963],{},"A three-minute limit that restarts after each move",[923,965,966],{},"A live match feed",[923,968,969],{},"Automatic result, recent-match, and ranking updates",[890,971,972],{},"The schema includes a 19×19 board, five-in-a-row victory, and scores of 3 for a win, 1 for a draw, and 0 for a loss. Each user can create up to three waiting rooms. A room with no participant for 30 minutes becomes eligible for cleanup.",[907,974,976],{"id":975},"features-used-in-the-game","Features used in the game",[978,979,980,993],"table",{},[981,982,983],"thead",{},[984,985,986,990],"tr",{},[987,988,989],"th",{},"Feature",[987,991,992],{},"Role in Gomoku",[994,995,996,1005,1013,1021,1029,1037],"tbody",{},[984,997,998,1002],{},[999,1000,1001],"td",{},"Schema file",[999,1003,1004],{},"Defines matches, moves, and player records",[984,1006,1007,1010],{},[999,1008,1009],{},"REST API",[999,1011,1012],{},"Retrieves recent matches and player rankings",[984,1014,1015,1018],{},[999,1016,1017],{},"WebSocket",[999,1019,1020],{},"Delivers room creation, joining, and move results in real time",[984,1022,1023,1026],{},[999,1024,1025],{},"Event handler",[999,1027,1028],{},"Evaluates turns, coordinates, victory, and time limits on the server",[984,1030,1031,1034],{},[999,1032,1033],{},"Member permissions",[999,1035,1036],{},"Allows only signed-in users to participate",[984,1038,1039,1041],{},[999,1040,449],{},[999,1042,1043],{},"Lets participants chat on the same screen",[890,1045,1046],{},"The browser does not declare victory or write scores directly. The server validates the board and turn, saves only valid moves, and sends the same result to both users.",[907,1048,1050],{"id":1049},"_2-upload-the-files-to-a-workspace","2. Upload the files to a workspace",[890,1052,1053],{},"Upload the schema to a project folder in a team or personal workspace. If you downloaded the ZIP, put all five files in one folder by using folder upload or archive upload.",[1055,1056,1062],"pre",{"className":1057,"code":1059,"language":1060,"meta":1061},[1058],"language-text","gomoku-room/\n├── gomoku-realtime.sfn\n├── index.html\n├── style.css\n├── app.js\n└── README.md\n","text","",[932,1063,1059],{"__ignoreMap":1061},[890,1065,1066,1067,1070],{},"Open the schema file and check the three tables under ",[932,1068,1069],{},"DB Structure",".",[978,1072,1073,1083],{},[981,1074,1075],{},[984,1076,1077,1080],{},[987,1078,1079],{},"Table",[987,1081,1082],{},"Stored data",[994,1084,1085,1095,1105],{},[984,1086,1087,1092],{},[999,1088,1089],{},[932,1090,1091],{},"gomoku_games",[999,1093,1094],{},"Room code, participants, current turn, time limit, and final result",[984,1096,1097,1102],{},[999,1098,1099],{},[932,1100,1101],{},"gomoku_moves",[999,1103,1104],{},"Move number, stone color, coordinates, and user",[984,1106,1107,1112],{},[999,1108,1109],{},[932,1110,1111],{},"gomoku_players",[999,1113,1114],{},"Wins, losses, draws, cumulative score, and recent games by user",[890,1116,1117],{},"Matches and player records are stored separately, so recent history and rankings can be loaded again after reopening the page.",[907,1119,1121],{"id":1120},"_3-check-the-api-and-real-time-features","3. Check the API and real-time features",[890,1123,1124,1125,1128],{},"Open ",[932,1126,1127],{},"API Build"," at the top and verify the following:",[1130,1131,1132,1138,1144,1150,1156],"ol",{},[923,1133,1134,1135,1070],{},"The database name is ",[932,1136,1137],{},"gomoku",[923,1139,1140,1141,1070],{},"Real-time sockets are enabled under ",[932,1142,1143],{},"Feature connections",[923,1145,1146,1147,1070],{},"The event handler is ",[932,1148,1149],{},"turn-based-board",[923,1151,1152,1153,1070],{},"Real-time send and receive permissions are set to ",[932,1154,1155],{},"Member",[923,1157,1158],{},"Create and update APIs are disabled for all three tables.",[890,1160,1161],{},"Disabling create and update APIs prevents participants from changing win counts or moves through REST. Every game state change must pass through the server event handler.",[907,1163,1165],{"id":1164},"_4-deploy-with-sqlite3","4. Deploy with SQLite3",[890,1167,1168,1169,1172],{},"For the first run, select SQLite3 under ",[932,1170,1171],{},"Storage",". It requires no separate database address or account.",[890,1174,1175,1176,1179],{},"Before selecting ",[932,1177,1178],{},"Deploy",", review the displayed changes and permission summary. If a database with the same name already contains records, an administrator or deployment operator may need to approve the operation according to the server overwrite policy.",[1055,1181,1184],{"className":1182,"code":1183,"language":1060,"meta":1061},[1058],"GET /api/web/gomoku/gomoku_games/list\nGET /api/web/gomoku/gomoku_players/list\nWS  /api/web/gomoku/realtime-ws\n",[932,1185,1183],{"__ignoreMap":1061},[890,1187,1188,1189,1192],{},"For an HTTPS production server, the browser must use a secure ",[932,1190,1191],{},"wss://"," connection on the same domain. Build the address from the current page host instead of hard-coding a development domain.",[907,1194,1196],{"id":1195},"_5-open-the-gomoku-interface","5. Open the Gomoku interface",[890,1198,1199,1200,935,1202,1204,1205,1207],{},"The schema creates the game database and backend. ",[932,1201,934],{},[932,1203,938],{},", and ",[932,1206,941],{}," provide the board and user experience. Keeping them separate lets you redesign the interface while retaining match history.",[890,1209,1210,1211,1213,1214,1217],{},"If you uploaded the full sample, select ",[932,1212,934],{}," and open ",[932,1215,1216],{},"Preview",". If you use only the schema, connect the REST APIs and WebSocket above from your own HTML.",[890,1219,1220,1221,935,1224,1204,1227,1230],{},"The client sends actions such as ",[932,1222,1223],{},"board-game.create",[932,1225,1226],{},"board-game.join",[932,1228,1229],{},"board-game.move"," over WebSocket. It displays stones and scores only from confirmed events returned by the server.",[907,1232,1234],{"id":1233},"_6-play-with-two-users","6. Play with two users",[1130,1236,1237,1243,1250,1253,1259,1262],{},[923,1238,1239,1240,1242],{},"Open the same ",[932,1241,934],{}," with two different member accounts.",[923,1244,1245,1246,1249],{},"Select ",[932,1247,1248],{},"Create new match"," in the first account.",[923,1251,1252],{},"Send the generated room code to the second account.",[923,1254,1255,1256,1070],{},"Enter the code in the second account and select ",[932,1257,1258],{},"Join",[923,1260,1261],{},"Take turns and confirm that the same move appears on both screens.",[923,1263,1264],{},"After five stones connect, confirm that the victory, recent matches, and rankings update.",[890,1266,1267],{},"Using browsers with separate sessions, such as a normal and an incognito window, makes testing on one computer easier.",[890,1269,1270],{},[899,1271],{"alt":1272,"src":1273},"Real-time Gomoku with collaboration chat open","/img/docs/webspace/gomoku/realtime-gomoku-collaboration.png",[907,1275,1277],{"id":1276},"the-server-records-the-result","The server records the result",[890,1279,1280],{},"When five stones connect horizontally, vertically, or diagonally, the server ends the match and stores the winner and score. If a turn exceeds its time limit, the server determines the timeout using server time.",[890,1282,1283],{},[899,1284],{"alt":1285,"src":1286},"Gomoku victory and automatically calculated player rankings","/img/docs/webspace/gomoku/realtime-gomoku-result.png",[890,1288,1289,1290,1293],{},"If recent matches and rankings do not update immediately, verify that the client refreshes the lists after receiving the WebSocket completion event instead of repeatedly selecting the button. Expand ",[932,1291,1292],{},"Developer information"," to inspect sent and received JSON and server processing time.",[907,1295,1297],{"id":1296},"turn-it-into-your-own-game","Turn it into your own game",[890,1299,1300,1302],{},[932,1301,1149],{}," is not specific to Gomoku. Change these handler settings in the schema to use it as a starting point for another turn-based game.",[978,1304,1305,1319],{},[981,1306,1307],{},[984,1308,1309,1312,1316],{},[987,1310,1311],{},"Setting",[987,1313,1315],{"align":1314},"right","Current value",[987,1317,1318],{},"Meaning",[994,1320,1321,1334,1347,1360,1373,1386],{},[984,1322,1323,1328,1331],{},[999,1324,1325],{},[932,1326,1327],{},"boardSize",[999,1329,1330],{"align":1314},"19",[999,1332,1333],{},"Cells along one side of the board",[984,1335,1336,1341,1344],{},[999,1337,1338],{},[932,1339,1340],{},"winLength",[999,1342,1343],{"align":1314},"5",[999,1345,1346],{},"Consecutive stones required to win",[984,1348,1349,1354,1357],{},[999,1350,1351],{},[932,1352,1353],{},"turnTimeSeconds",[999,1355,1356],{"align":1314},"180",[999,1358,1359],{},"Time limit for one move",[984,1361,1362,1367,1370],{},[999,1363,1364],{},[932,1365,1366],{},"winScore",[999,1368,1369],{"align":1314},"3",[999,1371,1372],{},"Win score",[984,1374,1375,1380,1383],{},[999,1376,1377],{},[932,1378,1379],{},"drawScore",[999,1381,1382],{"align":1314},"1",[999,1384,1385],{},"Draw score",[984,1387,1388,1393,1396],{},[999,1389,1390],{},[932,1391,1392],{},"lossScore",[999,1394,1395],{"align":1314},"0",[999,1397,1398],{},"Loss score",[890,1400,1401],{},"You can create a fast game on a smaller board, adjust scoring for an organization event, or add spectators, seasonal rankings, and team matches on the same real-time foundation.",[890,1403,1404],{},"Gomoku is both a complete example and a starting point. Replace stones with monsters and items for turn-based combat, or replace cells with questions and choices for a real-time quiz. Keep data and rules in the schema, then add your game's experience to the interface.",[907,1406,1408],{"id":1407},"troubleshooting","Troubleshooting",[978,1410,1411,1421],{},[981,1412,1413],{},[984,1414,1415,1418],{},[987,1416,1417],{},"Symptom",[987,1419,1420],{},"Check",[994,1422,1423,1434,1442,1452,1466],{},[984,1424,1425,1428],{},[999,1426,1427],{},"Real-time event handler is unavailable",[999,1429,1430,1431,1433],{},"Confirm that the server version supports the schema's ",[932,1432,1149],{}," handler",[984,1435,1436,1439],{},[999,1437,1438],{},"Create or join does not work",[999,1440,1441],{},"Check DB deployment, real-time features, sign-in, and send/receive permissions",[984,1443,1444,1449],{},[999,1445,1446],{},[932,1447,1448],{},"401 Unauthorized",[999,1450,1451],{},"Check the sign-in session and make sure a token was not placed directly in the URL query",[984,1453,1454,1457],{},[999,1455,1456],{},"WebSocket is blocked in production",[999,1458,1459,1460,1462,1463],{},"Confirm the HTTPS page uses ",[932,1461,1191],{}," and CSP allows ",[932,1464,1465],{},"connect-src",[984,1467,1468,1471],{},[999,1469,1470],{},"The modified page shows an old version",[999,1472,1473],{},"Reopen Preview and confirm the latest static file version is returned",[907,1475,1477],{"id":1476},"wrapping-up","Wrapping up",[890,1479,1480],{},"Starting from a single static page in the first example, this series has covered databases, relationships between tables, role-based permissions, document submissions from outside the organization, and now real-time game state judged entirely by the server. Each example added just one new concept on top of the last. Combine a few of these depending on what you need, and you can build most internal and client-facing tools with WebSpace alone.",[907,1482,1484],{"id":1483},"next-steps","Next steps",[920,1486,1487,1493,1498],{},[923,1488,1489],{},[926,1490,1492],{"href":1491},"../api-overview","Build an API and deploy a database",[923,1494,1495],{},[926,1496,589],{"href":1497},"../performance",[923,1499,1500],{},[926,1501,614],{"href":1502},"../admin/service-capacity",{"title":1061,"searchDepth":1504,"depth":1505,"links":1506},2,3,[1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518],{"id":909,"depth":1504,"text":910},{"id":975,"depth":1504,"text":976},{"id":1049,"depth":1504,"text":1050},{"id":1120,"depth":1504,"text":1121},{"id":1164,"depth":1504,"text":1165},{"id":1195,"depth":1504,"text":1196},{"id":1233,"depth":1504,"text":1234},{"id":1276,"depth":1504,"text":1277},{"id":1296,"depth":1504,"text":1297},{"id":1407,"depth":1504,"text":1408},{"id":1476,"depth":1504,"text":1477},{"id":1483,"depth":1504,"text":1484},null,"Download the Gomoku schema file (.sfn) and deploy it as an SQLite3 database, REST API, and WebSocket game backend.","md",{"slug":1523},"/webspace/examples/realtime-gomoku/",true,{"title":1526,"description":1527,"ogType":1528,"twitterCard":1529,"keywords":1530},"Build a real-time Gomoku game | WebSocket game server example","Deploy a Gomoku schema in SetFN WebSpace and test room joining, real-time moves, win detection, and ranking storage.","article","summary_large_image",[1531,1532,1533,1534,1535,1536,1537],"build a real-time Gomoku game","WebSocket game server","WebSocket example","SQLite game","no-code backend","schema file download","SetFN WebSpace","FFsb2su5MFC5VwpW9EfqkoBsh0xIsjtOhnuN4Yyd0cs",[1540,1541],{"title":627,"path":628,"stem":629,"children":-1},{"title":640,"path":641,"stem":642,"children":-1},{"title":631,"filename":1543,"content":1544},"realtime-gomoku","# Build a real-time Gomoku game\n\nUpload the files, deploy the schema, and open two browsers. A friend can join the room created in one browser, and every move appears immediately in the other. The server records results and rankings.\n\nNo separate frontend build tool is required. Play one match with the completed sample first, then modify the data structure, real-time behavior, and game rules.\n\n![19×19 board, live match feed, and player rankings](/img/docs/webspace/gomoku/realtime-gomoku-board.png)\n\n---\n\n## 1. Play a match first\n\nThe fastest way to begin is with the **complete sample ZIP**. Upload the schema and interface files to the same folder and deploy the schema.\n\n- [Download the complete real-time Gomoku sample ZIP](/examples/webspace/gomoku/setfn-realtime-gomoku-sample.zip): Includes the schema, `index.html`, `style.css`, `app.js`, and README\n- [Download the Gomoku schema file (.sfn)](/examples/webspace/gomoku/gomoku-realtime.sfn): Use it to inspect only the backend or connect your own interface\n\nThe sample demonstrates:\n\n- A two-user match using a room code\n- The last move, your stones, and the current turn\n- A three-minute limit that restarts after each move\n- A live match feed\n- Automatic result, recent-match, and ranking updates\n\nThe schema includes a 19×19 board, five-in-a-row victory, and scores of 3 for a win, 1 for a draw, and 0 for a loss. Each user can create up to three waiting rooms. A room with no participant for 30 minutes becomes eligible for cleanup.\n\n## Features used in the game\n\n| Feature | Role in Gomoku |\n| --- | --- |\n| Schema file | Defines matches, moves, and player records |\n| REST API | Retrieves recent matches and player rankings |\n| WebSocket | Delivers room creation, joining, and move results in real time |\n| Event handler | Evaluates turns, coordinates, victory, and time limits on the server |\n| Member permissions | Allows only signed-in users to participate |\n| Collaboration | Lets participants chat on the same screen |\n\nThe browser does not declare victory or write scores directly. The server validates the board and turn, saves only valid moves, and sends the same result to both users.\n\n## 2. Upload the files to a workspace\n\nUpload the schema to a project folder in a team or personal workspace. If you downloaded the ZIP, put all five files in one folder by using folder upload or archive upload.\n\n```text\ngomoku-room/\n├── gomoku-realtime.sfn\n├── index.html\n├── style.css\n├── app.js\n└── README.md\n```\n\nOpen the schema file and check the three tables under `DB Structure`.\n\n| Table | Stored data |\n| --- | --- |\n| `gomoku_games` | Room code, participants, current turn, time limit, and final result |\n| `gomoku_moves` | Move number, stone color, coordinates, and user |\n| `gomoku_players` | Wins, losses, draws, cumulative score, and recent games by user |\n\nMatches and player records are stored separately, so recent history and rankings can be loaded again after reopening the page.\n\n## 3. Check the API and real-time features\n\nOpen `API Build` at the top and verify the following:\n\n1. The database name is `gomoku`.\n2. Real-time sockets are enabled under `Feature connections`.\n3. The event handler is `turn-based-board`.\n4. Real-time send and receive permissions are set to `Member`.\n5. Create and update APIs are disabled for all three tables.\n\nDisabling create and update APIs prevents participants from changing win counts or moves through REST. Every game state change must pass through the server event handler.\n\n## 4. Deploy with SQLite3\n\nFor the first run, select SQLite3 under `Storage`. It requires no separate database address or account.\n\nBefore selecting `Deploy`, review the displayed changes and permission summary. If a database with the same name already contains records, an administrator or deployment operator may need to approve the operation according to the server overwrite policy.\n\n```text\nGET /api/web/gomoku/gomoku_games/list\nGET /api/web/gomoku/gomoku_players/list\nWS  /api/web/gomoku/realtime-ws\n```\n\nFor an HTTPS production server, the browser must use a secure `wss://` connection on the same domain. Build the address from the current page host instead of hard-coding a development domain.\n\n## 5. Open the Gomoku interface\n\nThe schema creates the game database and backend. `index.html`, `style.css`, and `app.js` provide the board and user experience. Keeping them separate lets you redesign the interface while retaining match history.\n\nIf you uploaded the full sample, select `index.html` and open `Preview`. If you use only the schema, connect the REST APIs and WebSocket above from your own HTML.\n\nThe client sends actions such as `board-game.create`, `board-game.join`, and `board-game.move` over WebSocket. It displays stones and scores only from confirmed events returned by the server.\n\n## 6. Play with two users\n\n1. Open the same `index.html` with two different member accounts.\n2. Select `Create new match` in the first account.\n3. Send the generated room code to the second account.\n4. Enter the code in the second account and select `Join`.\n5. Take turns and confirm that the same move appears on both screens.\n6. After five stones connect, confirm that the victory, recent matches, and rankings update.\n\nUsing browsers with separate sessions, such as a normal and an incognito window, makes testing on one computer easier.\n\n![Real-time Gomoku with collaboration chat open](/img/docs/webspace/gomoku/realtime-gomoku-collaboration.png)\n\n## The server records the result\n\nWhen five stones connect horizontally, vertically, or diagonally, the server ends the match and stores the winner and score. If a turn exceeds its time limit, the server determines the timeout using server time.\n\n![Gomoku victory and automatically calculated player rankings](/img/docs/webspace/gomoku/realtime-gomoku-result.png)\n\nIf recent matches and rankings do not update immediately, verify that the client refreshes the lists after receiving the WebSocket completion event instead of repeatedly selecting the button. Expand `Developer information` to inspect sent and received JSON and server processing time.\n\n## Turn it into your own game\n\n`turn-based-board` is not specific to Gomoku. Change these handler settings in the schema to use it as a starting point for another turn-based game.\n\n| Setting | Current value | Meaning |\n| --- | ---: | --- |\n| `boardSize` | 19 | Cells along one side of the board |\n| `winLength` | 5 | Consecutive stones required to win |\n| `turnTimeSeconds` | 180 | Time limit for one move |\n| `winScore` | 3 | Win score |\n| `drawScore` | 1 | Draw score |\n| `lossScore` | 0 | Loss score |\n\nYou can create a fast game on a smaller board, adjust scoring for an organization event, or add spectators, seasonal rankings, and team matches on the same real-time foundation.\n\nGomoku is both a complete example and a starting point. Replace stones with monsters and items for turn-based combat, or replace cells with questions and choices for a real-time quiz. Keep data and rules in the schema, then add your game's experience to the interface.\n\n## Troubleshooting\n\n| Symptom | Check |\n| --- | --- |\n| Real-time event handler is unavailable | Confirm that the server version supports the schema's `turn-based-board` handler |\n| Create or join does not work | Check DB deployment, real-time features, sign-in, and send/receive permissions |\n| `401 Unauthorized` | Check the sign-in session and make sure a token was not placed directly in the URL query |\n| WebSocket is blocked in production | Confirm the HTTPS page uses `wss://` and CSP allows `connect-src` |\n| The modified page shows an old version | Reopen Preview and confirm the latest static file version is returned |\n\n## Wrapping up\n\nStarting from a single static page in the first example, this series has covered databases, relationships between tables, role-based permissions, document submissions from outside the organization, and now real-time game state judged entirely by the server. Each example added just one new concept on top of the last. Combine a few of these depending on what you need, and you can build most internal and client-facing tools with WebSpace alone.\n\n## Next steps\n\n- [Build an API and deploy a database](../24.api-overview.md)\n- [Performance and scaling](../48.performance.md)\n- [Services and capacity](../50.admin/40.service-capacity.md)\n",1789664756357]